19.1.6. email.contentmanager
: Managing MIME Content
Note
The contentmanager module has been included in the standard library on a provisional basis. Backwards incompatible changes (up to and including removal of the module) may occur if deemed necessary by the core developers.
New in version 3.4: as a provisional module.
The message
module provides a class that can represent an
arbitrary email message. That basic message model has a useful and flexible
API, but it provides only a lower-level API for interacting with the generic
parts of a message (the headers, generic header parameters, and the payload,
which may be a list of sub-parts). This module provides classes and tools
that provide an enhanced and extensible API for dealing with various specific
types of content, including the ability to retrieve the content of the message
as a specialized object type rather than as a simple bytes object. The module
automatically takes care of the RFC-specified MIME details (required headers
and parameters, etc.) for the certain common content types content properties,
and support for additional types can be added by an application using the
extension mechanisms.
This module defines the eponymous “Content Manager” classes. The base
ContentManager
class defines an API for registering content
management functions which extract data from Message
objects or insert data
and headers into Message
objects, thus providing a way of converting
between Message
objects containing data and other representations of that
data (Python data types, specialized Python objects, external files, etc). The
module also defines one concrete content manager: raw_data_manager
converts between MIME content types and str
or bytes
data. It also
provides a convenient API for managing the MIME parameters when inserting
content into Message
s. It also handles inserting and extracting
Message
objects when dealing with the message/rfc822
content type.
Another part of the enhanced interface is subclasses of
Message
that provide new convenience API functions,
including convenience methods for calling the Content Managers derived from
this module.
Note
Although EmailMessage
and MIMEPart
are currently
documented in this module because of the provisional nature of the code, the
implementation lives in the email.message
module.
-
class
email.message.
EmailMessage
(policy=default) If policy is specified (it must be an instance of a
policy
class) use the rules it specifies to udpate and serialize the representation of the message. If policy is not set, use thedefault
policy, which follows the rules of the email RFCs except for line endings (instead of the RFC mandated\r\n
, it uses the Python standard\n
line endings). For more information see thepolicy
documentation.This class is a subclass of
Message
. It adds the following methods:-
is_attachment
() Return
True
if there is a Content-Disposition header and its (case insensitive) value isattachment
,False
otherwise.Changed in version 3.4.2: is_attachment is now a method instead of a property, for consistency with
is_multipart()
.
-
get_body
(preferencelist=('related', 'html', 'plain')) Return the MIME part that is the best candidate to be the “body” of the message.
preferencelist must be a sequence of strings from the set
related
,html
, andplain
, and indicates the order of preference for the content type of the part returned.Start looking for candidate matches with the object on which the
get_body
method is called.If
related
is not included in preferencelist, consider the root part (or subpart of the root part) of any related encountered as a candidate if the (sub-)part matches a preference.When encountering a
multipart/related
, check thestart
parameter and if a part with a matching Content-ID is found, consider only it when looking for candidate matches. Otherwise consider only the first (default root) part of themultipart/related
.If a part has a Content-Disposition header, only consider the part a candidate match if the value of the header is
inline
.If none of the candidates matches any of the preferences in preferneclist, return
None
.Notes: (1) For most applications the only preferencelist combinations that really make sense are
('plain',)
,('html', 'plain')
, and the default,('related', 'html', 'plain')
. (2) Because matching starts with the object on whichget_body
is called, callingget_body
on amultipart/related
will return the object itself unless preferencelist has a non-default value. (3) Messages (or message parts) that do not specify a Content-Type or whose Content-Type header is invalid will be treated as if they are of typetext/plain
, which may occasionally causeget_body
to return unexpected results.
-
iter_attachments
() Return an iterator over all of the parts of the message that are not candidate “body” parts. That is, skip the first occurrence of each of
text/plain
,text/html
,multipart/related
, ormultipart/alternative
(unless they are explicitly marked as attachments via Content-Disposition: attachment), and return all remaining parts. When applied directly to amultipart/related
, return an iterator over the all the related parts except the root part (ie: the part pointed to by thestart
parameter, or the first part if there is nostart
parameter or thestart
parameter doesn’t match the Content-ID of any of the parts). When applied directly to amultipart/alternative
or a non-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 the
get_content
method of the content_manager, passing self as the message object, and passing along any other arguments or keywords as additional arguments. If content_manager is not specified, use thecontent_manager
specified by the currentpolicy
.
-
set_content
(*args, content_manager=None, **kw) Call the
set_content
method of the content_manager, passing self as the message object, and passing along any other arguments or keywords as additional arguments. If content_manager is not specified, use thecontent_manager
specified by the currentpolicy
.
Convert a non-
multipart
message into amultipart/related
message, moving any existing Content- headers and payload into a (new) first part of themultipart
. If boundary is specified, use it as the boundary string in the multipart, otherwise leave the boundary to be automatically created when it is needed (for example, when the message is serialized).
-
make_alternative
(boundary=None) Convert a non-
multipart
or amultipart/related
into amultipart/alternative
, moving any existing Content- headers and payload into a (new) first part of themultipart
. If boundary is specified, use it as the boundary string in the multipart, otherwise leave the boundary to be automatically created when it is needed (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 existing Content- headers and payload into a (new) first part of themultipart
. If boundary is specified, use it as the boundary string in the multipart, otherwise leave the boundary to be automatically created when it is needed (for example, when the message is serialized).
If the message is a
multipart/related
, create a new message object, pass all of the arguments to itsset_content()
method, andattach()
it to themultipart
. If the message is a non-multipart
, callmake_related()
and then proceed as above. If the message is any other type ofmultipart
, raise aTypeError
. If content_manager is not specified, use thecontent_manager
specified by the currentpolicy
. If the added part has no Content-Disposition header, add one with the valueinline
.
-
add_alternative
(*args, content_manager=None, **kw) If the message is a
multipart/alternative
, create a new message object, pass all of the arguments to itsset_content()
method, andattach()
it to themultipart
. If the message is a non-multipart
ormultipart/related
, callmake_alternative()
and then proceed as above. If the message is any other type ofmultipart
, raise aTypeError
. If content_manager is not specified, use thecontent_manager
specified by the currentpolicy
.
-
add_attachment
(*args, content_manager=None, **kw) If the message is a
multipart/mixed
, create a new message object, pass all of the arguments to itsset_content()
method, andattach()
it to themultipart
. If the message is a non-multipart
,multipart/related
, ormultipart/alternative
, callmake_mixed()
and then proceed as above. If content_manager is not specified, use thecontent_manager
specified by the currentpolicy
. If the added part has no Content-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 appropriate options to thecontent_manager
.
-
clear
() Remove the payload and all of the headers.
-
clear_content
() Remove the payload and all of the
Content-
headers, leaving all other headers intact and in their original order.
-
-
class
email.message.
MIMEPart
(policy=default) This class represents a subpart of a MIME message. It is identical to
EmailMessage
, except that no MIME-Version headers are added whenset_content()
is called, since sub-parts do not need their own MIME-Version headers.
-
class
email.contentmanager.
ContentManager
Base class for content managers. Provides the standard registry mechanisms to register converters between MIME content and other representations, as well as the
get_content
andset_content
dispatch methods.-
get_content
(msg, *args, **kw) Look up a handler function based on the
mimetype
of msg (see next paragraph), call it, passing through all arguments, and return the result of the call. The expectation is that the handler will extract the payload from msg and return an object that encodes information about the 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 the
maintype
- the empty string
If none of these keys produce a handler, raise a
KeyError
for the full MIME type.- the string representing the full MIME type (
-
set_content
(msg, obj, *args, **kw) If the
maintype
ismultipart
, raise aTypeError
; otherwise look up a handler function based on the type of obj (see next paragraph), callclear_content()
on the msg, and call the handler function, passing through all arguments. The expectation is that the handler will transform and store obj into msg, possibly making other changes to msg as well, such as adding various MIME headers to encode information needed to interpret the stored data.To find the handler, obtain the type of obj (
typ = type(obj)
), and look for the following keys in the registry, stopping with the first one found:- 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 of the types in the MRO (
typ.__mro__
). Finally, if no other key yields a handler, check for a handler for the keyNone
. If there is no handler forNone
, raise aKeyError
for the fully qualified name of the type.Also add a MIME-Version header if one is not present (see also
MIMEPart
).- the type itself (
-
add_get_handler
(key, handler) Record the function handler as the handler for key. For the possible values of key, see
get_content()
.
-
add_set_handler
(typekey, handler) Record handler as the function to call when an object of a type matching typekey is passed to
set_content()
. For the possible values of typekey, 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 the
content_manager
provided by
EmailPolicy
and its derivatives.
-
email.contentmanager.
raw_data_manager
This content manager provides only a minimum interface beyond that provided by
Message
itself: it deals only with text, raw byte strings, andMessage
objects. Nevertheless, it provides significant advantages compared to the base API:get_content
on a text part will return a unicode string without the application needing to manually decode it,set_content
provides a rich set of options for controlling the headers added to a part and controlling the content transfer encoding, and it enables the use of the variousadd_
methods, thereby simplifying the creation of multipart messages.-
email.contentmanager.
get_content
(msg, errors='replace') Return the payload of the part as either a string (for
text
parts), aEmailMessage
object (formessage/rfc822
parts), or abytes
object (for all other non-multipart types). Raise aKeyError
if called on amultipart
. If the part is atext
part and errors is specified, use it as the error handler when decoding 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 to msg:
Add a Content-Type header with a
maintype/subtype
value.- For
str
, set the MIMEmaintype
totext
, and set the subtype to subtype if it is specified, orplain
if it is not. - For
bytes
, use the specified maintype and subtype, or raise aTypeError
if they are not specified. - For
Message
objects, set the maintype tomessage
, and set the subtype to subtype if it is specified orrfc822
if it is not. If subtype ispartial
, raise an error (bytes
objects must be used to constructmessage/partial
parts). - For <’list’>, which should be a list of
Message
objects, set themaintype
tomultipart
, and thesubtype
to subtype if it is specified, andmixed
if it is not. If the message parts in the <’list’> have MIME-Version headers, remove them.
If charset is provided (which is valid only for
str
), encode the string to bytes using the specified character set. The default isutf-8
. If the specified charset is a known alias for a standard MIME charset name, use the standard charset instead.If cte is set, encode the payload using the specified content transfer encoding, and set the Content-Transfer-Endcoding header to that value. For
str
objects, if it is not set use heuristics to determine the most compact encoding. Possible values for cte arequoted-printable
,base64
,7bit
,8bit
, andbinary
. If the input cannot be encoded in the specified encoding (eg:7bit
), raise aValueError
. ForMessage
, per RFC 2046, raise an error if a cte ofquoted-printable
orbase64
is requested for subtyperfc822
, and for any cte other than7bit
for subtypeexternal-body
. Formessage/rfc822
, use8bit
if cte is not specified. For all other values of subtype, use7bit
.Note
A cte of
binary
does not actually work correctly yet. TheMessage
object as modified byset_content
is correct, butBytesGenerator
does not serialize it correctly.If disposition is set, use it as the value of the Content-Disposition header. If not specified, and filename is specified, add the header with the value
attachment
. If it is not specified and filename is also not specified, do not add the header. The only valid values for disposition areattachment
andinline
.If filename is specified, use it as the value of the
filename
parameter of the Content-Disposition header. There is no default.If cid is specified, add a Content-ID header with cid as its value.
If params is specified, iterate its
items
method and use the resulting(key, value)
pairs to set additional parameters on the Content-Type header.If headers is specified and is a list of strings of the form
headername: headervalue
or a list ofheader
objects (distinguised from strings by having aname
attribute), add the headers to msg.- For
-