Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MIMEMultipart, MIMEText, MIMEBase, and payloads for sending email with file attachment in Python

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() 
  1. 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 
  2. 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?

  3. I read that MIME has a tree-like structure[2] , does that mean MIMEMultipart is always at the top?
  4. In the first code block, MIMEMultipart encodes ['From'], ['To'], and ['Subject'], but in the Python documentation, MIMEText can also be used to encode ['From'], ['To'], and ['Subject']. How to do I decide one to use?
  5. What exactly is a "payload"? Is it some content to be transported? If so, what kind of content does this include (I noticed that body text and attachment are treated as payloads)? I thought this would be an easy question but I just could not find a satisfying, reliable, and simple answer.
  6. Is is true that although MIME can attach file formats much simpler than just some texts, at the end all the encoding, header information, and payloads are all turned into strings so that they can be passed into .sendmail()?

[1]http://naelshiab.com/tutorial-send-email-python/
[2]http://blog.magiksys.net/generate-and-send-mail-with-python-tutorial

like image 677
Ken Lin Avatar asked Aug 08 '16 09:08

Ken Lin


People also ask

How do I use MIMEMultipart in Python?

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.

What is MIMEBase Python?

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 .

What is the use of MIMEMultipart?

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.


1 Answers

E-mail messages

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).

Multipart messages

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.

like image 188
zvone Avatar answered Oct 11 '22 20:10

zvone