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

19.1.7. email.header: Интернационализированные заголовкиemail.header: Internationalized headers

RFC 2822 – это базовый стандарт, описывающий формат email-сообщений. Он происходит от более старого стандарта RFC 822, который получил широкое распространение в то время, когда большинство писем состояло только из символов ASCII. RFC 2822 – это спецификация, написанная в предположении, что email содержит только 7-битные символы ASCII.

Разумеется, с распространением электронной почты по всему миру она стала интернационализированной, так что теперь в сообщениях можно использовать языковые кодировки. Однако базовый стандарт по-прежнему требует, чтобы сообщения передавались только с использованием 7-битных символов ASCII, поэтому было написано множество RFC, описывающих, как кодировать не-ASCII символы в формат, совместимый с RFC 2822. Эти RFC включают RFC 2045, RFC 2046, RFC 2047 и RFC 2231. Пакет email поддерживает эти стандарты в своих модулях email.header и email.charset.

Если нужно включить не-ASCII символы в заголовки писем, например, в поля Subject или To, следует использовать класс Header и присвоить полю в объекте Message экземпляр Header вместо строки для значения заголовка. Импортируйте класс Header из модуля email.header. Например:

>>> from email.message import Message
>>> from email.header import Header
>>> msg = Message()
>>> h = Header('p\xf6stal', 'iso-8859-1')
>>> msg['Subject'] = h
>>> msg.as_string()
'Subject: =?iso-8859-1?q?p=F6stal?=\n\n'

Обратите внимание: мы хотели, чтобы поле Subject содержало не-ASCII символ? Для этого мы создали экземпляр Header и передали кодировку, в которой закодирована байтовая строка. Когда последующий экземпляр Message был преобразован в линейную форму, поле Subject было правильно закодировано по RFC 2047. Почтовые клиенты, поддерживающие MIME, отобразят этот заголовок с использованием встроенного символа ISO-8859-1.

Вот описание класса Header:

class email.header.Header(s=None, charset=None, maxlinelen=None, header_name=None, continuation_ws=' ', errors='strict')

Создаёт заголовок, совместимый с MIME, который может содержать строки в разных наборах символов.

Необязательный параметр s – это начальное значение заголовка. Если None (значение по умолчанию), начальное значение не задаётся. Позднее можно добавлять данные в заголовок вызовами метода append(). s может быть экземпляром bytes или str, но за разъяснением семантики обратитесь к документации append().

Optional charset serves two purposes: it has the same meaning as the charset argument to the append() method. It also sets the default character set for all subsequent append() calls that omit the charset argument. If charset is not provided in the constructor (the default), the us-ascii character set is used both as s‘s initial charset and as the default for subsequent append() calls.

Максимальную длину строки можно задать явно через maxlinelen. Чтобы разделить первую строку на более короткое значение (с учётом заголовка поля, который не входит в s, например Subject), передайте имя поля в параметре header_name. Значение по умолчанию для maxlinelen – 76, а значение по умолчанию для header_nameNone, то есть оно не учитывается для первой строки длинного разделённого заголовка.

Необязательный параметр continuation_ws должен быть пробельным символом для переноса, совместимым с RFC 2822, и обычно это пробел или символ табуляции. Этот символ будет добавляться в начало строк продолжения. По умолчанию continuation_ws – это одиночный пробел.

Необязательный параметр errors передаётся напрямую методу append().

append(s, charset=None, errors='strict')

Добавляет строку s к MIME-заголовку.

Необязательный параметр charset, если указан, должен быть экземпляром Charset (см. email.charset) или именем кодировки, которая будет преобразована в экземпляр Charset. Значение None (по умолчанию) означает, что используется charset, заданный в конструкторе.

s может быть экземпляром bytes или str. Если это экземпляр bytes, то charset – это кодировка этой байтовой строки, и будет вызвано исключение UnicodeError, если строку невозможно декодировать с помощью этой кодировки.

Если s – экземпляр str, то charset – это подсказка, указывающая кодировку символов в строке.

В любом случае, при создании заголовка, совместимого с RFC 2822, с использованием правил RFC 2047, строка будет закодирована с помощью выходного кодека набора символов. Если строка не может быть закодирована с помощью выходного кодека, будет возбуждено исключение UnicodeError.

Необязательный errors передаётся как аргумент errors при вызове decode, если s является байтовой строкой.

encode(splitchars=';, \t', maxlinelen=None, linesep='\n')

Кодирует заголовок сообщения в формат, соответствующий RFC, возможно, перенося длинные строки и инкапсулируя не-ASCII части в кодировки base64 или quoted-printable.

Необязательный параметр splitchars – это строка, содержащая символы, которым следует придавать дополнительный вес при разбиении во время обычного переноса заголовка. Это очень грубая поддержка «синтаксических разрывов высшего уровня» из RFC 2822: точки разбиения перед символом splitchar предпочтительнее при разбиении строк, причём символы предпочтительнее в порядке их появления в строке. Пробел и табуляция могут быть включены в строку, чтобы указать, какому из них отдавать предпочтение в качестве точки разбиения, когда другие символы разбиения отсутствуют в разбиваемой строке. Splitchars не влияет на строки, закодированные по RFC 2047.

maxlinelen, если указан, переопределяет значение экземпляра для максимальной длины строки.

linesep задаёт символы, используемые для разделения строк свёрнутого заголовка. По умолчанию используется наиболее полезное значение для кода приложений Python (\n), но можно указать \r\n для получения заголовков с разделителями строк, соответствующими RFC.

Изменено в версии 3.2: Добавлен аргумент linesep.

Класс Header также предоставляет ряд методов для поддержки стандартных операторов и встроенных функций.

__str__()

Возвращает приближённое представление Header в виде строки с неограниченной длиной строки. Все части преобразуются в Юникод с использованием указанной кодировки и соответствующим образом соединяются. Любые части с кодировкой 'unknown-8bit' декодируются как ASCII с использованием обработчика ошибок 'replace'.

Изменено в версии 3.2: Добавлена обработка кодировки 'unknown-8bit'.

__eq__(other)

Этот метод позволяет сравнивать два экземпляра Header на равенство.

__ne__(other)

Этот метод позволяет сравнивать два экземпляра Header на неравенство.

Модуль email.header также предоставляет следующие удобные функции.

email.header.decode_header(header)

Декодирует значение заголовка сообщения без преобразования набора символов. Значение заголовка находится в header.

Эта функция возвращает список пар (decoded_string, charset), содержащих каждую из декодированных частей заголовка. charset равен None для незакодированных частей заголовка, в противном случае это строка в нижнем регистре, содержащая имя кодировки, указанной в закодированной строке.

Вот пример:

>>> from email.header import decode_header
>>> decode_header('=?iso-8859-1?q?p=F6stal?=')
[(b'p\xf6stal', 'iso-8859-1')]
email.header.make_header(decoded_seq, maxlinelen=None, header_name=None, continuation_ws=' ')

Создаёт экземпляр Header из последовательности пар, возвращённой функцией decode_header().

Функция decode_header() принимает строку значения заголовка и возвращает последовательность пар формата (decoded_string, charset), где charset – имя кодировки.

Эта функция принимает одну из таких последовательностей пар и возвращает экземпляр Header. Необязательные параметры maxlinelen, header_name и continuation_ws такие же, как в конструкторе Header.