19.1.6.email.contentmanager: Managing MIME Content

New in version 3.4:as aprovisional module.

Source code:Lib/email/contentmanager.py

Note

The contentmanager module has been included in the standard library on aprovisional basis. Backwards incompatiblechanges (up to and including removal of the module) may occur if deemednecessary by the core developers.


Themessage module provides a class that can represent anarbitrary email message. That basic message model has a useful and flexibleAPI, but it provides only a lower-level API for interacting with the genericparts of a message (the headers, generic header parameters, and the payload,which may be a list of sub-parts). This module provides classes and toolsthat provide an enhanced and extensible API for dealing with various specifictypes of content, including the ability to retrieve the content of the messageas a specialized object type rather than as a simple bytes object. The moduleautomatically takes care of the RFC-specified MIME details (required headersand parameters, etc.) for the certain common content types content properties,and support for additional types can be added by an application using theextension mechanisms.

This module defines the eponymous “Content Manager” classes. The baseContentManager class defines an API for registering contentmanagement functions which extract data fromMessage objects or insert dataand headers intoMessage objects, thus providing a way of convertingbetweenMessage objects containing data and other representations of thatdata (Python data types, specialized Python objects, external files, etc). Themodule also defines one concrete content manager:raw_data_managerconverts between MIME content types andstr orbytes data. It alsoprovides a convenient API for managing the MIME parameters when insertingcontent intoMessages. It also handles inserting and extractingMessage objects when dealing with themessage/rfc822 content type.

Another part of the enhanced interface is subclasses ofMessage that provide new convenience API functions,including convenience methods for calling the Content Managers derived fromthis module.

Note

AlthoughEmailMessage andMIMEPart are currentlydocumented in this module because of the provisional nature of the code, theimplementation lives in theemail.message module.

classemail.message.EmailMessage(policy=default)

Ifpolicy is specified (it must be an instance of apolicyclass) use the rules it specifies to update and serialize the representationof the message. Ifpolicy is not set, use thedefault policy, which follows the rules of the emailRFCs except for line endings (instead of the RFC mandated\r\n, it usesthe Python standard\n line endings). For more information see thepolicy documentation.

This class is a subclass ofMessage. It addsthe following methods:

is_attachment()

ReturnTrue if there is aContent-Disposition headerand its (case insensitive) value isattachment,False otherwise.

Changed in version 3.4.2:is_attachment is now a method instead of a property, for consistencywithis_multipart().

get_body(preferencelist=('related','html','plain'))

Return the MIME part that is the best candidate to be the “body” of themessage.

preferencelist must be a sequence of strings from the setrelated,html, andplain, and indicates the order of preference for thecontent type of the part returned.

Start looking for candidate matches with the object on which theget_body method is called.

Ifrelated is not included inpreferencelist, consider the rootpart (or subpart of the root part) of any related encountered as acandidate if the (sub-)part matches a preference.

When encountering amultipart/related, check thestart parameterand if a part with a matchingContent-ID is found, consideronly it when looking for candidate matches. Otherwise consider only thefirst (default root) part of themultipart/related.

If a part has aContent-Disposition header, only considerthe part a candidate match if the value of the header isinline.

If none of the candidates matches any of the preferences inpreferencelist, returnNone.

Notes: (1) For most applications the onlypreferencelist combinationsthat really make sense are('plain',),('html','plain'), and thedefault,('related','html','plain'). (2) Because matching startswith the object on whichget_body is called, callingget_body onamultipart/related will return the object itself unlesspreferencelist has a non-default value. (3) Messages (or message parts)that do not specify aContent-Type or whoseContent-Type header is invalid will be treated as if theyare of typetext/plain, which may occasionally causeget_body toreturn unexpected results.

iter_attachments()

Return an iterator over all of the parts of the message that are notcandidate “body” parts. That is, skip the first occurrence of each oftext/plain,text/html,multipart/related, ormultipart/alternative (unless they are explicitly marked asattachments viaContent-Disposition: attachment), andreturn all remaining parts. When applied directly to amultipart/related, return an iterator over the all the related partsexcept the root part (ie: the part pointed to by thestart parameter,or the first part if there is nostart parameter or thestartparameter doesn’t match theContent-ID of any of theparts). When applied directly to amultipart/alternative or anon-multipart, return an empty iterator.

iter_parts()

Return an iterator over all of the immediate sub-parts of the message,which will be empty for a non-multipart. (See alsowalk().)

get_content(*args,content_manager=None,**kw)

Call theget_content method of thecontent_manager, passing selfas the message object, and passing along any other arguments or keywordsas additional arguments. Ifcontent_manager is not specified, usethecontent_manager specified by the currentpolicy.

set_content(*args,content_manager=None,**kw)

Call theset_content method of thecontent_manager, passing selfas the message object, and passing along any other arguments or keywordsas additional arguments. Ifcontent_manager is not specified, usethecontent_manager specified by the currentpolicy.

make_related(boundary=None)

Convert a non-multipart message into amultipart/related message,moving any existingContent- headers and payload into a(new) first part of themultipart. Ifboundary is specified, useit as the boundary string in the multipart, otherwise leave the boundaryto be automatically created when it is needed (for example, when themessage is serialized).

make_alternative(boundary=None)

Convert a non-multipart or amultipart/related into amultipart/alternative, moving any existingContent-headers and payload into a (new) first part of themultipart. Ifboundary is specified, use it as the boundary string in the multipart,otherwise leave the boundary to be automatically created when it isneeded (for example, when the message is serialized).

make_mixed(boundary=None)

Convert a non-multipart, amultipart/related, or amultipart-alternative into amultipart/mixed, moving any existingContent- headers and payload into a (new) first part of themultipart. Ifboundary is specified, use it as the boundary stringin the multipart, otherwise leave the boundary to be automaticallycreated when it is needed (for example, when the message is serialized).

add_related(*args,content_manager=None,**kw)

If the message is amultipart/related, create a new messageobject, pass all of the arguments to itsset_content() method,andattach() it to themultipart. Ifthe message is a non-multipart, callmake_related() and thenproceed as above. If the message is any other type ofmultipart,raise aTypeError. Ifcontent_manager is not specified, usethecontent_manager specified by the currentpolicy.If the added part has noContent-Disposition header,add one with the valueinline.

add_alternative(*args,content_manager=None,**kw)

If the message is amultipart/alternative, create a new messageobject, pass all of the arguments to itsset_content() method, andattach() it to themultipart. If themessage is a non-multipart ormultipart/related, callmake_alternative() and then proceed as above. If the message isany other type ofmultipart, raise aTypeError. Ifcontent_manager is not specified, use thecontent_manager specifiedby the currentpolicy.

add_attachment(*args,content_manager=None,**kw)

If the message is amultipart/mixed, create a new message object,pass all of the arguments to itsset_content() method, andattach() it to themultipart. If themessage is a non-multipart,multipart/related, ormultipart/alternative, callmake_mixed() and then proceed asabove. Ifcontent_manager is not specified, use thecontent_managerspecified by the currentpolicy. If the added parthas noContent-Disposition header, add one with the valueattachment. This method can be used both for explicit attachments(Content-Disposition: attachment andinline attachments(Content-Disposition: inline), by passing appropriateoptions to thecontent_manager.

clear()

Remove the payload and all of the headers.

clear_content()

Remove the payload and all of theContent- headers, leavingall other headers intact and in their original order.

classemail.message.MIMEPart(policy=default)

This class represents a subpart of a MIME message. It is identical toEmailMessage, except that noMIME-Version headers areadded whenset_content() is called, since sub-parts donot need their ownMIME-Version headers.

classemail.contentmanager.ContentManager

Base class for content managers. Provides the standard registry mechanismsto register converters between MIME content and other representations, aswell as theget_content andset_content dispatch methods.

get_content(msg,*args,**kw)

Look up a handler function based on themimetype ofmsg (see nextparagraph), call it, passing through all arguments, and return the resultof the call. The expectation is that the handler will extract thepayload frommsg and return an object that encodes information aboutthe extracted data.

To find the handler, look for the following keys in the registry,stopping with the first one found:

  • the string representing the full MIME type (maintype/subtype)
  • the string representing themaintype
  • the empty string

If none of these keys produce a handler, raise aKeyError for thefull MIME type.

set_content(msg,obj,*args,**kw)

If themaintype ismultipart, raise aTypeError; otherwiselook up a handler function based on the type ofobj (see nextparagraph), callclear_content() on themsg, and call the handler function, passing through all arguments. Theexpectation is that the handler will transform and storeobj intomsg, possibly making other changes tomsg as well, such as addingvarious MIME headers to encode information needed to interpret the storeddata.

To find the handler, obtain the type ofobj (typ=type(obj)), andlook for the following keys in the registry, stopping with the first onefound:

  • the type itself (typ)
  • the type’s fully qualified name (typ.__module__+'.'+typ.__qualname__).
  • the type’s qualname (typ.__qualname__)
  • the type’s name (typ.__name__).

If none of the above match, repeat all of the checks above for each ofthe types in theMRO (typ.__mro__). Finally, if no other keyyields a handler, check for a handler for the keyNone. If there isno handler forNone, raise aKeyError for the fullyqualified name of the type.

Also add aMIME-Version header if one is not present (seealsoMIMEPart).

add_get_handler(key,handler)

Record the functionhandler as the handler forkey. For the possiblevalues ofkey, seeget_content().

add_set_handler(typekey,handler)

Recordhandler as the function to call when an object of a typematchingtypekey is passed toset_content(). For the possiblevalues oftypekey, seeset_content().

19.1.6.1. Content Manager Instances

Currently the email package provides only one concrete content manager,raw_data_manager, although more may be added in the future.raw_data_manager is thecontent_manager provided byEmailPolicy and its derivatives.

email.contentmanager.raw_data_manager

This content manager provides only a minimum interface beyond that providedbyMessage itself: it deals only with text, rawbyte strings, andMessage objects. Nevertheless, itprovides significant advantages compared to the base API:get_content ona text part will return a unicode string without the application needing tomanually decode it,set_content provides a rich set of options forcontrolling the headers added to a part and controlling the content transferencoding, and it enables the use of the variousadd_ methods, therebysimplifying the creation of multipart messages.

email.contentmanager.get_content(msg,errors='replace')

Return the payload of the part as either a string (fortext parts), anEmailMessage object (formessage/rfc822parts), or abytes object (for all other non-multipart types). RaiseaKeyError if called on amultipart. If the part is atext part anderrors is specified, use it as the error handler whendecoding the payload to unicode. The default error handler isreplace.

email.contentmanager.set_content(msg,<'str'>,subtype="plain",charset='utf-8' cte=None,disposition=None,filename=None,cid=None,params=None,headers=None)
email.contentmanager.set_content(msg,<'bytes'>,maintype,subtype,cte="base64",disposition=None,filename=None,cid=None,params=None,headers=None)
email.contentmanager.set_content(msg,<'Message'>,cte=None,disposition=None,filename=None,cid=None,params=None,headers=None)
email.contentmanager.set_content(msg,<'list'>,subtype='mixed',disposition=None,filename=None,cid=None,params=None,headers=None)

Add headers and payload tomsg:

Add aContent-Type header with amaintype/subtypevalue.

  • Forstr, set the MIMEmaintype totext, and set thesubtype tosubtype if it is specified, orplain if it is not.
  • Forbytes, use the specifiedmaintype andsubtype, orraise aTypeError if they are not specified.
  • ForMessage objects, set the maintype tomessage, and set the subtype tosubtype if it is specifiedorrfc822 if it is not. Ifsubtype ispartial, raise anerror (bytes objects must be used to constructmessage/partial parts).
  • For<’list’>, which should be a list ofMessage objects, set themaintype tomultipart, and thesubtype tosubtype if it isspecified, andmixed if it is not. If the message parts inthe<’list’> haveMIME-Version headers, removethem.

Ifcharset is provided (which is valid only forstr), encode thestring to bytes using the specified character set. The default isutf-8. If the specifiedcharset is a known alias for a standardMIME charset name, use the standard charset instead.

Ifcte is set, encode the payload using the specified content transferencoding, and set theContent-Transfer-Encoding header tothat value. Forstr objects, if it is not set use heuristics todetermine the most compact encoding. Possible values forcte arequoted-printable,base64,7bit,8bit, andbinary.If the input cannot be encoded in the specified encoding (eg:7bit),raise aValueError. ForMessage, perRFC 2046, raise an error if acte ofquoted-printable orbase64 is requested forsubtyperfc822, and for anycteother than7bit forsubtypeexternal-body. Formessage/rfc822, use8bit ifcte is not specified. For allother values ofsubtype, use7bit.

Note

Acte ofbinary does not actually work correctly yet.TheMessage object as modified byset_content is correct, butBytesGenerator does not serialize itcorrectly.

Ifdisposition is set, use it as the value of theContent-Disposition header. If not specified, andfilename is specified, add the header with the valueattachment.If it is not specified andfilename is also not specified, do not addthe header. The only valid values fordisposition areattachmentandinline.

Iffilename is specified, use it as the value of thefilenameparameter of theContent-Disposition header. There is nodefault.

Ifcid is specified, add aContent-ID header withcid as its value.

Ifparams is specified, iterate itsitems method and use theresulting(key,value) pairs to set additional parameters on theContent-Type header.

Ifheaders is specified and is a list of strings of the formheadername:headervalue or a list ofheader objects(distinguished from strings by having aname attribute), add theheaders tomsg.