email.header: Cabeceras internacionalizadas

Código fuente: Lib/email/header.py


Este módulo es parte de la API de email heredada (Compat32). En la API actual, la codificación y decodificación de las cabeceras se gestiona de forma transparente por la API de tipo diccionario de la clase EmailMessage. Además de los usos del código heredado, este módulo puede ser útil en aplicaciones que necesiten controlar completamente el conjunto de caracteres usado cuando se codifican las cabeceras.

El resto del texto de esta sección es la documentación original del módulo.

RFC 2822 es el estándar base que describe el formato de los mensajes de correo electrónico. Deriva del estándar anterior RFC 822, cuyo uso se generalizó durante una época en la que la mayoría del correo electrónico se componía únicamente de caracteres ASCII. RFC 2822 es una especificación que se escribió asumiendo que el correo electrónico contiene solo caracteres ASCII 7-bit.

Por supuesto, al haberse extendido el correo electrónico por todo el mundo, se ha internacionalizado, de forma que ahora pueden usarse los conjuntos de caracteres específicos de un idioma en los mensajes de correo electrónico. El estándar base todavía requiere que los mensajes de correo electrónico sean transferidos usando solo caracteres ASCII 7-bit, así que se han escrito multitud de RFCs describiendo cómo codificar correos electrónicos que contengan caracteres no ASCII en formatos conforme a la RFC 2822. Entre estas RFCs se incluyen RFC 2045, RFC 2046, RFC 2047 y RFC 2231. El paquete email soporta estos estándares en sus módulos email.header y email.charset.

Si quieres incluir caracteres no ASCII en tus cabeceras de correo electrónico, por ejemplo en los campos Subject o To, deberías usar la clase Header y asignar el campo del objeto Message a una instancia de Header en vez de usar una cadena de caracteres para el valor de la cabecera. Importa la clase Header del módulo email.header. Por ejemplo:

>>> 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'

¿Has visto cómo hemos hecho que el campo Subject contuviera un caracter no ASCII? Lo hemos hecho creando una instancia de Header y pasándole el conjunto de caracteres en los que estaba codificado la cadena de bytes. Cuando la instancia de Message subsecuente se ha aplanado, el campo Subject se ha codificado en RFC 2047 adecuadamente. Los lectores de correo que soportan MIME deberían mostrar esta cabecera usando el caracter ISO-8859-1 incrustado.

Aquí está la descripción de la clase Header:

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

Crea una cabecera conforme a las especificaciones MIME que contiene cadenas de caracteres en diferentes conjuntos de caracteres.

El argumento opcional s es el valor inicial de la cabecera. Si es None (el valor por defecto), el valor inicial de la cabecera quedará sin asignar. Puedes añadirlo luego a la cabecera con llamadas al método append(). s debe ser una instancia de bytes o str, pero lee la documentación de append() para conocer los detalles semánticos.

El argumento opcional charset sirve para dos propósitos: tiene el mismo significado que el argumento charset en el método append(). También asigna el conjunto de caracteres por defecto para todas las llamadas subsecuentes a append() que omitan el argumento charset. Si no se proporciona charset en el constructor (por defecto), el conjunto de caracteres us-ascii se usa tanto para el conjunto de caracteres inicial de s como por defecto para las llamadas subsecuentes a append().

La longitud de línea máxima puede especificarse explícitamente con maxlinelen. Para dividir la primera línea en un valor más corto (teniendo en cuenta los campos de la cabecera que no están incluidos en s, por ejemplo Subject), pasar el nombre del campo en header_name. El valor por defecto de maxlinelen es 76, y el valor por defecto de header_name es None, lo que quiere decir que no se tiene en cuenta para una cabecera larga dividida.

El argumento opcional continuation_ws debe ser conforme a las normas de espacios en blanco plegables de la RFC 2822, y normalmente es o un espacio o un caracter tabulador. Este caracter se antepondrá delante de las líneas continuadas. El valor por defecto de continuation_ws es un solo espacio.

El argumento opcional errors se pasa directamente a través del método append().

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

Añade la cadena de caracteres s a la cabecera MIME.

El argumento opcional charset, si se proporciona, debe ser una instancia de Charset (ver email.charset) o el nombre de un conjunto de datos, que deberá ser convertido a una instancia de Charset. Un valor de None (el valor por defecto) significa que se usará el charset dado en el constructor.

s puede ser una instancia de bytes o de str. Si es una instancia de bytes, entonces charset es la codificación de esa cadena de bytes, y se lanzará un UnicodeError si la cadena de caracteres no puede decodificarse con ese conjunto de caracteres.

Si s es una instancia de str, entonces charset es una sugerencia que especifica el conjunto de caracteres usando en la cadena de caracteres.

En cualquier caso, cuando se produce una cabecera conforme a la RFC 2822 usando las reglas de la RFC 2047, la cadena de caracteres se codificará usando el códec de salida del conjunto de caracteres. Si la cadena de caracteres no puede codificarse usando el códec de salida, se lanzará un UnicodeError.

El argumento opcional errors se pasa como el argumento de errores para la llamada de decodificación si s es una cadena de bits.

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

Codifica un mensaje de la cabecera en un formato conforme a RFC, posiblemente envolviendo las líneas largas y encapsulando las partes no ASCII en base64 o en codificaciones imprimibles entrecomilladas.

El argumento opcional splitchars es una cadena de caracteres que contiene caracteres a los que el algoritmo de separación debería asignar espacio extra durante la encapsulación de la cabecera normal. Esto da un basto soporte a los saltos sintácticos de alto nivel de la RFC 2822: los puntos de separación precedidos por un caracter separador tienen preferencia durante la separación de la línea, con preferencia de caracteres en el orden en el que aparecen en la cadena de caracteres. El espacio y el tabulador pueden incluirse en la cadena de caracteres para indicar si se debería dar preferencia a uno sobre el otro como punto de separación cuando no aparezcan otros caracteres separadores en la línea que se está dividiendo. Los caracteres separadores no afectan a las líneas codificadas de la RFC 2047.

maxlinelen, si se proporciona, sobrescribe el valor de longitud de línea máxima para la instancia.

linesep especifica los caracteres usados para separar las líneas de la cabecera plegada. Su valor por defecto es el valor más útil para el código de una aplicación Python (\n), pero se puede especificar \r\n para producir cabeceras con separadores de línea conforme a RFCs.

Distinto en la versión 3.2: Argumento linesep añadido.

La clase Header también proporciona una serie de métodos para soportar operaciones estándar y funciones incorporadas.

__str__()

Retorna una aproximación de Header como una cadena de caracteres, usando una longitud de línea ilimitada. Todas las piezas se convierten a unicode utilizando la codificación especificada y unidas adecuadamente. Todas las piezas con un conjunto de caracteres 'unknown-8bit' se decodifican como ASCII usando el gestor de errores de 'replace'.

Distinto en la versión 3.2: Añadida gestión del conjunto de caracteres 'unknown-8bit'.

__eq__(other)

Este método permite comparar si dos instancias de Header son iguales.

__ne__(other)

Este método permite comparar si dos instancias de Header no son iguales.

El módulo email.header También proporciona las prácticas funciones que se indican a continuación.

email.header.decode_header(header)

Decodifica el valor de un mensaje de la cabecera sin convertir el conjunto de caracteres. El valor de la cabecera está en header.

Esta función retorna una lista de duplas (decoded_string, charset) que contiene cada una de las partes decodificadas de la cabecera. charset será None para las partes no codificadas de la cabecera, de lo contrario será una cadena de caracteres en minúscula con el nombre del conjunto de caracteres especificado en la cadena de caracteres codificada.

Aquí va un ejemplo:

>>> 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=' ')

Crea una instancia de Header a partir de una secuencia de duplas como las retornadas por decode_header().

decode_header() toma el valor de una cadena de caracteres de la cabecera y retorna una secuencia de duplas con el formato (decoded_string, charset), donde charset es el nombre del conjunto de caracteres.

Esta función toma una de esas secuencias de duplas y retorna una instancia de Header. Los argumentos opcionales maxlinelen, header_name y continuation_ws son como los del constructor Header.