Handling multipart messages
Making a mail with attachments is a little more work, but not much: we just make a
root Message and attach nested Message objects created from the MIME type object that
corresponds to the type of data we’re attaching. The MIMEText class, for instance, is a
subclass of Message, which is tailored for text parts, and knows how to generate the
right types of header information when printed. MIMEImage and MIMEAudio similarly cus-
tomize Message for images and audio, and also know how to apply Base64 and other
MIME encodings to binary data. The root message is where we store the main headers
of the mail, and we attach parts here, instead of setting the entire payload—the payload
is a list now, not a string. MIMEMultipart is a Message that provides the extra header
protocol we need for the root:
>>> from email.mime.multipart import MIMEMultipart # Message subclasses
>>> from email.mime.text import MIMEText # with extra headers+logic
>>>
>>> top = MIMEMultipart() # root Message object
>>> top['from'] = 'Art <[email protected]>' # subtype default=mixed
>>> top['to'] = '[email protected]'
>>>
>>> sub1 = MIMEText('nice red uniforms...\n') # part Message attachments
>>> sub2 = MIMEText(open('data.txt').read())
>>> sub2.add_header('Content-Disposition', 'attachment', filename='data.txt')
>>> top.attach(sub1)
>>> top.attach(sub2)
When we ask for the text, a correctly formatted full mail text is returned, separators
and all, ready to be sent with smtplib—quite a trick, if you’ve ever tried this by hand:
>>> text = top.as_string() # or do: str(top) or print(top)
>>> print(text)
Content-Type: multipart/mixed; boundary="===============1574823535=="
MIME-Version: 1.0
from: Art <[email protected]>
to: [email protected]
--===============1574823535==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
nice red uniforms...
--===============1574823535==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="data.txt"
line1
line2
line3
--===============1574823535==--
email: Parsing and Composing Mail Content | 925