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

19.1.1. email.message: Представление сообщения электронной почтыemail.message: Representing an email message

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


Новое в версии 3.6: 1

Центральный класс в пакете email – это EmailMessage класс, импортируемый из модуля email.message. Он является базовым классом для объектной модели email. EmailMessage предоставляет основные функции для установки и запроса полей заголовков, для доступа к телам сообщений, а также для создания или изменения структурированных сообщений.

An email message consists of headers and a payload (which is also referred to as the content). Headers are RFC 5322 or RFC 6532 style field names and values, where the field name and value are separated by a colon. The colon is not part of either the field name or the field value. The payload may be a simple text message, or a binary object, or a structured sequence of sub-messages each with their own set of headers and their own payload. The latter type of payload is indicated by the message having a MIME type such as multipart/* or message/rfc822.

The conceptual model provided by an EmailMessage object is that of an ordered dictionary of headers coupled with a payload that represents the RFC 5322 body of the message, which might be a list of sub-EmailMessage objects. In addition to the normal dictionary methods for accessing the header names and values, there are methods for accessing specialized information from the headers (for example the MIME content type), for operating on the payload, for generating a serialized version of the message, and for recursively walking over the object tree.

Интерфейс, похожий на словарь EmailMessage, индексируется по именам заголовков, которые должны быть значениями ASCII. Значения словаря – это строки с дополнительными методами. Заголовки хранятся и возвращаются с сохранением регистра, но имена полей сравниваются без учёта регистра. В отличие от обычного словаря, ключи упорядочены, и могут быть дублирующиеся ключи. Предусмотрены дополнительные методы для работы с заголовками, имеющими дублирующиеся ключи.

Полезная нагрузка – это либо строковый объект, либо объект bytes в случае простых сообщений, либо список объектов EmailMessage для MIME-контейнеров, таких как multipart/* и message/rfc822.

class email.message.EmailMessage(policy=default)

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

as_string(unixfrom=False, maxheaderlen=None, policy=None)

Возвращает всё сообщение, преобразованное в строку. Если необязательный параметр unixfrom равен true, в возвращаемую строку включается конвертный заголовок. unixfrom по умолчанию равен False. Для обратной совместимости с базовым классом Message принимается параметр maxheaderlen, но по умолчанию он равен None, что означает, что по умолчанию длина строки управляется max_line_length политики. Аргумент policy может использоваться для переопределения политики по умолчанию, полученной из экземпляра сообщения. Это может быть использовано для управления форматированием, создаваемым методом, поскольку указанная policy будет передана в Generator.

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

Обратите внимание, что этот метод предоставляется для удобства и может быть не самым полезным способом сериализации сообщений в вашем приложении, особенно если вы работаете с несколькими сообщениями. См. email.generator.Generator для более гибкого API сериализации сообщений. Также обратите внимание, что этот метод ограничен созданием сообщений, сериализованных как "7 bit clean", когда utf8 равно False, что является значением по умолчанию.

Изменено в версии 3.6: поведение по умолчанию, когда параметр maxheaderlen не указан, было изменено: вместо значения 0 по умолчанию теперь используется значение max_line_length из политики.

__str__()

Эквивалентно as_string(policy=self.policy.clone(utf8=True)). Позволяет str(msg) создать строку, содержащую сериализованное сообщение в удобочитаемом формате.

Changed in version 3.4: the method was changed to use utf8=True, thus producing an RFC 6531-like message representation, instead of being a direct alias for as_string().

as_bytes(unixfrom=False, policy=None)

Возвращает всё сообщение, преобразованное в объект bytes. Если необязательный параметр unixfrom равен true, в возвращаемую строку включается конвертный заголовок. unixfrom по умолчанию равен False. Аргумент policy может использоваться для переопределения политики по умолчанию, полученной из экземпляра сообщения. Это может быть использовано для управления форматированием, создаваемым методом, поскольку указанная policy будет передана в BytesGenerator.

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

Обратите внимание, что этот метод предоставляется для удобства и может быть не самым полезным способом сериализации сообщений в вашем приложении, особенно если вы работаете с несколькими сообщениями. См. email.generator.BytesGenerator для более гибкого API сериализации сообщений.

__bytes__()

Эквивалентно as_bytes(). Позволяет bytes(msg) создать объект bytes, содержащий сериализованное сообщение.

is_multipart()

Возвращает True, если полезная нагрузка сообщения представляет собой список объектов sub-EmailMessage, в противном случае возвращает False. Когда is_multipart() возвращает False, полезная нагрузка должна быть строковым объектом (который может быть двоичной нагрузкой, закодированной с помощью CTE). Обратите внимание, что is_multipart() возвращающий True не обязательно означает, что “msg.get_content_maintype() == 'multipart'” вернёт True. Например, is_multipart вернёт True, когда EmailMessage имеет тип message/rfc822.

set_unixfrom(unixfrom)

Устанавливает конвертный заголовок сообщения равным unixfrom, который должен быть строкой. (См. mboxMessage для краткого описания этого заголовка.)

get_unixfrom()

Возвращает конвертный заголовок сообщения. По умолчанию равен None, если конвертный заголовок никогда не был установлен.

Следующие методы реализуют интерфейс, подобный отображению (mapping), для доступа к заголовкам сообщения. Обратите внимание, что между этими методами и обычным интерфейсом отображения (т.е. словаря) есть некоторые семантические различия. Например, в словаре нет дублирующихся ключей, но здесь могут быть дублирующиеся заголовки сообщения. Кроме того, в словарях нет гарантированного порядка ключей, возвращаемых keys(), но в объекте EmailMessage заголовки всегда возвращаются в порядке их появления в исходном сообщении или в том порядке, в котором они были добавлены в сообщение позже. Любой заголовок, удалённый, а затем добавленный снова, всегда добавляется в конец списка заголовков.

Эти семантические различия являются преднамеренными и направлены на удобство в наиболее распространённых случаях использования.

Обратите внимание, что во всех случаях заголовки конверта, присутствующие в сообщении, не включаются в интерфейс отображения.

__len__()

Возвращает общее количество заголовков, включая дубликаты.

__contains__(name)

Возвращает истину, если объект сообщения имеет поле с именем name. Сравнение производится без учёта регистра, а name не включает завершающее двоеточие. Используется для оператора in. Например:

if 'message-id' in myMessage:
   print('Message-ID:', myMessage['message-id'])
__getitem__(name)

Возвращает значение указанного поля заголовка. name не включает разделитель - двоеточие. Если заголовок отсутствует, возвращается None; исключение KeyError никогда не возбуждается.

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

При использовании стандартных (не compat32) политик возвращаемое значение является экземпляром подкласса email.headerregistry.BaseHeader.

__setitem__(name, val)

Добавляет заголовок в сообщение с именем поля name и значением val. Поле добавляется в конец существующих заголовков сообщения.

Обратите внимание, что это не перезаписывает и не удаляет существующие заголовки с тем же именем. Если требуется гарантировать, что новый заголовок будет единственным в сообщении с именем поля name, сначала удалите это поле, например:

del msg['subject']
msg['subject'] = 'Python roolz!'

Если политика policy определяет некоторые заголовки как уникальные (как это делают стандартные политики), данный метод может возбудить ValueError при попытке присвоить значение такому заголовку, когда он уже существует. Такое поведение предусмотрено намеренно ради согласованности, но не стоит полагаться на него, поскольку в будущем мы можем сделать так, чтобы такие присваивания автоматически удаляли существующий заголовок.

__delitem__(name)

Удаляет все вхождения поля с именем name из заголовков сообщения. Исключение не возбуждается, если указанное поле отсутствует в заголовках.

keys()

Возвращает список всех имён полей заголовков сообщения.

values()

Возвращает список всех значений полей сообщения.

items()

Возвращает список кортежей из двух элементов, содержащих все заголовки и значения полей сообщения.

get(name, failobj=None)

Возвращает значение указанного поля заголовка. Это идентично __getitem__(), за исключением того, что в случае отсутствия указанного заголовка возвращается необязательный failobj (failobj по умолчанию равен None).

Вот несколько дополнительных полезных методов, связанных с заголовками:

get_all(name, failobj=None)

Возвращает список всех значений для поля с именем name. Если в сообщении нет таких заголовков, возвращается failobj (по умолчанию None).

add_header(_name, _value, **_params)

Расширенная настройка заголовка. Этот метод похож на __setitem__(), за исключением того, что дополнительные параметры заголовка можно передавать в виде именованных аргументов. _name – это добавляемое поле заголовка, а _valueосновное значение заголовка.

Для каждого элемента словаря именованных аргументов _params ключ используется как имя параметра, причём символы подчёркивания преобразуются в дефисы (поскольку дефисы недопустимы в идентификаторах Python). Обычно параметр добавляется как key="value", если только значение не равно None; в этом случае добавляется только ключ.

Если значение содержит не-ASCII символы, кодировка и язык могут быть явно заданы указанием значения в виде тройки в формате (CHARSET, LANGUAGE, VALUE), где CHARSET – строка, задающая кодировку для кодирования значения, LANGUAGE обычно может быть установлен в None или пустую строку (см. RFC 2231 для других возможностей), а VALUE – строковое значение, содержащее не-ASCII кодовые точки. Если тройка не передана и значение содержит не-ASCII символы, оно автоматически кодируется в формат RFC 2231 с использованием CHARSET utf-8 и LANGUAGE None.

Вот пример:

msg.add_header('Content-Disposition', 'attachment', filename='bud.gif')

Это добавит заголовок, который выглядит как

Content-Disposition: attachment; filename="bud.gif"

Пример расширенного интерфейса с не-ASCII символами:

msg.add_header('Content-Disposition', 'attachment',
               filename=('iso-8859-1', '', 'Fußballer.ppt'))
replace_header(_name, _value)

Заменяет заголовок. Заменяет первый найденный в сообщении заголовок, соответствующий _name, сохраняя порядок заголовков и регистр имени поля исходного заголовка. Если соответствующий заголовок не найден, возбуждается исключение KeyError.

get_content_type()

Возвращает тип содержимого сообщения, приведённый к нижнему регистру в формате maintype/subtype. Если в сообщении нет заголовка Content-Type, возвращается значение, возвращаемое get_default_type(). Если заголовок Content-Type некорректен, возвращается text/plain.

(Согласно RFC 2045, сообщения всегда имеют тип по умолчанию, get_content_type() всегда возвращает некоторое значение. RFC 2045 определяет тип по умолчанию для сообщения как text/plain, если оно не находится внутри контейнера multipart/digest; в этом случае типом по умолчанию будет message/rfc822. Если заголовок Content-Type содержит некорректное описание типа, RFC 2045 предписывает использовать тип по умолчанию text/plain.)

get_content_maintype()

Возвращает основной тип содержимого сообщения. Это часть maintype строки, возвращаемой get_content_type().

get_content_subtype()

Возвращает подтип содержимого сообщения. Это часть subtype строки, возвращаемой get_content_type().

get_default_type()

Возвращает тип содержимого по умолчанию. Большинство сообщений имеют тип содержимого по умолчанию text/plain, за исключением сообщений, которые являются подчастями контейнеров multipart/digest. Такие подчасти имеют тип содержимого по умолчанию message/rfc822.

set_default_type(ctype)

Устанавливает тип содержимого по умолчанию. ctype должен быть либо text/plain, либо message/rfc822, хотя это не контролируется. Тип содержимого по умолчанию не хранится в заголовке Content-Type, поэтому он влияет только на возвращаемое значение методов get_content_type, когда в сообщении отсутствует заголовок Content-Type.

set_param(param, value, header='Content-Type', requote=True, charset=None, language='', replace=False)

Устанавливает параметр в заголовке Content-Type. Если параметр уже существует в заголовке, заменяет его значение на value. Когда header равен Content-Type (по умолчанию) и заголовок ещё не существует в сообщении, он добавляется, его значение устанавливается в text/plain, и добавляется новое значение параметра. Необязательный параметр header указывает альтернативный заголовок вместо Content-Type.

Если значение содержит не-ASCII символы, кодировка и язык могут быть явно указаны с помощью необязательных параметров charset и language. Необязательный параметр language задаёт язык RFC 2231, по умолчанию – пустая строка. Оба параметра charset и language должны быть строками. По умолчанию используется utf8 charset и None для language.

Если replace равен False (по умолчанию), заголовок перемещается в конец списка заголовков. Если replace равен True, заголовок будет обновлён на месте.

Использование параметра requote с объектами EmailMessage устарело.

Обратите внимание, что существующие значения параметров заголовков могут быть получены через атрибут params значения заголовка (например, msg['Content-Type'].params['charset']).

Изменено в версии 3.4: replace добавлен ключевой параметр.

del_param(param, header='content-type', requote=True)

Полностью удаляет указанный параметр из заголовка Content-Type. Заголовок будет перезаписан на месте без этого параметра и его значения. Необязательный параметр header указывает альтернативный заголовок вместо Content-Type.

Использование параметра requote с объектами EmailMessage устарело.

get_filename(failobj=None)

Возвращает значение параметра filename заголовка Content-Disposition сообщения. Если в заголовке нет параметра filename, этот метод пытается найти параметр name в заголовке Content-Type. Если ни один из них не найден или заголовок отсутствует, возвращается failobj. Возвращаемая строка всегда будет раскрыта в соответствии с email.utils.unquote().

get_boundary(failobj=None)

Возвращает значение параметра boundary заголовка Content-Type сообщения или failobj, если заголовок отсутствует или не содержит параметра boundary. Возвращаемая строка всегда будет раскрыта в соответствии с email.utils.unquote().

set_boundary(boundary)

Устанавливает параметр boundary заголовка Content-Type в значение boundary. set_boundary() всегда будет заключать boundary в кавычки при необходимости. Возбуждается исключение HeaderParseError, если объект сообщения не имеет заголовка Content-Type.

Обратите внимание, что использование этого метода незначительно отличается от удаления старого заголовка Content-Type и добавления нового с новой границей через add_header(), поскольку set_boundary() сохраняет порядок заголовка Content-Type в списке заголовков.

get_content_charset(failobj=None)

Возвращает параметр charset заголовка Content-Type, приведённый к нижнему регистру. Если заголовок Content-Type отсутствует или не содержит параметра charset, возвращается failobj.

get_charsets(failobj=None)

Возвращает список, содержащий имена наборов символов в сообщении. Если сообщение является multipart, список будет содержать по одному элементу для каждой вложенной части в полезной нагрузке; в противном случае это будет список длиной 1.

Каждый элемент списка представляет собой строку – значение параметра charset в заголовке Content-Type для соответствующей подчасти. Если у подчасти нет заголовка Content-Type, параметра charset или она не относится к основному MIME-типу text, то этот элемент возвращаемого списка будет равен failobj.

is_attachment()

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

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

get_content_disposition()

Возвращает значение заголовка Content-Disposition сообщения в нижнем регистре (без параметров), если он есть, или None. Возможные значения этого метода: inline, attachment или None, если сообщение соответствует RFC 2183.

Новое в версии 3.5.

Следующие методы относятся к запросу и изменению содержимого (полезной нагрузки) сообщения.

walk()

Метод walk() – это универсальный генератор, который можно использовать для обхода всех частей и подчастей дерева объекта сообщения в порядке прямого обхода в глубину. Обычно walk() используется как итератор в цикле for; каждая итерация возвращает следующую подчасть.

Вот пример, который выводит MIME-тип каждой части многокомпонентной структуры сообщения:

>>> for part in msg.walk():
...     print(part.get_content_type())
multipart/report
text/plain
message/delivery-status
text/plain
text/plain
message/rfc822
text/plain

walk обходит подчасти любой части, для которой is_multipart() возвращает True, даже если msg.get_content_maintype() == 'multipart' может возвращать False. Это видно в нашем примере при использовании отладочной вспомогательной функции _structure:

>>> for part in msg.walk():
...     print(part.get_content_maintype() == 'multipart',
...           part.is_multipart())
True True
False False
False True
False False
False False
False True
False False
>>> _structure(msg)
multipart/report
    text/plain
    message/delivery-status
        text/plain
        text/plain
    message/rfc822
        text/plain

Здесь части message не являются multiparts, но содержат подчасти. is_multipart() возвращает True, а walk спускается в подчасти.

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()

Return an iterator over all of the immediate sub-parts of the message that are not candidate “body” parts. That is, skip the first occurrence of each of text/plain, text/html, multipart/related, or multipart/alternative (unless they are explicitly marked as attachments via Content-Disposition: attachment), and return all remaining parts. When applied directly to a multipart/related, return an iterator over the all the related parts except the root part (ie: the part pointed to by the start parameter, or the first part if there is no start parameter or the start parameter doesn’t match the Content-ID of any of the parts). When applied directly to a multipart/alternative or a non-multipart, return an empty iterator.

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-, оставляя все остальные заголовки нетронутыми и в исходном порядке.

Объекты EmailMessage имеют следующие атрибуты экземпляра:

preamble

Формат MIME-документа допускает наличие некоторого текста между пустой строкой после заголовков и первой строкой границы multipart. Обычно этот текст не виден в MIME-совместимом почтовом клиенте, поскольку он находится вне стандартной MIME-защиты. Однако при просмотре необработанного текста сообщения или при просмотре сообщения в клиенте, не поддерживающем MIME, этот текст может стать видимым.

Атрибут preamble содержит этот дополнительный текст за пределами MIME-защиты для MIME-документов. Когда Parser обнаруживает некоторый текст после заголовков, но до первой строки границы, он присваивает этот текст атрибуту preamble сообщения. Когда Generator записывает текстовое представление MIME-сообщения и обнаруживает, что сообщение имеет атрибут preamble, он записывает этот текст в области между заголовками и первой границей. Подробнее см. email.parser и email.generator.

Обратите внимание: если у объекта сообщения нет преамбулы, атрибут preamble будет равен None.

epilogue

Атрибут epilogue действует так же, как атрибут preamble, за исключением того, что он содержит текст, который появляется между последней границей и концом сообщения. Как и в случае с preamble, если текст эпилога отсутствует, этот атрибут будет равен None.

defects

Атрибут defects содержит список всех проблем, обнаруженных при разборе этого сообщения. См. email.errors для подробного описания возможных дефектов разбора.

class email.message.MIMEPart(policy=default)

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

Сноски

1

Изначально добавлено в 3.4 как временный модуль. Документация для устаревшего класса сообщений перемещена в email.message.Message: Представление email-сообщения с использованием compat32 API.