19.1.3. email.generator
: Generating MIME documents¶
Source code: Lib/email/generator.py
One of the most common tasks is to generate the flat (serialized) version of
the email message represented by a message object structure. You will need to
do this if you want to send your message via smtplib.SMTP.sendmail()
or
the nntplib
module, or print the message on the console. Taking a
message object structure and producing a serialized representation is the job
of the generator classes.
As with the email.parser
module, you aren’t limited to the functionality
of the bundled generator; you could write one from scratch yourself. However
the bundled generator knows how to generate most email in a standards-compliant
way, should handle MIME and non-MIME email messages just fine, and is designed
so that the bytes-oriented parsing and generation operations are inverses,
assuming the same non-transforming policy
is used for both. That
is, parsing the serialized byte stream via the
BytesParser
class and then regenerating the serialized
byte stream using BytesGenerator
should produce output identical to
the input 1. (On the other hand, using the generator on an
EmailMessage
constructed by program may result in
changes to the EmailMessage
object as defaults are
filled in.)
The Generator
class can be used to flatten a message into a text (as
opposed to binary) serialized representation, but since Unicode cannot
represent binary data directly, the message is of necessity transformed into
something that contains only ASCII characters, using the standard email RFC
Content Transfer Encoding techniques for encoding email messages for transport
over channels that are not “8 bit clean”.
-
class
email.generator.
BytesGenerator
(outfp, mangle_from_=None, maxheaderlen=None, *, policy=None)¶ Return a
BytesGenerator
object that will write any message provided to theflatten()
method, or any surrogateescape encoded text provided to thewrite()
method, to the file-like object outfp. outfp must support awrite
method that accepts binary data.If optional mangle_from_ is
True
, put a>
character in front of any line in the body that starts with the exact string"From "
, that isFrom
followed by a space at the beginning of a line. mangle_from_ defaults to the value of themangle_from_
setting of the policy (which isTrue
for thecompat32
policy andFalse
for all others). mangle_from_ is intended for use when messages are stored in unix mbox format (seemailbox
and WHY THE CONTENT-LENGTH FORMAT IS BAD).If maxheaderlen is not
None
, refold any header lines that are longer than maxheaderlen, or if0
, do not rewrap any headers. If manheaderlen isNone
(the default), wrap headers and other message lines according to the policy settings.If policy is specified, use that policy to control message generation. If policy is
None
(the default), use the policy associated with theMessage
orEmailMessage
object passed toflatten
to control the message generation. Seeemail.policy
for details on what policy controls.New in version 3.2.
Changed in version 3.3: Added the policy keyword.
Changed in version 3.6: The default behavior of the mangle_from_ and maxheaderlen parameters is to follow the policy.
-
flatten
(msg, unixfrom=False, linesep=None)¶ Print the textual representation of the message object structure rooted at msg to the output file specified when the
BytesGenerator
instance was created.If the
policy
optioncte_type
is8bit
(the default), copy any headers in the original parsed message that have not been modified to the output with any bytes with the high bit set reproduced as in the original, and preserve the non-ASCII Content-Transfer-Encoding of any body parts that have them. Ifcte_type
is7bit
, convert the bytes with the high bit set as needed using an ASCII-compatible Content-Transfer-Encoding. That is, transform parts with non-ASCII Content-Transfer-Encoding (Content-Transfer-Encoding: 8bit) to an ASCII compatible Content-Transfer-Encoding, and encode RFC-invalid non-ASCII bytes in headers using the MIMEunknown-8bit
character set, thus rendering them RFC-compliant.If unixfrom is
True
, print the envelope header delimiter used by the Unix mailbox format (seemailbox
) before the first of the RFC 5322 headers of the root message object. If the root object has no envelope header, craft a standard one. The default isFalse
. Note that for subparts, no envelope header is ever printed.If linesep is not
None
, use it as the separator character between all the lines of the flattened message. If linesep isNone
(the default), use the value specified in the policy.
-
clone
(fp)¶ Return an independent clone of this
BytesGenerator
instance with the exact same option settings, and fp as the new outfp.
-
write
(s)¶ Encode s using the
ASCII
codec and thesurrogateescape
error handler, and pass it to the write method of the outfp passed to theBytesGenerator
’s constructor.
-
As a convenience, EmailMessage
provides the methods
as_bytes()
and bytes(aMessage)
(a.k.a.
__bytes__()
), which simplify the generation of
a serialized binary representation of a message object. For more detail, see
email.message
.
Because strings cannot represent binary data, the Generator
class must
convert any binary data in any message it flattens to an ASCII compatible
format, by converting them to an ASCII compatible
Content-Transfer_Encoding. Using the terminology of the email
RFCs, you can think of this as Generator
serializing to an I/O stream
that is not “8 bit clean”. In other words, most applications will want
to be using BytesGenerator
, and not Generator
.
-
class
email.generator.
Generator
(outfp, mangle_from_=None, maxheaderlen=None, *, policy=None)¶ Return a
Generator
object that will write any message provided to theflatten()
method, or any text provided to thewrite()
method, to the file-like object outfp. outfp must support awrite
method that accepts string data.If optional mangle_from_ is
True
, put a>
character in front of any line in the body that starts with the exact string"From "
, that isFrom
followed by a space at the beginning of a line. mangle_from_ defaults to the value of themangle_from_
setting of the policy (which isTrue
for thecompat32
policy andFalse
for all others). mangle_from_ is intended for use when messages are stored in unix mbox format (seemailbox
and WHY THE CONTENT-LENGTH FORMAT IS BAD).If maxheaderlen is not
None
, refold any header lines that are longer than maxheaderlen, or if0
, do not rewrap any headers. If manheaderlen isNone
(the default), wrap headers and other message lines according to the policy settings.If policy is specified, use that policy to control message generation. If policy is
None
(the default), use the policy associated with theMessage
orEmailMessage
object passed toflatten
to control the message generation. Seeemail.policy
for details on what policy controls.Changed in version 3.3: Added the policy keyword.
Changed in version 3.6: The default behavior of the mangle_from_ and maxheaderlen parameters is to follow the policy.
-
flatten
(msg, unixfrom=False, linesep=None)¶ Print the textual representation of the message object structure rooted at msg to the output file specified when the
Generator
instance was created.If the
policy
optioncte_type
is8bit
, generate the message as if the option were set to7bit
. (This is required because strings cannot represent non-ASCII bytes.) Convert any bytes with the high bit set as needed using an ASCII-compatible Content-Transfer-Encoding. That is, transform parts with non-ASCII Cotnent-Transfer-Encoding (Content-Transfer-Encoding: 8bit) to an ASCII compatible Content-Transfer-Encoding, and encode RFC-invalid non-ASCII bytes in headers using the MIMEunknown-8bit
character set, thus rendering them RFC-compliant.If unixfrom is
True
, print the envelope header delimiter used by the Unix mailbox format (seemailbox
) before the first of the RFC 5322 headers of the root message object. If the root object has no envelope header, craft a standard one. The default isFalse
. Note that for subparts, no envelope header is ever printed.If linesep is not
None
, use it as the separator character between all the lines of the flattened message. If linesep isNone
(the default), use the value specified in the policy.Changed in version 3.2: Added support for re-encoding
8bit
message bodies, and the linesep argument.
-
As a convenience, EmailMessage
provides the methods
as_string()
and str(aMessage)
(a.k.a.
__str__()
), which simplify the generation of
a formatted string representation of a message object. For more detail, see
email.message
.
The email.generator
module also provides a derived class,
DecodedGenerator
, which is like the Generator
base class,
except that non-text parts are not serialized, but are instead
represented in the output stream by a string derived from a template filled
in with information about the part.
-
class
email.generator.
DecodedGenerator
(outfp, mangle_from_=None, maxheaderlen=None, fmt=None, *, policy=None)¶ Act like
Generator
, except that for any subpart of the message passed toGenerator.flatten()
, if the subpart is of main type text, print the decoded payload of the subpart, and if the main type is not text, instead of printing it fill in the string fmt using information from the part and print the resulting filled-in string.To fill in fmt, execute
fmt % part_info
, wherepart_info
is a dictionary composed of the following keys and values:type
– Full MIME type of the non-text partmaintype
– Main MIME type of the non-text partsubtype
– Sub-MIME type of the non-text partfilename
– Filename of the non-text partdescription
– Description associated with the non-text partencoding
– Content transfer encoding of the non-text part
If fmt is
None
, use the following default fmt:“[Non-text (%(type)s) part of message omitted, filename %(filename)s]”
Optional _mangle_from_ and maxheaderlen are as with the
Generator
base class.
Footnotes
- 1
This statement assumes that you use the appropriate setting for
unixfrom
, and that there are nopolicy
settings calling for automatic adjustments (for example,refold_source
must benone
, which is not the default). It is also not 100% true, since if the message does not conform to the RFC standards occasionally information about the exact original text is lost during parsing error recovery. It is a goal to fix these latter edge cases when possible.