Документация Python неофициальный перевод
Содержание страницы

19.1.6. email.contentmanager: Управление MIME-содержимымemail.contentmanager: Managing MIME Content

Новое в версии 3.4: как временный модуль.

Исходный код: Lib/email/contentmanager.py

Примечание

Модуль contentmanager был включен в стандартную библиотеку на временной основе. Обратно несовместимые изменения (вплоть до удаления модуля) могут быть внесены, если основные разработчики сочтут это необходимым.


Модуль message предоставляет класс, который может представлять произвольное email-сообщение. Эта базовая модель сообщения имеет полезный и гибкий API, но предоставляет только низкоуровневый API для взаимодействия с общими частями сообщения (заголовки, общие параметры заголовков и полезная нагрузка, которая может быть списком подчастей). Этот модуль предоставляет классы и инструменты, которые обеспечивают расширенный и расширяемый API для работы с различными конкретными типами содержимого, включая возможность извлекать содержимое сообщения как объект специализированного типа, а не как простой объект байтов. Модуль автоматически обрабатывает RFC-специфичные MIME-детали (необходимые заголовки и параметры и т.д.) для определенных распространенных типов содержимого, а поддержка дополнительных типов может быть добавлена приложением с помощью механизмов расширения.

Этот модуль определяет одноименные классы «Content Manager». Базовый класс ContentManager определяет API для регистрации функций управления содержимым, которые извлекают данные из объектов Message или вставляют данные и заголовки в объекты Message, тем самым обеспечивая способ преобразования между объектами Message, содержащими данные, и другими представлениями этих данных (типы данных Python, специализированные объекты Python, внешние файлы и т.д.). Модуль также определяет один конкретный менеджер содержимого: raw_data_manager преобразует между MIME-типами содержимого и данными str или bytes. Он также предоставляет удобный API для управления MIME-параметрами при вставке содержимого в Message. Также он обрабатывает вставку и извлечение объектов Message при работе с типом содержимого message/rfc822.

Еще одна часть расширенного интерфейса – подклассы Message, которые предоставляют новые удобные функции API, включая удобные методы для вызова менеджеров содержимого, производных от этого модуля.

Примечание

Хотя EmailMessage и MIMEPart в настоящее время документированы в этом модуле из-за временного характера кода, реализация находится в модуле email.message.

class email.message.EmailMessage(policy=default)

Если указан policy (он должен быть экземпляром класса policy), используйте указанные им правила для обновления и сериализации представления сообщения. Если policy не задан, используйте политику default, которая следует правилам email RFC, за исключением окончаний строк (вместо требуемого RFC \r\n используется стандартное для Python \n окончание строк). Дополнительную информацию см. в документации policy.

Этот класс является подклассом Message. Он добавляет следующие методы:

is_attachment()

Возвращает True, если присутствует заголовок Content-Disposition и его значение (без учёта регистра) равно attachment, иначе False.

Изменено в версии 3.4.2: is_attachment теперь метод, а не свойство, для согласованности с is_multipart().

get_body(preferencelist=('related', 'html', 'plain'))

Возвращает MIME-часть, которая наилучшим образом подходит на роль «тела» сообщения.

preferencelist должен быть последовательностью строк из набора related, html и plain и указывает порядок предпочтения типа содержимого возвращаемой части.

Поиск подходящих кандидатов начинается с объекта, для которого вызван метод get_body.

Если related не включён в preferencelist, корневая часть (или подчасть корневой части) любой встреченной связанной части рассматривается как кандидат, если эта (под)часть соответствует предпочтению.

При обнаружении multipart/related проверяется параметр start, и если найдена часть с соответствующим Content-ID, то при поиске подходящих кандидатов рассматривается только она. В противном случае рассматривается только первая (корневая по умолчанию) часть multipart/related.

Если часть имеет заголовок Content-Disposition, то часть считается подходящим кандидатом только если значение заголовка равно inline.

Если ни один из кандидатов не соответствует ни одному предпочтению из preferencelist, возвращается None.

Примечания: (1) Для большинства приложений единственные комбинации preferencelist, которые действительно имеют смысл: ('plain',), ('html', 'plain') и значение по умолчанию ('related', 'html', 'plain'). (2) Поскольку сопоставление начинается с объекта, для которого вызывается get_body, вызов get_body на multipart/related вернет сам объект, если только preferencelist не имеет нестандартного значения. (3) Сообщения (или части сообщений), которые не указывают Content-Type или чей заголовок Content-Type недействителен, будут обрабатываться как имеющие тип text/plain, что иногда может приводить к неожиданным результатам get_body.

iter_attachments()

Возвращает итератор по всем частям сообщения, которые не являются кандидатами на «тело». То есть пропускает первое вхождение каждого из text/plain, text/html, multipart/related или multipart/alternative (если только они явно не помечены как вложения через Content-Disposition: attachment) и возвращает все остальные части. При непосредственном применении к multipart/related возвращает итератор по всем связанным частям, кроме корневой (т.е. части, на которую указывает параметр start, или первой части, если параметр start отсутствует или параметр start не соответствует Content-ID ни одной из частей). При непосредственном применении к multipart/alternative или не-multipart возвращает пустой итератор.

iter_parts()

Возвращает итератор по всем непосредственным подчастям сообщения; для не-multipart итератор будет пустым. (См. также walk().)

get_content(*args, content_manager=None, **kw)

Вызывает метод get_content объекта content_manager, передавая self в качестве объекта сообщения и передавая любые другие аргументы или ключевые слова как дополнительные аргументы. Если content_manager не указан, используется content_manager, заданный текущим policy.

set_content(*args, content_manager=None, **kw)

Вызывает метод set_content объекта content_manager, передавая self в качестве объекта сообщения и передавая любые другие аргументы или ключевые слова как дополнительные аргументы. Если content_manager не указан, используется content_manager, заданный текущим policy.

Преобразует сообщение, не являющееся multipart, в сообщение multipart/related, перемещая все существующие заголовки Content- и полезную нагрузку в (новую) первую часть multipart. Если указан boundary, он используется в качестве строки границы в multipart, в противном случае граница будет создана автоматически при необходимости (например, при сериализации сообщения).

make_alternative(boundary=None)

Преобразует сообщение, не являющееся multipart или являющееся multipart/related, в сообщение multipart/alternative, перемещая все существующие заголовки Content- и полезную нагрузку в (новую) первую часть multipart. Если указан boundary, он используется в качестве строки границы в multipart, в противном случае граница будет создана автоматически при необходимости (например, при сериализации сообщения).

make_mixed(boundary=None)

Преобразует сообщение, не являющееся multipart, являющееся multipart/related или multipart-alternative, в сообщение multipart/mixed, перемещая все существующие заголовки Content- и полезную нагрузку в (новую) первую часть multipart. Если указан boundary, он используется в качестве строки границы в multipart, в противном случае граница будет создана автоматически при необходимости (например, при сериализации сообщения).

Если сообщение является multipart/related, создаётся новый объект сообщения, все аргументы передаются его методу set_content(), и attach() его к multipart. Если сообщение не является multipart, вызывается make_related(), после чего выполняется описанное выше. Если сообщение относится к любому другому типу multipart, возбуждается TypeError. Если content_manager не указан, используется content_manager, заданный текущим policy. Если у добавленной части нет заголовка Content-Disposition, добавляется заголовок со значением inline.

add_alternative(*args, content_manager=None, **kw)

Если сообщение является multipart/alternative, создаётся новый объект сообщения, все аргументы передаются его методу set_content(), и attach() его к multipart. Если сообщение не является multipart или является multipart/related, вызывается make_alternative(), после чего выполняется описанное выше. Если сообщение относится к любому другому типу multipart, возбуждается TypeError. Если content_manager не указан, используется content_manager, заданный текущим policy.

add_attachment(*args, content_manager=None, **kw)

Если сообщение является multipart/mixed, создайте новый объект сообщения, передайте все аргументы его методу set_content() и attach() его в multipart. Если сообщение является не-multipart, multipart/related или multipart/alternative, вызовите make_mixed() и затем действуйте как выше. Если content_manager не указан, используйте content_manager, заданный текущим policy. Если добавленная часть не имеет заголовка Content-Disposition, добавьте заголовок со значением attachment. Этот метод можно использовать как для явных вложений (Content-Disposition: attachment, так и для inline вложений (Content-Disposition: inline) путем передачи соответствующих параметров в content_manager.

clear()

Удаляет полезную нагрузку и все заголовки.

clear_content()

Удаляет полезную нагрузку и все заголовки Content-, оставляя все остальные заголовки нетронутыми и в исходном порядке.

class email.message.MIMEPart(policy=default)

Этот класс представляет подчасть MIME-сообщения. Он идентичен EmailMessage, за исключением того, что заголовки MIME-Version не добавляются при вызове set_content(), поскольку подчасти не нуждаются в собственных заголовках MIME-Version.

class email.contentmanager.ContentManager

Базовый класс для диспетчеров содержимого. Предоставляет стандартные механизмы регистрации для преобразователей между MIME-содержимым и другими представлениями, а также методы отправки get_content и set_content.

get_content(msg, *args, **kw)

Находит функцию-обработчик на основе mimetype сообщения msg (см. следующий абзац), вызывает её, передавая все аргументы, и возвращает результат вызова. Ожидается, что обработчик извлечёт полезную нагрузку из msg и вернёт объект, который кодирует информацию об извлечённых данных.

Для поиска обработчика ищутся следующие ключи в реестре; поиск прекращается при первом найденном:

  • строка, представляющая полный MIME-тип (maintype/subtype)
  • строка, представляющая maintype
  • пустая строка

Если ни один из этих ключей не дал обработчика, возбуждается KeyError для полного MIME-типа.

set_content(msg, obj, *args, **kw)

Если maintype равно multipart, возбуждается TypeError; в противном случае находится функция-обработчик на основе типа obj (см. следующий абзац), вызывается clear_content() на msg и вызывается функция-обработчик с передачей всех аргументов. Ожидается, что обработчик преобразует и сохранит obj в msg, возможно, внося также другие изменения в msg, например, добавляя различные MIME-заголовки для кодирования информации, необходимой для интерпретации сохранённых данных.

Для поиска обработчика получается тип obj (typ = type(obj)), и в реестре ищутся следующие ключи; поиск прекращается при первом найденном:

  • сам тип (typ)
  • полное квалифицированное имя типа (typ.__module__ + '.' + typ.__qualname__).
  • qualname типа (typ.__qualname__)
  • имя типа (typ.__name__).

Если ни одно из вышеперечисленных не совпадает, повторить все проверки выше для каждого из типов в MRO (typ.__mro__). Наконец, если ни один другой ключ не даёт обработчика, проверить наличие обработчика для ключа None. Если обработчика для None нет, вызвать KeyError для полного имени типа.

Также добавляется заголовок MIME-Version, если он отсутствует (см. также MIMEPart).

add_get_handler(key, handler)

Регистрирует функцию handler как обработчик для key. Возможные значения key описаны в get_content().

add_set_handler(typekey, handler)

Регистрирует handler как функцию, вызываемую, когда объект типа, соответствующего typekey, передаётся в set_content(). Возможные значения typekey описаны в set_content().

19.1.6.1. Экземпляры Content ManagerContent Manager Instances

В настоящее время пакет email предоставляет только один конкретный диспетчер содержимого – raw_data_manager, хотя в будущем может быть добавлено больше. raw_data_manager – это content_manager, предоставляемый EmailPolicy и его производными.

email.contentmanager.raw_data_manager

Этот диспетчер содержимого предоставляет лишь минимальный интерфейс в дополнение к тому, что предоставляет сам Message: он работает только с текстом, необработанными байтовыми строками и объектами Message. Тем не менее, он даёт значительные преимущества по сравнению с базовым API: get_content для текстовой части возвращает строку Unicode без необходимости ручного декодирования, set_content предоставляет богатый набор опций для управления заголовками, добавляемыми к части, и управления кодировкой передачи содержимого, а также позволяет использовать различные методы add_, упрощая создание многокомпонентных сообщений.

email.contentmanager.get_content(msg, errors='replace')

Возвращает содержимое части как строку (для частей text), объект EmailMessage (для частей message/rfc822) или объект bytes (для всех других не multipart-типов). Вызывает KeyError при вызове для multipart. Если часть является text и указан errors, использует его как обработчик ошибок при декодировании содержимого в unicode. Обработчик ошибок по умолчанию – replace.

email.contentmanager.set_content(msg, <'str'>, subtype="plain", charset='utf-8' cte=None, disposition=None, filename=None, cid=None, params=None, headers=None)
email.contentmanager.set_content(msg, <'bytes'>, maintype, subtype, cte="base64", disposition=None, filename=None, cid=None, params=None, headers=None)
email.contentmanager.set_content(msg, <'Message'>, cte=None, disposition=None, filename=None, cid=None, params=None, headers=None)
email.contentmanager.set_content(msg, <'list'>, subtype='mixed', disposition=None, filename=None, cid=None, params=None, headers=None)

Добавляет заголовки и содержимое в msg:

Добавляет заголовок Content-Type со значением maintype/subtype.

  • Для str устанавливает MIME maintype в text, а подтип – в subtype, если он указан, или в plain, если нет.
  • Для bytes использует указанные maintype и subtype, или вызывает TypeError, если они не указаны.
  • Для объектов Message установите maintype в message, а subtype – в subtype, если он указан, или в rfc822, если нет. Если subtype равен partial, вызовите исключение (объекты bytes должны использоваться для создания частей message/partial).
  • Для <’list’>, который должен быть списком объектов Message, установите maintype в multipart, а subtype – в subtype, если он указан, и в mixed, если нет. Если части сообщения в <’list’> имеют заголовки MIME-Version, удалите их.

Если указан charset (действителен только для str), кодирует строку в байты с использованием указанной кодировки. По умолчанию используется utf-8. Если указанный charset является известным псевдонимом стандартного имени кодировки MIME, использует стандартную кодировку.

Если cte установлен, закодируйте полезную нагрузку с помощью указанного кодирования передачи содержимого и установите заголовок Content-Transfer-Encoding в это значение. Для объектов str, если он не установлен, используйте эвристику для определения наиболее компактного кодирования. Возможные значения для cte: quoted-printable, base64, 7bit, 8bit и binary. Если входные данные невозможно закодировать с помощью указанного кодирования (например, 7bit), вызовите ValueError. Для Message, согласно RFC 2046, вызовите исключение, если для subtype rfc822 запрошен cte равный quoted-printable или base64, и для любого cte отличного от 7bit для subtype external-body. Для message/rfc822 используйте 8bit, если cte не указан. Для всех остальных значений subtype используйте 7bit.

Примечание

cte равный binary пока работает некорректно. Объект Message, изменённый с помощью set_content, правилен, но BytesGenerator не сериализует его корректно.

Если disposition установлен, используйте его как значение заголовка Content-Disposition. Если не указан, а filename указан, добавьте заголовок со значением attachment. Если он не указан и filename тоже не указан, не добавляйте заголовок. Единственные допустимые значения для disposition: attachment и inline.

Если filename указан, используйте его как значение параметра filename заголовка Content-Disposition. Значения по умолчанию нет.

Если указан cid, добавляет заголовок Content-ID со значением cid.

Если указан params, перебирает его метод items и использует полученные пары (key, value) для установки дополнительных параметров заголовка Content-Type.

Если указан headers и это список строк вида headername: headervalue или список объектов header (отличаются от строк наличием атрибута name), добавляет заголовки в msg.