email.headerregistry
: Пользовательские объекты заголовков¶
Источник: Lib/email/headerregistry.py
Added in version 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
. Строковое значение любого объекта заголовка - это значение, полностью декодированное в юникод.Этот базовый класс определяет следующие свойства, доступные только для чтения:
- name¶
Имя заголовка (часть поля перед „:“). Это именно то значение, которое было передано в вызове
header_factory
для name; то есть регистр сохраняется.
- defects¶
Кортеж из
HeaderDefect
экземпляров, сообщающих о любых проблемах с соответствием RFC, обнаруженных при разборе. Пакет email старается быть полным в обнаружении проблем с соответствием. Обсуждение типов дефектов, о которых может быть сообщено, см. в модулеerrors
.
- max_count¶
Максимальное количество заголовков данного типа, которые могут иметь одинаковый
name
. ЗначениеNone
означает неограниченное количество. ЗначениеBaseHeader
для этого атрибута равноNone
; ожидается, что специализированные классы заголовков будут переопределять это значение по мере необходимости.
BaseHeader
также предоставляет следующий метод, который вызывается кодом библиотеки электронной почты и, как правило, не должен вызываться прикладными программами:- fold(*, policy)¶
Возвращает строку, содержащую
linesep
символов, необходимых для корректного сворачивания заголовка в соответствии с политикой. Если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-символов в значении заголовка. Когда в конструктор передается значение, содержащее кодированные слова, парсер
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
, значение может быть экземпляром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
задается joining значением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.
- 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__
генерируемых классов.По умолчанию используются следующие отображения:
- тема:
UniqueUnstructuredHeader
- дата:
UniqueDateHeader
- дата отправки:
DateHeader
- дата происхождения:
UniqueDateHeader
- отправитель:
UniqueSingleAddressHeader
- отправитель-отправитель:
SingleAddressHeader
- на:
UniqueAddressHeader
- resent-to:
AddressHeader
- cc:
UniqueAddressHeader
- resent-cc:
AddressHeader
- bcc:
UniqueAddressHeader
- resent-bcc:
AddressHeader
- с сайта:
UniqueAddressHeader
- resent-from:
AddressHeader
- ответ на:
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.
Для удобства вместо username и domain можно указать addr_spec, в этом случае username и domain будут разобраны из addr_spec. addr_spec должен быть правильной строкой, заключенной в кавычки RFC; если это не так, то
Address
вызовет ошибку. Символы Юникода разрешены и будут закодированы в свойствах при сериализации. Однако, согласно RFC, юникод не разрешен в части имени пользователя адреса.- display_name¶
Часть адреса, содержащая отображаемое имя, если таковое имеется, с удалением всех кавычек. Если адрес не имеет отображаемого имени, этот атрибут будет пустой строкой.
- username¶
Часть адреса
username
, в которой удалены все кавычки.
- domain¶
Часть адреса
domain
.
- addr_spec¶
Часть адреса
username@domain
, правильно заключенная в кавычки для использования в качестве пустого адреса (вторая форма, показанная выше). Этот атрибут не изменяется.
- __str__()¶
Значение
str
объекта - это адрес, приведенный в соответствии с правилами RFC 5322, но без кодировки Content Transfer Encoding любых не-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
представляет собой один адрес, который не входит в группу.
Сноски