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

email.message.Message: представление email-сообщения с помощью API compat32email.message.Message: Representing an email message using the compat32 API

Класс Message очень похож на класс EmailMessage, но без методов, добавленных в этом классе, и с немного отличающимся поведением по умолчанию некоторых других методов. Здесь также описаны методы, которые, хотя и поддерживаются классом EmailMessage, не рекомендуются к использованию, кроме случаев работы с устаревшим кодом.

В остальном философия и структура обоих классов одинаковы.

В этом документе описывается поведение при использовании политики Compat32 по умолчанию (для Message). При использовании другой политики следует использовать класс EmailMessage.

An email message consists of headers and a payload. Headers must be RFC 5322 style 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.

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

Псевдословарь Message индексируется по именам заголовков, которые должны быть значениями ASCII. Значения словаря – строки, которые должны содержать только символы ASCII; предусмотрена специальная обработка для входных данных, не являющихся ASCII, но она не всегда дает правильные результаты. Заголовки хранятся и возвращаются с сохранением регистра, но имена полей сопоставляются без учета регистра. Также может присутствовать единичный конвертный заголовок, также известный как заголовок Unix-From или заголовок From_. Полезная нагрузка представляет собой либо строку, либо байты в случае простых объектов сообщений, либо список объектов Message для документов-контейнеров MIME (например, multipart/* и message/rfc822).

Ниже приведены методы класса Message:

class email.message.Message(policy=compat32)

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

Изменено в версии 3.3: Был добавлен именованный аргумент policy.

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

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

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

Обратите внимание, что этот метод предоставляется для удобства и не всегда форматирует сообщение так, как требуется. Например, по умолчанию он не выполняет преобразование строк, начинающихся с From, которое требуется для формата Unix mbox. Для большей гибкости создайте экземпляр Generator и используйте его метод flatten() напрямую. Например:

from io import StringIO
from email.generator import Generator
fp = StringIO()
g = Generator(fp, mangle_from_=True, maxheaderlen=60)
g.flatten(msg)
text = fp.getvalue()

Если объект сообщения содержит двоичные данные, которые не закодированы в соответствии со стандартами RFC, несоответствующие данные будут заменены на кодовые точки Unicode «неизвестный символ». (См. также as_bytes() и BytesGenerator.)

Изменено в версии 3.4: Добавлен именованный аргумент policy.

__str__()

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

as_bytes(unixfrom=False, policy=None)

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

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

Обратите внимание, что этот метод предоставляется для удобства и не всегда форматирует сообщение так, как требуется. Например, по умолчанию он не выполняет преобразование строк, начинающихся с From, которое требуется для формата Unix mbox. Для большей гибкости создайте экземпляр BytesGenerator и используйте его метод flatten() напрямую. Например:

from io import BytesIO
from email.generator import BytesGenerator
fp = BytesIO()
g = BytesGenerator(fp, mangle_from_=True, maxheaderlen=60)
g.flatten(msg)
text = fp.getvalue()

Добавлено в версии 3.4.

__bytes__()

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

Добавлено в версии 3.4.

is_multipart()

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

set_unixfrom(unixfrom)

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

get_unixfrom()

Return the message’s envelope header. Defaults to None if the envelope header was never set.

attach(payload)

Add the given payload to the current payload, which must be None or a list of Message objects before the call. After the call, the payload will always be a list of Message objects. If you want to set the payload to a scalar object (e.g. a string), use set_payload() instead.

This is a legacy method. On the EmailMessage class its functionality is replaced by set_content() and the related make and add methods.

get_payload(i=None, decode=False)

Return the current payload, which will be a list of Message objects when is_multipart() is True, or a string when is_multipart() is False. If the payload is a list and you mutate the list object, you modify the message’s payload in place.

With optional argument i, get_payload() will return the i-th element of the payload, counting from zero, if is_multipart() is True. An IndexError will be raised if i is less than 0 or greater than or equal to the number of items in the payload. If the payload is a string (i.e. is_multipart() is False) and i is given, a TypeError is raised.

Optional decode is a flag indicating whether the payload should be decoded or not, according to the Content-Transfer-Encoding header. When True and the message is not a multipart, the payload will be decoded if this header’s value is quoted-printable or base64. If some other encoding is used, or Content-Transfer-Encoding header is missing, the payload is returned as-is (undecoded). In all cases the returned value is binary data. If the message is a multipart and the decode flag is True, then None is returned. If the payload is base64 and it was not perfectly formed (missing padding, characters outside the base64 alphabet), then an appropriate defect will be added to the message’s defect property (InvalidBase64PaddingDefect or InvalidBase64CharactersDefect, respectively).

When decode is False (the default) the body is returned as a string without decoding the Content-Transfer-Encoding. However, for a Content-Transfer-Encoding of 8bit, an attempt is made to decode the original bytes using the charset specified by the Content-Type header, using the replace error handler. If no charset is specified, or if the charset given is not recognized by the email package, the body is decoded using the default ASCII charset.

This is a legacy method. On the EmailMessage class its functionality is replaced by get_content() and iter_parts().

set_payload(payload, charset=None)

Set the entire message object’s payload to payload. It is the client’s responsibility to ensure the payload invariants. Optional charset sets the message’s default character set; see set_charset() for details.

This is a legacy method. On the EmailMessage class its functionality is replaced by set_content().

set_charset(charset)

Set the character set of the payload to charset, which can either be a Charset instance (see email.charset), a string naming a character set, or None. If it is a string, it will be converted to a Charset instance. If charset is None, the charset parameter will be removed from the Content-Type header (the message will not be otherwise modified). Anything else will generate a TypeError.

If there is no existing MIME-Version header one will be added. If there is no existing Content-Type header, one will be added with a value of text/plain. Whether the Content-Type header already exists or not, its charset parameter will be set to charset.output_charset. If charset.input_charset and charset.output_charset differ, the payload will be re-encoded to the output_charset. If there is no existing Content-Transfer-Encoding header, then the payload will be transfer-encoded, if needed, using the specified Charset, and a header with the appropriate value will be added. If a Content-Transfer-Encoding header already exists, the payload is assumed to already be correctly encoded using that Content-Transfer-Encoding and is not modified.

This is a legacy method. On the EmailMessage class its functionality is replaced by the charset parameter of the email.message.EmailMessage.set_content() method.

get_charset()

Return the Charset instance associated with the message’s payload.

This is a legacy method. On the EmailMessage class it always returns None.

The following methods implement a mapping-like interface for accessing the message’s RFC 2822 headers. Note that there are some semantic differences between these methods and a normal mapping (i.e. dictionary) interface. For example, in a dictionary there are no duplicate keys, but here there may be duplicate message headers. Also, in dictionaries there is no guaranteed order to the keys returned by keys(), but in a Message object, headers are always returned in the order they appeared in the original message, or were added to the message later. Any header deleted and then re-added are always appended to the end of the header list.

These semantic differences are intentional and are biased toward maximal convenience.

Note that in all cases, any envelope header present in the message is not included in the mapping interface.

In a model generated from bytes, any header values that (in contravention of the RFCs) contain non-ASCII bytes will, when retrieved through this interface, be represented as Header objects with a charset of unknown-8bit.

__len__()

Return the total number of headers, including duplicates.

__contains__(name)

Return True if the message object has a field named name. Matching is done case-insensitively and name should not include the trailing colon. Used for the in operator, e.g.:

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

Return the value of the named header field. name should not include the colon field separator. If the header is missing, None is returned; a KeyError is never raised.

Note that if the named field appears more than once in the message’s headers, exactly which of those field values will be returned is undefined. Use the get_all() method to get the values of all the extant named headers.

__setitem__(name, val)

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

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

del msg['subject']
msg['subject'] = 'Python roolz!'
__delitem__(name)

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

keys()

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

values()

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

items()

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

get(name, failobj=None)

Возвращает значение указанного поля заголовка. Этот метод идентичен методу __getitem__() за исключением того, что если указанный заголовок отсутствует, возвращается необязательный параметр 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'))

Что даёт

Content-Disposition: attachment; filename*="iso-8859-1''Fu%DFballer.ppt"
replace_header(_name, _value)

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

get_content_type()

Возвращает тип содержимого сообщения. Возвращаемая строка приводится к нижнему регистру в форме maintype/subtype. Если в сообщении не было заголовка Content-Type, будет возвращен тип по умолчанию, заданный get_default_type(). Поскольку согласно 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_params(failobj=None, header='content-type', unquote=True)

Возвращает параметры заголовка Content-Type сообщения в виде списка. Элементы возвращаемого списка – кортежи из двух элементов (ключ/значение), разделённые знаком '='. Левая часть от '=' – ключ, а правая – значение. Если в параметре нет знака '=', значением является пустая строка; в противном случае значение соответствует get_param() и не экранируется, если необязательный параметр unquote равен True (по умолчанию).

Необязательный параметр failobj – объект, возвращаемый при отсутствии заголовка Content-Type. Необязательный параметр header – заголовок, который нужно искать вместо Content-Type.

Это устаревший метод. В классе EmailMessage его функциональность заменена свойством params отдельных объектов заголовков, возвращаемых методами доступа к заголовкам.

get_param(param, failobj=None, header='content-type', unquote=True)

Возвращает значение параметра param заголовка Content-Type в виде строки. Если сообщение не содержит заголовка Content-Type или такого параметра нет, возвращается failobj (по умолчанию None).

Необязательный параметр header, если указан, задаёт заголовок сообщения, который следует использовать вместо Content-Type.

Ключи параметров всегда сравниваются без учёта регистра. Возвращаемое значение может быть строкой или кортежем из трёх элементов, если параметр был закодирован по RFC 2231. Если это кортеж из трёх элементов, элементы значения имеют вид (CHARSET, LANGUAGE, VALUE). Обратите внимание, что и CHARSET, и LANGUAGE могут быть None; в этом случае следует считать, что VALUE закодирован в кодировке us-ascii. Обычно LANGUAGE можно игнорировать.

Если вашему приложению безразлично, был ли параметр закодирован по RFC 2231, можно свернуть значение параметра, вызвав email.utils.collapse_rfc2231_value() и передав возвращаемое значение из get_param(). Это вернёт подходящим образом декодированную строку Unicode, если значение является кортежем, или исходную строку без кавычек, если нет. Например:

rawparam = msg.get_param('foo')
param = email.utils.collapse_rfc2231_value(rawparam)

В любом случае значение параметра (возвращённая строка или элемент VALUE кортежа из трёх элементов) всегда не экранируется, если только unquote не установлен в False.

Это устаревший метод. В классе EmailMessage его функциональность заменена свойством params отдельных объектов заголовков, возвращаемых методами доступа к заголовкам.

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

Устанавливает параметр в заголовке Content-Type. Если параметр уже существует в заголовке, его значение будет заменено на value. Если заголовок Content-Type ещё не задан для этого сообщения, он будет установлен в text/plain, а новое значение параметра будет добавлено в соответствии с RFC 2045.

Необязательный параметр header задаёт альтернативный заголовок для Content-Type; все параметры будут экранированы при необходимости, если только необязательный параметр requote не равен False (по умолчанию True).

Если указан необязательный параметр charset, параметр будет закодирован в соответствии с RFC 2231. Необязательный параметр language задаёт язык по RFC 2231, по умолчанию – пустая строка. И charset, и language должны быть строками.

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

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

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

Полностью удаляет указанный параметр из заголовка Content-Type. Заголовок будет перезаписан на месте без параметра и его значения. Все значения будут экранированы при необходимости, если только requote не равен False (по умолчанию True). Необязательный параметр header задаёт альтернативу заголовку Content-Type.

set_type(type, header='Content-Type', requote=True)

Устанавливает основной тип и подтип для заголовка Content-Type. type должен быть строкой вида maintype/subtype, в противном случае возбуждается ValueError.

Этот метод заменяет заголовок Content-Type, сохраняя все параметры на месте. Если requote равен False, экранирование существующего заголовка остаётся без изменений; в противном случае параметры будут экранированы (по умолчанию).

Альтернативный заголовок можно указать в аргументе header. При установке заголовка Content-Type также добавляется заголовок MIME-Version.

Это устаревший метод. В классе EmailMessage его функциональность заменена методами make_ и add_.

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 в кавычки при необходимости. Если у объекта сообщения нет заголовка Content-Type, вызывается HeaderParseError.

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

get_content_charset(failobj=None)

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

Обратите внимание, что этот метод отличается от get_charset(), который возвращает экземпляр Charset для кодировки тела сообщения по умолчанию.

get_charsets(failobj=None)

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

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

get_content_disposition()

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

Добавлено в версии 3.5.

walk()

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

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

>>> 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 спускается во вложенные части.

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

preamble

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

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

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

epilogue

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

Нет необходимости устанавливать epilogue в пустую строку, чтобы Generator выводил символ новой строки в конце файла.

defects

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