email.headerregistry: Benutzerdefinierte Header-Objekte¶
Quellcode: Lib/email/headerregistry.py
Hinzugefügt in Version 3.6: [1]
Header werden durch angepasste Unterklassen von str dargestellt. Die spezifische Klasse, die zur Darstellung eines bestimmten Headers verwendet wird, wird durch die header_factory der wirksamen policy bestimmt, wenn die Header erstellt werden. Dieser Abschnitt dokumentiert die spezifische header_factory, die vom email-Paket zur Verarbeitung von RFC 5322-konformen E-Mail-Nachrichten implementiert wird. Diese stellt nicht nur angepasste Header-Objekte für verschiedene Header-Typen bereit, sondern auch einen Erweiterungsmechanismus, damit Anwendungen ihre eigenen benutzerdefinierten Header-Typen hinzufügen können.
Bei Verwendung von Policy-Objekten, die von EmailPolicy abgeleitet sind, werden alle Header von HeaderRegistry erstellt und haben BaseHeader als ihre letzte Basisklasse. Jede Header-Klasse hat eine zusätzliche Basisklasse, die vom Typ des Headers bestimmt wird. Zum Beispiel haben viele Header die Klasse UnstructuredHeader als ihre andere Basisklasse. Die spezialisierte zweite Klasse für einen Header wird durch den Namen des Headers bestimmt, wobei eine Nachschlagetabelle in der HeaderRegistry gespeichert ist. All dies wird für das typische Anwendungsprogramm transparent verwaltet, aber Schnittstellen werden bereitgestellt, um das Standardverhalten für komplexere Anwendungen zu ändern.
Die folgenden Abschnitte dokumentieren zunächst die Basisklassen von Headern und ihre Attribute, gefolgt von der API zur Änderung des Verhaltens von HeaderRegistry und schließlich den unterstützenden Klassen, die zur Darstellung von Daten aus strukturierten Headern verwendet werden.
- class email.headerregistry.BaseHeader(name, value)¶
name und value werden vom
header_factory-Aufruf anBaseHeaderübergeben. Der String-Wert jedes Header-Objekts ist der value, der vollständig in Unicode dekodiert wurde.Diese Basisklasse definiert die folgenden schreibgeschützten Eigenschaften
- name¶
Der Name des Headers (der Teil des Feldes vor dem „:“). Dies ist exakt der Wert, der im Aufruf von
header_factoryfür name übergeben wird; das heißt, die Groß- und Kleinschreibung wird beibehalten.
- defects¶
Ein Tupel von
HeaderDefect-Instanzen, die alle bei der Analyse gefundenen RFC-Konformitätsprobleme melden. Das email-Paket versucht, die Konformitätsfragen vollständig zu erkennen. Siehe das Modulerrorsfür eine Diskussion der Arten von Defekten, die gemeldet werden können.
- max_count¶
Die maximale Anzahl von Headern dieses Typs, die denselben
namehaben können. Ein Wert vonNonebedeutet unbegrenzt. DerBaseHeader-Wert für dieses Attribut istNone; es wird erwartet, dass spezialisierte Header-Klassen diesen Wert bei Bedarf überschreiben.
BaseHeaderbietet auch die folgende Methode, die vom email-Bibliotheks-Code aufgerufen wird und im Allgemeinen nicht von Anwendungsprogrammen aufgerufen werden sollte.- fold(*, policy)¶
Gibt einen String zurück, der
linesep-Zeichen enthält, wie sie erforderlich sind, um den Header gemäß policy korrekt umzubrechen. Eincte_typevon8bitwird so behandelt, als wäre er7bit, da Header keine beliebigen Binärdaten enthalten dürfen. Wennutf8Falseist, werden Nicht-ASCII-Daten gemäß RFC 2047 kodiert.
BaseHeaderallein kann nicht zur Erstellung eines Header-Objekts verwendet werden. Es definiert ein Protokoll, mit dem jede spezialisierte Klasse zusammenarbeitet, um das Header-Objekt zu erzeugen. Insbesondere verlangtBaseHeader, dass die spezialisierte Klasse eineclassmethod()namensparsebereitstellt. Diese Methode wird wie folgt aufgerufen:parse(string, kwds)
kwdsist ein Wörterbuch, das einen vorinitialisierten Schlüssel,defects, enthält.defectsist eine leere Liste. Die Parse-Methode sollte alle erkannten Defekte zu dieser Liste hinzufügen. Nach der Rückgabe muss das Wörterbuchkwdsmindestens die Schlüsseldecodedunddefectsenthalten.decodedsollte der String-Wert für den Header sein (d. h. der Header-Wert, der vollständig in Unicode dekodiert wurde). Die Parse-Methode sollte davon ausgehen, dass string Content-Transfer-Encoding-Teile enthalten kann, aber alle gültigen Unicode-Zeichen korrekt behandeln, damit sie nicht kodierte Header-Werte parsen kann.BaseHeader's__new__erstellt dann die Header-Instanz und ruft ihreinit-Methode auf. Die spezialisierte Klasse muss nur eineinit-Methode bereitstellen, wenn sie zusätzliche Attribute über die vonBaseHeaderselbst bereitgestellten hinaus festlegen möchte. Eine solcheinit-Methode sollte wie folgt aussehen:def init(self, /, *args, **kw): self._myattr = kw.pop('myattr') super().init(*args, **kw)
Das heißt, alles zusätzliche, das die spezialisierte Klasse in das Wörterbuch
kwdseinfügt, sollte entfernt und verarbeitet werden, und der verbleibende Inhalt vonkw(undargs) sollte an dieBaseHeaderinit-Methode übergeben werden.
- class email.headerregistry.UnstructuredHeader¶
Ein „unstrukturierter“ Header ist der Standardtyp des Headers in RFC 5322. Jeder Header, der keine spezifizierte Syntax hat, wird als unstrukturiert behandelt. Das klassische Beispiel für einen unstrukturierten Header ist der Subject-Header.
In RFC 5322 ist ein unstrukturierter Header eine Aneinanderreihung von beliebigen Texten im ASCII-Zeichensatz. RFC 2047 hat jedoch einen mit RFC 5322 kompatiblen Mechanismus zur Kodierung von Nicht-ASCII-Text als ASCII-Zeichen innerhalb eines Header-Werts. Wenn ein value, das kodierte Wörter enthält, an den Konstruktor übergeben wird, konvertiert der
UnstructuredHeader-Parser solche kodierten Wörter in Unicode, wobei die Regeln von RFC 2047 für unstrukturierte Texte befolgt werden. Der Parser verwendet Heuristiken, um zu versuchen, bestimmte nicht konforme kodierte Wörter zu dekodieren. In solchen Fällen werden Defekte registriert, ebenso wie Defekte für Probleme wie ungültige Zeichen innerhalb der kodierten Wörter oder des nicht kodierten Textes.Dieser Header-Typ bietet keine zusätzlichen Attribute.
- class email.headerregistry.DateHeader¶
RFC 5322 gibt ein sehr spezifisches Format für Daten in E-Mail-Headern vor. Der
DateHeader-Parser erkennt dieses Datumsformat und auch eine Reihe von alternativen Formen, die manchmal „in freier Wildbahn“ gefunden werden.Dieser Header-Typ bietet die folgenden zusätzlichen Attribute
- datetime¶
Wenn der Header-Wert als gültiges Datum einer oder anderer Form erkannt werden kann, enthält dieses Attribut eine
datetime-Instanz, die dieses Datum repräsentiert. Wenn die Zeitzone des Eingabedatums als-0000angegeben ist (was bedeutet, dass es in UTC ist, aber keine Informationen über die Quellzeitzone enthält), dann istdatetimeein naivesdatetime. Wenn ein spezifischer Zeitzonen-Offset gefunden wird (einschließlich+0000), dann enthältdatetimeein awaredatetime, dasdatetime.timezoneverwendet, um den Zeitzonen-Offset zu speichern.
Der
decoded-Wert des Headers wird durch Formatieren desdatetimegemäß den Regeln von RFC 5322 bestimmt; das heißt, er wird gesetzt aufemail.utils.format_datetime(self.datetime)
Beim Erstellen eines
DateHeaderkann value einedatetime-Instanz sein. Dies bedeutet beispielsweise, dass der folgende Code gültig ist und das tut, was man erwarten würde.msg['Date'] = datetime(2011, 7, 15, 21)
Da dies ein naives
datetimeist, wird es als UTC-Zeitstempel interpretiert und der resultierende Wert hat eine Zeitzone von-0000. Viel nützlicher ist die Verwendung der Funktionlocaltime()aus dem Modulutils.msg['Date'] = utils.localtime()
Dieses Beispiel setzt den Datums-Header auf die aktuelle Zeit und das aktuelle Datum unter Verwendung des aktuellen Zeitzonen-Offsets.
- class email.headerregistry.AddressHeader¶
Adress-Header sind einer der komplexesten strukturierten Header-Typen. Die Klasse
AddressHeaderbietet eine generische Schnittstelle zu jedem Adress-Header.Dieser Header-Typ bietet die folgenden zusätzlichen Attribute
- groups¶
Ein Tupel von
Group-Objekten, die die im Header-Wert gefundenen Adressen und Gruppen kodieren. Adressen, die nicht Teil einer Gruppe sind, werden in dieser Liste als einzelne Adress-Groupsdargestellt, derendisplay_nameNoneist.
- addresses¶
Ein Tupel von
Address-Objekten, die alle einzelnen Adressen aus dem Header-Wert kodieren. Wenn der Header-Wert Gruppen enthält, werden die einzelnen Adressen aus der Gruppe an der Stelle, an der die Gruppe im Wert vorkommt, in die Liste aufgenommen (d. h. die Liste der Adressen wird zu einer eindimensionalen Liste „abgeflacht“).
Der
decoded-Wert des Headers enthält alle dekodierten kodierten Wörter in Unicode.idna-kodierte Domain-Namen werden ebenfalls in Unicode dekodiert. Derdecoded-Wert wird durch Verknüpfen desstr-Werts der Elemente desgroups-Attributs mit', 'gesetzt.Eine Liste von
Address- undGroup-Objekten in beliebiger Kombination kann verwendet werden, um den Wert eines Adress-Headers festzulegen.Group-Objekte, derendisplay_nameNoneist, werden als einzelne Adressen interpretiert, was es ermöglicht, eine Adressliste mit intakten Gruppen zu kopieren, indem die aus demgroups-Attribut des Quell-Headers erhaltene Liste verwendet wird.
- class email.headerregistry.SingleAddressHeader¶
Eine Unterklasse von
AddressHeader, die ein zusätzliches Attribut hinzufügt- address¶
Die einzelne Adresse, die vom Header-Wert kodiert wird. Wenn der Header-Wert tatsächlich mehr als eine Adresse enthält (was unter der Standard-
policyeine Verletzung der RFC wäre), führt der Zugriff auf dieses Attribut zu einemValueError.
Viele der oben genannten Klassen haben auch eine Unique-Variante (zum Beispiel UniqueUnstructuredHeader). Der einzige Unterschied ist, dass in der Unique-Variante max_count auf 1 gesetzt ist.
- class email.headerregistry.MIMEVersionHeader¶
Es gibt eigentlich nur einen gültigen Wert für den MIME-Version-Header, und das ist
1.0. Zur Zukunftssicherheit unterstützt diese Header-Klasse andere gültige Versionsnummern. Wenn eine Versionsnummer einen gültigen Wert gemäß RFC 2045 hat, dann hat das Header-Objekt nicht-None-Werte für die folgenden Attribute:- version¶
Die Versionsnummer als String, wobei etwaige Leerzeichen und/oder Kommentare entfernt wurden.
- major¶
Die Hauptversionsnummer als Integer
- minor¶
Die Nebenversionsnummer als Integer
- class email.headerregistry.ParameterizedMIMEHeader¶
MIME-Header beginnen alle mit dem Präfix „Content-“. Jeder spezifische Header hat einen bestimmten Wert, der unter der Klasse für diesen Header beschrieben wird. Einige können auch eine Liste von ergänzenden Parametern annehmen, die ein gängiges Format haben. Diese Klasse dient als Basis für alle MIME-Header, die Parameter akzeptieren.
- params¶
Ein Wörterbuch, das Parameternamen auf Parameterwerte abbildet.
- class email.headerregistry.ContentTypeHeader¶
Eine Klasse vom Typ
ParameterizedMIMEHeader, die den Header Content-Type verarbeitet.- content_type¶
Der Content-Type-String im Format
maintype/subtype.
- maintype¶
- subtype¶
- class email.headerregistry.ContentDispositionHeader¶
Eine Klasse vom Typ
ParameterizedMIMEHeader, die den Header Content-Disposition verarbeitet.- content_disposition¶
inlineundattachmentsind die einzigen gebräuchlichen gültigen Werte.
- class email.headerregistry.ContentTransferEncoding¶
Verarbeitet den Header Content-Transfer-Encoding.
- class email.headerregistry.HeaderRegistry(base_class=BaseHeader, default_class=UnstructuredHeader, use_default_map=True)¶
Dies ist die Factory, die standardmäßig von
EmailPolicyverwendet wird.HeaderRegistryerstellt dynamisch die Klasse, die zur Erstellung einer Header-Instanz verwendet wird, indem base_class und eine spezialisierte Klasse aus einem von ihr gehaltenen Registry verwendet werden. Wenn ein gegebener Header-Name nicht im Registry erscheint, wird die von default_class angegebene Klasse als spezialisierte Klasse verwendet. Wenn use_default_mapTrue(Standard) ist, wird die Standardzuordnung von Header-Namen zu Klassen bei der Initialisierung in das Registry kopiert. base_class ist immer die letzte Klasse in der Liste__bases__der generierten Klasse.Die Standardzuordnungen sind:
- 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
HeaderRegistryhat die folgenden Methoden:- map_to_type(self, name, cls)¶
name ist der Name des Headers, der zugeordnet werden soll. Er wird im Registry in Kleinbuchstaben umgewandelt. cls ist die spezialisierte Klasse, die zusammen mit base_class verwendet wird, um die Klasse zur Instanziierung von Headern zu erstellen, die name entsprechen.
- __getitem__(name)¶
Konstruiert und gibt eine Klasse zurück, die zur Erstellung eines name-Headers verwendet wird.
- __call__(name, value)¶
Ruft den spezialisierten Header, der name zugeordnet ist, aus dem Registry ab (verwendet default_class, wenn name nicht im Registry vorkommt) und kombiniert ihn mit base_class, um eine Klasse zu erstellen. Ruft den Konstruktor der erstellten Klasse auf und übergibt ihr dieselbe Argumentenliste. Gibt schließlich die dadurch erstellte Klasseninstanz zurück.
Die folgenden Klassen sind die Klassen, die zur Darstellung von Daten aus strukturierten Headern verwendet werden und im Allgemeinen von einem Anwendungsprogramm zum Erstellen von strukturierten Werten zur Zuweisung an bestimmte Header verwendet werden können.
- class email.headerregistry.Address(display_name='', username='', domain='', addr_spec=None)¶
Die Klasse, die zur Darstellung einer E-Mail-Adresse verwendet wird. Die allgemeine Form einer Adresse lautet
[display_name] <username@domain>
oder
username@domain
wobei jeder Teil spezifischen Syntaxregeln entsprechen muss, die in RFC 5322 festgelegt sind.
Als Komfortfunktion kann addr_spec anstelle von username und domain angegeben werden. In diesem Fall werden username und domain aus addr_spec extrahiert. Eine addr_spec muss ein ordnungsgemäß RFC-kodierter String sein; wenn dies nicht der Fall ist, löst
Addresseinen Fehler aus. Unicode-Zeichen sind zulässig und werden beim Serialisieren ordnungsgemäß kodiert. Gemäß den RFCs ist Unicode jedoch NICHT im Benutzernamen (username) der Adresse zulässig.- display_name¶
Der Anzeigeteil (display name) der Adresse, falls vorhanden, ohne jegliche Kodierung. Wenn die Adresse keinen Anzeigeteil hat, ist dieses Attribut ein leerer String.
- username¶
Der
username-Teil der Adresse, ohne jegliche Kodierung.
- domain¶
Der
domain-Teil der Adresse.
- addr_spec¶
Der
username@domain-Teil der Adresse, korrekt für die Verwendung als reine Adresse kodiert (die zweite oben gezeigte Form). Dieses Attribut ist nicht veränderbar.
- __str__()¶
Der
str-Wert des Objekts ist die Adresse, die gemäß den Regeln von RFC 5322 kodiert ist, jedoch ohne Content Transfer Encoding von Nicht-ASCII-Zeichen.
Zur Unterstützung von SMTP (RFC 5321) behandelt
Addresseinen Sonderfall: Wennusernameunddomainbeide leer sind (oderNone), dann ist der String-Wert vonAddress<>.
- class email.headerregistry.Group(display_name=None, addresses=None)¶
Die Klasse, die zur Darstellung einer Adressgruppe verwendet wird. Die allgemeine Form einer Adressgruppe lautet
display_name: [address-list];
Um die Verarbeitung von Adresslisten zu erleichtern, die eine Mischung aus Gruppen und einzelnen Adressen enthalten, kann eine
Groupauch verwendet werden, um einzelne Adressen darzustellen, die keiner Gruppe angehören, indem display_name aufNonegesetzt und eine Liste der einzelnen Adresse als addresses bereitgestellt wird.- display_name¶
Der
display_nameder Gruppe. Wenn erNoneist und genau eineAddressinaddressesvorhanden ist, repräsentiert dieGroupeine einzelne Adresse, die keiner Gruppe angehört.
Fußnoten