Other combinations are possible, including some types that are not commonly seen in
practice, such as message/delivery status. Most messages have a main text part, though
it is not required, and may be nested in a multipart or other construct.
In all cases, an email message is a simple, linear string, but these message structures are
automatically detected when mail text is parsed and are created by your method calls
when new messages are composed. For instance, when creating messages, the message
attach method adds parts for multipart mails, and set_payload sets the entire payload
to a string for simple mails.
Message objects also have assorted properties (e.g., the filename of an attachment), and
they provide a convenient walk generator method, which returns the next Message in
the payload each time through in a for loop or other iteration context. Because the
walker yields the root Message object first (i.e., self), single-part messages don’t have
to be handled as a special case; a nonmultipart message is effectively a Message with a
single item in its payload—itself.
Ultimately, the Message object structure closely mirrors the way mails are formatted as
text. Special header lines in the mail’s text give its type (e.g., plain text or multipart),
as well as the separator used between the content of nested parts. Since the underlying
textual details are automated by the email package—both when parsing and when
composing—we won’t go into further formatting details here.
If you are interested in seeing how this translates to real emails, a great way to learn
mail structure is by inspecting the full raw text of messages displayed by email clients
you already use, as we’ll see with some we meet in this book. In fact, we’ve already seen
a few—see the raw text printed by our earlier POP email scripts for simple mail text
examples. For more on the Message object, and email in general, consult the email
package’s entry in Python’s library manual. We’re skipping details such as its available
encoders and MIME object classes here in the interest of space.
Beyond the email package, the Python library includes other tools for mail-related pro-
cessing. For instance, mimetypes maps a filename to and from a MIME type:
mimetypes.guess_type(filename)
Maps a filename to a MIME type. Name spam.txt maps to text/plan.
mimetypes.guess_extension(contype)
Maps a MIME type to a filename extension. Type text/html maps to .html.
We also used the mimetypes module earlier in this chapter to guess FTP transfer modes
from filenames (see Example 13-10), as well as in Chapter 6, where we used it to guess
a media player for a filename (see the examples there, including playfile.py, Exam-
ple 6-23). For email, these can come in handy when attaching files to a new message
(guess_type) and saving parsed attachments that do not provide a filename
(guess_extension). In fact, this module’s source code is a fairly complete reference to
MIME types. See the library manual for more on these tools.
email: Parsing and Composing Mail Content | 923