Without much prior knowledge of MIME, I tried to learned how to write a Python script to send an email with a file attachment. After cross-referencing Python documentation, Stack Overflow questions, and general web searching, I settled with the following code [1] and tested it to be working.
import smtplib from email.MIMEMultipart import MIMEMultipart from email.MIMEText import MIMEText from email.MIMEBase import MIMEBase from email import encoders fromaddr = "YOUR EMAIL" toaddr = "EMAIL ADDRESS YOU SEND TO" msg = MIMEMultipart() msg['From'] = fromaddr msg['To'] = toaddr msg['Subject'] = "SUBJECT OF THE EMAIL" body = "TEXT YOU WANT TO SEND" msg.attach(MIMEText(body, 'plain')) filename = "NAME OF THE FILE WITH ITS EXTENSION" attachment = open("PATH OF THE FILE", "rb") part = MIMEBase('application', 'octet-stream') part.set_payload((attachment).read()) encoders.encode_base64(part) part.add_header('Content-Disposition', "attachment; filename= %s" % filename) msg.attach(part) server = smtplib.SMTP('smtp.gmail.com', 587) server.starttls() server.login(fromaddr, "YOUR PASSWORD") text = msg.as_string() server.sendmail(fromaddr, toaddr, text) server.quit()
I have a rough idea of how this script works now, and worked out the following workflow. Please let me know how accurate my flowchart(?) is.
as.string() | +------------MIMEMultipart | |---content-type | +---header---+---content disposition +----.attach()-----+----MIMEBase----| | +---payload (to be encoded in Base64) +----MIMEText
How do I know when to use MIMEMultipart, MIMEText and MIMEBase? This seems like a complicated question, so maybe just offer some general rules-of-thumb to me?
[1]http://naelshiab.com/tutorial-send-email-python/
[2]http://blog.magiksys.net/generate-and-send-mail-with-python-tutorial
MIMEMultipart is used when we have attachments or want to provide alternative versions of the same content (e.g. a plain text/HTML version). We have a simple text file. The example sends an email with a text file attachment to Mailtrap. We read the contents of the text file.
MIMEBase is provided primarily as a convenient base class for more specific MIME-aware subclasses. _maintype is the Content-Type major type (e.g. text or image), and _subtype is the Content-Type minor type (e.g. plain or gif). _params is a parameter key/value dictionary and is passed directly to Message. add_header .
An application can directly construct a MIME multipart object of any subtype by using the MimeMultipart(String subtype) constructor. For example, to create a "multipart/alternative" object, use new MimeMultipart("alternative") . The mail. mime.
An e-mail message consists of headers (e.g. "From", "To", "Subject" etc.) and body (see RFC 822, section 3.1).
The body of the message is, by default, treated as plain ASCII text. MIME (RFC 2045, RFC 2046, RFC 2047, RFC 2048, RFC 2049) defines extensions which allow specifying different types of email content.
One very useful thing you are able to with MIME is specify a Content-Type (e.g. text/html
or application/octet-stream
).
Another useful thing is that you can create a message with multiple parts (for instance, if you want to have both HTML and an image within the HTML). This is done by specifying a multipart
Content-Type (RFC 2046, section 5.1).
If a message has a multipart
Content-Type, that means it consists of multiple messages and each of them defines its own Content-Type (which can again be multipart or something else). Multipart messages are in Python represented by MIMEMultipart
class.
So, to answer question 3: When MIMEMultipart
is used, then yes, it is a tree-like structure, but if only MIMEText
is used, then it is not a tree.
Question 4 asks on which class to set the headers ("To", "From" etc.) - that is done the the Message
class, but all MIME
classes inherit from Message
, so it can be done on any of them, but those headers only make sense on the root part of a multipart message.
In other words, if a message consists of only one MIME part, specify headers on that part. If it consists of mutiple parts, then the root is a MIMEMultipart
- specify the headers on that part.
Question 2 asks "when to use MIMEMultipart, MIMEText and MIMEBase".
MIMEBase
is just a base class. As the specification says: "Ordinarily you won’t create instances specifically of MIMEBase
" MIMEText
is for text (e.g. text/plain
or text/html
), if the whole message is in text format, or if a part of it is.MIMEMultipart
is for saying "I have more than one part", and then listing the parts - you do that if you have attachments, you also do it to provide alternative versions of the same content (e.g. a plain text version plus an HTML version)Question 5 "What exactly is a "payload"?" - that is just a fancy word for the content of the message (or message part)
Question 6 There is a limitation to using only 7 bits in SMTP. See this answer for more details.
I did not completely understand Question 1, but it seems that the chart is more or less correct. BTW, I would not use MIMEBase
here, because there is MIMEApplication
which seems more appropriate for the intended purpose.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With