title: MIMEMultipart, MIMEText, MIMEBase, and payloads for sending email with file attachment in Python
body: <p>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 <sup>[1]</sup> and tested it to be working. </p>
  
  <pre><code>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()
  </code></pre>
  
  <ol>
  <li><p>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. </p>
  
  <pre><code> as.string()  
   |
   +------------MIMEMultipart  
                |                                                |---content-type  
                |                                   +---header---+---content disposition  
                +----.attach()-----+----MIMEBase----|  
                                   |                +---payload (to be encoded in Base64)
                                   +----MIMEText
  </code></pre></li>
  <li><p>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?</p></li>
  <li>I read that MIME has a tree-like structure<sup>[2]</sup> , does that mean MIMEMultipart is always at the top? </li>
  <li>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?</li>
  <li>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.  </li>
  <li>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()?</li>
  </ol>
  
  <p>[1]<a href="http://naelshiab.com/tutorial-send-email-python/" rel="noreferrer">http://naelshiab.com/tutorial-send-email-python/</a><br>
  [2]<a href="http://blog.magiksys.net/generate-and-send-mail-with-python-tutorial" rel="noreferrer">http://blog.magiksys.net/generate-and-send-mail-with-python-tutorial</a>  </p>