email.header : en-têtes internationalisés

Code source : Lib/email/headers.py


Ce module fait partie de l'ancienne API de messagerie (Compat32). Dans l'API actuelle, l'encodage et le décodage des en-têtes sont gérés de manière transparente par l'API de type dictionnaire de la classe EmailMessage. En plus des utilisations dans de l'ancien code, ce module peut être utile dans les applications qui doivent contrôler complètement les jeux de caractères utilisés lors de l'encodage des en-têtes.

Le texte restant de cette section est la documentation originale de ce module.

La RFC 2822 est la norme de base qui décrit le format des messages électroniques. Elle dérive de l'ancienne norme RFC 822 qui s'est généralisée à une époque où la plupart des e-mails étaient composés uniquement de caractères ASCII. La RFC 2822 est une spécification écrite en supposant que le courrier électronique ne contient que des caractères ASCII 7 bits.

Bien sûr, à mesure que le courrier électronique a été déployé dans le monde, il s'est internationalisé, de sorte que des jeux de caractères spécifiques à une langue peuvent désormais être utilisés dans les messages électroniques. La norme de base exige toujours que les messages électroniques soient transférés en utilisant uniquement des caractères ASCII 7 bits, de sorte qu'un grand nombre de RFC décrivent comment encoder les e-mails contenant des caractères non ASCII dans le format conforme à la RFC 2822. Ces RFC incluent la RFC 2045, la RFC 2046, la RFC 2047 et la RFC 2231. Le paquet email gère ces normes dans ses modules email.header et email.charset.

Si vous souhaitez inclure des caractères non-ASCII dans les en-têtes de vos e-mails, par exemple dans les champs Subject ou To, vous devez utiliser la classe Header et affecter le champ dans le Message à une instance de Header au lieu d'utiliser une chaîne pour la valeur de l'en-tête. Importez la classe Header du module email.header. Par exemple :

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

Remarquez ici comment nous voulions que le champ Subject contienne un caractère non-ASCII : nous avons créé une instance Header et transmis le jeu de caractères dans lequel la chaîne d'octets était encodée. Lorsque l'instance suivante Message a été aplatie, le champ Subject était correctement encodé selon la RFC 2047. Les lecteurs de courrier compatibles MIME afficheraient cet en-tête en utilisant le caractère ISO-8859-1 intégré.

Voici la description de la classe Header :

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

Crée un en-tête compatible MIME pouvant contenir des chaînes dans différents jeux de caractères.

s (facultatif) est la valeur d'en-tête initiale. S'il vaut None (valeur par défaut), la valeur d'en-tête initiale n'est pas définie. Vous pouvez ensuite ajouter des choses à l'en-tête avec des appels de méthode append(). s peut être une instance de bytes ou str, mais consultez la documentation append() pour la sémantique.

L'option charset sert à deux fins : elle a la même signification que l'argument charset de la méthode append(). Elle définit également le jeu de caractères par défaut pour tous les appels suivants append() qui omettent l'argument charset. Si charset n'est pas fourni dans le constructeur (par défaut), le jeu de caractères us-ascii est utilisé à la fois comme jeu de caractères initial de s et comme jeu par défaut pour les appels suivants à append().

La longueur de ligne maximale peut être spécifiée explicitement via maxlinelen. Pour diviser la première ligne en une valeur plus courte (pour tenir compte de l'en-tête de champ qui n'est pas inclus dans s, par exemple Subject) passez le nom du champ dans header_name. La valeur par défaut maxlinelen est 76 et la valeur par défaut pour header_name est None, ce qui signifie qu'elle n'est pas prise en compte pour la première ligne d'un long en-tête divisé.

continuation_ws (facultatif) doit être conforme aux caractères de reformatage RFC 2822 ; c'est généralement soit une espace, soit un caractère de tabulation fixe. Ce caractère est ajouté aux lignes de continuation. continuation_ws utilise par défaut une seule espace.

errors (facultatif) est transmis directement à la méthode append().

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

Ajoute la chaîne s à l'en-tête MIME.

Le charset facultatif, s'il est fourni, doit être une instance de Charset (voir email.charset) ou le nom d'un jeu de caractères, qui est converti en une instance Charset. Une valeur None (la valeur par défaut) signifie que le charset donné dans le constructeur est utilisé.

s peut être une instance de bytes ou str. S'il s'agit d'une instance de bytes, alors charset est l'encodage de cette chaîne d'octets et une UnicodeError est levée si la chaîne ne peut pas être décodée avec ce jeu de caractères.

Si s est une instance de str, alors charset est une indication spécifiant le jeu de caractères des caractères de la chaîne.

Dans les deux cas, lors de la production d'un en-tête conforme à la RFC 2822 à l'aide des règles RFC 2047, la chaîne est encodée à l'aide du codec de sortie du jeu de caractères. Si la chaîne ne peut pas être encodée à l'aide du codec de sortie, une erreur UnicodeError est levée.

L'option errors est transmise comme argument d'erreurs à l'appel de décodage si s est une chaîne d'octets.

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

Encode un en-tête de message dans un format conforme à la RFC, en reformatant éventuellement de longues lignes et en encapsulant des parties non ASCII dans des encodages base64 ou dits quoted-printable (c.-à-d. que, par exemple, les caractères non ASCII sont représentés par un signe égal, suivi de son numéro, exprimé en hexadécimal).

splitchars (facultatif) est une chaîne contenant des caractères auxquels l'algorithme de fractionnement doit donner un poids supplémentaire lors du reformatage normal de l'en-tête. Il s'agit d'une prise en charge très approximative des « ruptures syntaxiques de niveau supérieur » de la RFC 2822 : les points de séparation précédés d'un caractère de séparation sont préférés lors de la séparation des lignes, les caractères étant préférés dans l'ordre dans lequel ils apparaissent dans la chaîne. Une espace et une tabulation peuvent être incluses dans la chaîne pour indiquer si la préférence doit être donnée à l'une plutôt qu'à l'autre comme point de partage lorsque d'autres caractères fractionnés n'apparaissent pas dans la ligne fractionnée. splitchars n'affecte pas les lignes encodées selon la RFC 2047.

maxlinelen, s'il est fourni, remplace la valeur de l'instance pour la longueur de ligne maximale.

linesep spécifie les caractères utilisés pour séparer les lignes de l'en-tête plié. Il prend par défaut la valeur la plus utile pour le code d'application Python (\n), mais \r\n peut être spécifié afin de produire des en-têtes avec des séparateurs de ligne conformes à la RFC.

Modifié dans la version 3.2: ajout de l'argument linesep.

La classe Header fournit également un certain nombre de méthodes pour prendre en charge les opérateurs standard et les fonctions intégrées.

__str__()

Renvoie une approximation de Header sous forme de chaîne, en utilisant une longueur de ligne illimitée. Toutes les parties sont converties en Unicode en utilisant l'encodage spécifié et réunies de manière appropriée. Tous les morceaux avec un charset à 'unknown-8bit' sont décodés en ASCII en utilisant le gestionnaire d'erreurs 'replace'.

Modifié dans la version 3.2: ajout de la gestion du jeu de caractères 'unknown-8bit'.

__eq__(other)

Cette méthode vous permet de tester l'égalité de deux instances de Header.

__ne__(other)

Cette méthode vous permet de tester l'inégalité de deux instances de Header.

Le module email.header fournit également les fonctions pratiques suivantes.

email.header.decode_header(header)

Décode une valeur d'en-tête de message sans convertir le jeu de caractères. La valeur de l'en-tête est dans header.

Cette fonction renvoie une liste de paires (decoded_string, charset) contenant chacune des parties décodées de l'en-tête. charset est None pour les parties non encodées de l'en-tête, sinon une chaîne en minuscules contenant le nom du jeu de caractères spécifié dans la chaîne encodée.

Voici un exemple :

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

Crée une instance Header à partir d'une séquence de paires renvoyées par decode_header().

decode_header() prend une chaîne de valeur d'en-tête et renvoie une séquence de paires au format (decoded_string, charset)charset est le nom du jeu de caractères.

Cette fonction prend l'une de ces séquences de paires et renvoie une instance Header. maxlinelen, header_name et continuation_ws (facultatifs) s'utilisent comme dans le constructeur Header.