email.headerregistry
: пользовательские объекты заголовков
Добавлено в версии 3.6: [1]
Заголовки представлены настраиваемыми str
подклассами.
Используемый для представления заголовка класс, определяется
header_factory
policy
,
действующим при создании заголовков. В этом разделе рассматривается
header_factory
, реализованный пакетом email для обработки
сообщений электронной почты, совместимых с RFC 5322, который не только
предоставляет настраиваемые объекты заголовков для различных типов заголовков,
но также предоставляет механизм расширения для приложений, позволяющий
добавлять свои настраиваемые типы заголовков.
При использовании любого из объектов политики, производных от
EmailPolicy
, все заголовки создаются
HeaderRegistry
и содержат BaseHeader
в качестве последнего
базового класса. Каждый класс заголовка содержит дополнительный базовый класс,
определяемый типом заголовка. Например, у многих заголовков есть класс
UnstructuredHeader
в качестве другого базового класса.
Специализированный второй класс для заголовка определяется именем заголовка с
использованием таблицы поиска, хранящейся в HeaderRegistry
. Все это
управляется прозрачно для типичной прикладной программы, но предусмотрены
интерфейсы для изменения поведения по умолчанию для использования более
сложными приложениями.
В разделах ниже сначала описаны базовые классы заголовков и их атрибуты, затем
API для изменения поведения HeaderRegistry
и классы
поддержки, используемые для представления данных, распарсенных из
структурированных заголовков.
-
class
email.headerregistry.
BaseHeader
(name, value) name и value передаются в
BaseHeader
из вызоваheader_factory
. Строковое значение любого объекта заголовка — value, полностью декодированное в Юникод.Данный базовый класс определяет следующие свойства только для чтения:
-
name
Имя заголовка (часть поля перед «:»). Это именно то значение, которое было передано в вызове
header_factory
для name; т. е. регистр сохраняется.
-
defects
Кортеж из экземпляров
HeaderDefect
, сообщающих о любых проблемах с соответствием RFC, обнаруженных во время парсинга. Пакет email пытается завершить обнаружение проблем соответствия. См. модульerrors
для обсуждения типов дефектов, о которых можно сообщать.
-
max_count
Максимальное количество заголовков данного типа, у которых может быть один и тот же
name
. ЗначениеNone
означает неограниченное количество. ЗначениеBaseHeader
для этого атрибута —None
; ожидается, что специализированные классы заголовков будут переопределять это значение по мере необходимости.
BaseHeader
также предоставляет следующий метод, который вызывается кодом библиотеки email и обычно не должен вызываться прикладными программами:-
fold
(*, policy) Возвращает строку, содержащую
linesep
символов, необходимую для правильного сворачивания заголовка в соответствии с policy.cte_type
из8bit
будет рассматриваться как7bit
, поскольку заголовки не могут содержать произвольные двоичные данные. Еслиutf8
равенFalse
, отличные от ASCII данные, будут закодированы как RFC 2047.
BaseHeader
сам по себе не может использоваться для создания объекта заголовка. Он определяет протокол, с которым взаимодействует каждый специализированный заголовок для создания объекта заголовка. В частности,BaseHeader
требует, чтобы специализированный класс предоставлялclassmethod()
с именемparse
. Данный метод называется следующим образом:parse(string, kwds)
kwds
— это словарь, содержащий один предварительно инициализированный ключdefects
.defects
— пустой список. Метод парсинга должен добавлять в данный список все обнаруженные дефекты. По возвращении словарьkwds
должен содержать значения как минимум для ключейdecoded
иdefects
.decoded
должно быть строковым значением для заголовка (т. е. полностью декодированным в Юникод значением заголовка). Метод парсинга должен предполагать, что string может содержать части, закодированные при передаче содержимого, но также должен правильно обрабатывать все допустимые символы Юникода, чтобы он мог парсить незакодированные значения заголовков.Затем
BaseHeader
__new__
создаёт экземпляр заголовка и вызывает его методinit
. Специализированный класс должен предоставить методinit
только в том случае, если он хочет установить дополнительные атрибуты помимо тех, которые предоставляются самимBaseHeader
. Такой методinit
должен выглядеть так:def init(self, /, *args, **kw): self._myattr = kw.pop('myattr') super().init(*args, **kw)
Т. е. все лишнее, что специализированный класс помещает в словарь
kwds
, должно быть удалено и обработано, а оставшееся содержимоеkw
(иargs
) передано в методBaseHeader
init
.-
-
class
email.headerregistry.
UnstructuredHeader
«Неструктурированный» заголовок — это тип заголовка по умолчанию в RFC 5322. Любой заголовок, не имеющий указанного синтаксиса, считается неструктурированным. Классический пример неструктурированного заголовка — заголовок Subject.
В RFC 5322 неструктурированный заголовок представляет собой множество произвольного текста в множестве ASCII символов. Однако у RFC 2047 есть совместимый с RFC 5322 механизм, для кодирования отличного от ASCII текста, в виде символов ASCII в значении заголовка. Когда содержащий закодированные слова value, передаётся конструктору, парсер
UnstructuredHeader
преобразует закодированные слова в Юникод, следуя правилам RFC 2047 для неструктурированного текста. Парсер использует эвристику, чтобы попытаться декодировать определённые несовместимые закодированные слова. В таких случаях регистрируются дефекты, а также дефекты по таким вопросам, как недопустимые символы в закодированных словах или незакодированный текст.Данный тип заголовка не предоставляет никаких дополнительных атрибутов.
-
class
email.headerregistry.
DateHeader
RFC 5322 указывает очень специфический формат для дат в заголовках электронной почты. Парсер
DateHeader
распознает данный формат даты, а также распознает ряд вариантов форм, которые иногда встречаются «в дикой природе».Данный тип заголовка предоставляет следующие дополнительные атрибуты:
-
datetime
Если значение заголовка может быть распознано как допустимая дата той или иной формы, данный атрибут будет содержать экземпляр
datetime
, представляющий эту дату. Если часовой пояс входной даты указан как-0000
(указывая, что он указан в формате UTC, но не содержит информации об исходном часовом поясе), тогдаdatetime
будет наивнымdatetime
. Если найдено определённое смещение часового пояса (включая +0000), тоdatetime
будет содержать осведомленныйdatetime
, который используетdatetime.timezone
для записи смещения часового пояса.
Значение заголовка
decoded
определяется путём форматированияdatetime
в соответствии с правилами RFC 5322; т. е. установлено:email.utils.format_datetime(self.datetime)
При создании
DateHeader
value может быть экземпляромdatetime
. Это означает, например, что следующий код действителен и делает то, что можно было бы ожидать:msg['Date'] = datetime(2011, 7, 15, 21)
Поскольку это наивный
datetime
, он будет интерпретирован как временная метка UTC, а результирующее значение будет в часовом поясе-0000
. Гораздо полезнее использовать функциюlocaltime()
из модуляutils
:msg['Date'] = utils.localtime()
В этом примере заголовок даты задается текущим временем и датой, используя текущее смещение часового пояса.
-
-
class
email.headerregistry.
AddressHeader
Заголовки адресов являются одним из наиболее сложных структурированных типов заголовков. Класс
AddressHeader
предоставляет общий интерфейс для любого заголовка адреса.Данный тип заголовка предоставляет следующие дополнительные атрибуты:
-
groups
Кортеж из объектов
Group
, кодирующих адреса и группы, найденные в значении заголовка. Адреса, не входящие в группу, представлены в этом списке как одноадресныйGroups
,display_name
которыйNone
.
-
addresses
Кортеж из объектов
Address
, кодирующих все отдельные адреса из значения заголовка. Если значение заголовка содержит какие-либо группы, отдельные адреса из группы включаются в список в той точке, где группа встречается в значении (т. е. список адресов «сглаживается» до одномерного списка).
Значение заголовка
decoded
будет иметь все закодированные слова, декодированные в Юникод. Доменные имена в кодировкеidna
также декодируются в Юникод. Значениеdecoded
задаетсяjoin
значениемstr
элементов атрибутаgroups
с', '
.Список объектов
Address
иGroup
в любой комбинации может использоваться для установки значения заголовка адреса. ОбъектыGroup
, чейdisplay_name
равенNone
, будут интерпретироваться как одиночные адреса, что позволяет копировать список адресов с целыми группами, используя список, полученный из атрибутаgroups
исходного заголовка.-
-
class
email.headerregistry.
SingleAddressHeader
Подкласс
AddressHeader
, добавляющий один дополнительный атрибут:-
address
Единственный адрес, закодированный значением заголовка. Если значение заголовка на самом деле содержит более одного адреса (что было бы нарушением RFC по умолчанию
policy
), доступ к этому атрибуту приведёт кValueError
.
-
Многие из вышеперечисленных классов также содержат вариант Unique
(например,
UniqueUnstructuredHeader
). Единственное отличие состоит в том, что в
варианте Unique
для max_count
установлено значение 1.
-
class
email.headerregistry.
MIMEVersionHeader
На самом деле существует только одно допустимое значение для заголовка MIME-Version —
1.0
. Для проверки в будущем данный класс заголовков поддерживает другие допустимые номера версий. Если номер версии имеет допустимое значение для RFC 2045, то у объекта заголовка будут значения, отличные отNone
, для следующих атрибутов:-
version
Номер версии в виде строки с удаленными пробелами и/или комментариями.
-
major
Основной номер версии в виде целого числа.
-
minor
Дополнительный номер версии в виде целого числа.
-
-
class
email.headerregistry.
ParameterizedMIMEHeader
Все MIME заголовки начинаются с префикса «Content-». Каждый заголовок имеет определённое значение, описанное в разделе класса для данного заголовка. Некоторые также могут принять список дополнительных параметров, которые имеют общий формат. Данный класс служит основой для всех MIME заголовков, которые принимают параметры.
-
params
Словарь, сопоставляющий имена параметров со значениями параметров.
-
-
class
email.headerregistry.
ContentTypeHeader
Класс
ParameterizedMIMEHeader
, обрабатывающий заголовок Content-Type.-
content_type
Строка типа содержимого в формате
maintype/subtype
.
-
maintype
-
subtype
-
-
class
email.headerregistry.
ContentDispositionHeader
Класс
ParameterizedMIMEHeader
, который обрабатывает заголовок Content-Disposition.-
content_disposition
inline
иattachment
являются единственными общепринятыми допустимыми значениями.
-
-
class
email.headerregistry.
ContentTransferEncoding
Обрабатывает заголовок Content-Transfer-Encoding.
-
cte
Допустимые значения:
7bit
,8bit
,base64
иquoted- printable
. См. RFC 2045 для получения дополнительной информации.
-
-
class
email.headerregistry.
HeaderRegistry
(base_class=BaseHeader, default_class=UnstructuredHeader, use_default_map=True) Это фабрика, используемая
EmailPolicy
по умолчанию.HeaderRegistry
строит класс, используемый для динамического создания экземпляра заголовка, используя base_class и специализированный класс, полученный из хранящегося в нем реестра. Если заданное имя заголовка отсутствует в реестре, в качестве специализированного класса используется класс, указанный в default_class. Когда use_default_map равенTrue
(по умолчанию), стандартное сопоставление имён заголовков с классами копируется в реестр во время инициализации. base_class всегда является последним классом в списке__bases__
сгенерированного класса.Отображения по умолчанию:
subject: UniqueUnstructuredHeader date: UniqueDateHeader resent-date: DateHeader orig-date: UniqueDateHeader sender: UniqueSingleAddressHeader resent-sender: SingleAddressHeader to: UniqueAddressHeader resent-to: AddressHeader cc: UniqueAddressHeader resent-cc: AddressHeader bcc: UniqueAddressHeader resent-bcc: AddressHeader from: UniqueAddressHeader resent-from: AddressHeader reply-to: UniqueAddressHeader mime-version: MIMEVersionHeader content-type: ContentTypeHeader content-disposition: ContentDispositionHeader content-transfer-encoding: ContentTransferEncodingHeader message-id: MessageIDHeader У
HeaderRegistry
есть следующие методы:-
map_to_type
(self, name, cls) name — это имя заголовка для сопоставления. Он будет преобразован в нижний регистр в реестре. cls — это специализированный класс, который следует использовать вместе с base_class для создания класса, используемого для создания соответствующих name экземпляров заголовков.
-
__getitem__
(name) Создаёт и возвращает класс для обработки создания name заголовка.
-
__call__
(name, value) Извлекает из реестра специализированный заголовок, связанный с name (используя default_class, если name не отображается в реестре) и объединяет его с base_class для создания класса, вызывает конструктор созданного класса, передавая ему тот же список аргументов и возвращает класс созданный таким образом экземпляр.
-
Следующие классы — это классы, используемые для представления данных, распарсенных из структурированных заголовков, и, как правило, могут использоваться прикладной программой для создания структурированных значений для назначения определенным заголовкам.
-
class
email.headerregistry.
Address
(display_name='', username='', domain='', addr_spec=None) Класс, используемый для представления адреса электронной почты. Общая форма адреса такова:
[display_name] <username@domain>
или:
username@domain
где каждая часть должна соответствовать определенным правилам синтаксиса, изложенным в RFC 5322.
Для удобства можно указать addr_spec вместо username и domain, и в этом случае username и domain будут распарсенны из addr_spec. Строка addr_spec должна быть правильно заключена в RFC кавычки; если это не
Address
, возникнет ошибка. Разрешены символы Юникода, и они будут закодированы свойством при сериализации. Тем не менее, в соответствии с документами RFC, в части имени пользователя в адресе не разрешен Юникод.-
display_name
Часть отображаемого имени адреса, если таковая имеется, с удаленными кавычками. Если адрес не имеет отображаемого имени, данный атрибут будет пустой строкой.
-
username
Часть адреса
username
с удаленными кавычками.
-
domain
Часть адреса
domain
.
-
addr_spec
Часть адреса
username@domain
, правильно указанная для использования в качестве простого адреса (вторая форма показана выше). Данный атрибут не является изменяемым.
-
__str__
() Значение
str
объекта — это адрес, указанный в соответствии с правилами RFC 5322, но без кодирования передачи содержимого любых символов, отличных от ASCII.
Для поддержки SMTP (RFC 5321)
Address
обрабатывает один особый случай: еслиusername
иdomain
являются пустой строкой (илиNone
), то строковое значениеAddress
равно<>
.-
-
class
email.headerregistry.
Group
(display_name=None, addresses=None) Класс, используемый для представления группы адресов. Общая форма адресной группы такова:
display_name: [address-list];
Для удобства обработки списков адресов, состоящих из смеси групп и отдельных адресов,
Group
также можно использовать для представления отдельных адресов, не входящих в группу, установив display_name наNone
и предоставив список одного адреса как addresses.-
display_name
display_name
группы. Если этоNone
и вaddresses
есть ровно одинAddress
, тоGroup
представляет собой один адрес, не входящий в группу.
-
addresses
Возможно, пустой кортеж объектов
Address
, представляющих адреса в группе.
-
__str__
() Значение
str
Group
отформатировано в соответствии с RFC 5322, но без кодирования передачи содержимого любых символов, отличных от ASCII. Еслиdisplay_name
отсутствует и в спискеaddresses
есть одинAddress
, значениеstr
будет таким же, какstr
данногоAddress
.
-
Сноски
[1] | Первоначально добавлен в 3.3 как предварительный модуль |