title: Send e-mail to Gmail with inline image using Python
body: <p>My objective is to use Python to send an e-mail to a Gmail user that has an inline image. It is not possible to host this image online and then link to it through a <code>href</code>, due to the sensitive nature of the images (data from my work). </p>
  
  <p>I've tried encoding the <code>base64</code> version into a <code>HTML</code> then sending th is <code>HTML</code>, but this is well known to not work. I then noticed that in Gmail you can drag and drop an image into the send box and it will show up inline in the receiving end. Given this I then tried to send an e-mail from Python with the image as an attachment. This is seen in the below code, but unfortunately the image doesn't show up inline. </p>
  
  <p>My question is then: <strong>How to send the image such that it shows up inline?</strong> </p>
  
  <pre><code>import smtplib
  from email.MIMEMultipart import MIMEMultipart
  from email.MIMEBase import MIMEBase
  from email.MIMEText import MIMEText
  from email import Encoders
  import os
  
  gmail_user = "user1@gmail.com"
  gmail_pwd = "pass"
  
  to = "user2@gmail.com"
  subject = "Report"
  text = "Picture report"
  attach = 'TESTING.png'
  
  msg = MIMEMultipart()
  
  msg['From'] = gmail_user
  msg['To'] = to
  msg['Subject'] = subject
  
  msg.attach(MIMEText(text))
  
  part = MIMEBase('application', 'octet-stream')
  part.set_payload(open(attach, 'rb').read())
  Encoders.encode_base64(part)
  part.add_header('Content-Disposition',
     'attachment; filename="%s"' % os.path.basename(attach))
  msg.attach(part)
  
  mailServer = smtplib.SMTP("smtp.gmail.com", 587)
  mailServer.ehlo()
  mailServer.starttls()
  mailServer.ehlo()
  mailServer.login(gmail_user, gmail_pwd)
  mailServer.sendmail(gmail_user, to, msg.as_string())
  # Should be mailServer.quit(), but that crashes...
  mailServer.close()
  </code></pre>
  
  <p>When I send the inline image to myself manually this is what the "original email" looks like:</p>
  
  <pre><code>  Content-Type: multipart/related; boundary=047d7bd761fe73e03304e7e02237
  
  --047d7bd761fe73e03304e7e02237
  Content-Type: multipart/alternative; boundary=047d7bd761fe73e03004e7e02236
  
  --047d7bd761fe73e03004e7e02236
  Content-Type: text/plain; charset=ISO-8859-1
  
  [image: Inline images 1]
  
  --047d7bd761fe73e03004e7e02236
  Content-Type: text/html; charset=ISO-8859-1
  
  &lt;div dir="ltr"&gt;&lt;img alt="Inline images 1" src="cid:ii_141810ee4ae92ac6" height="400" width="534"&gt;&lt;br&gt;&lt;/div&gt;
  
  --047d7bd761fe73e03004e7e02236--
  --047d7bd761fe73e03304e7e02237
  Content-Type: image/png; name="Testing.png"
  Content-Transfer-Encoding: base64
  Content-ID: &lt;ii_141810ee4ae92ac6&gt;
  X-Attachment-Id: ii_141810ee4ae92ac6
  </code></pre>
  
  <p>When I send it to myself through Python as an attachment it is very different:</p>
  
  <pre><code>Content-Type: multipart/mixed; boundary="===============6881579935569047077=="
  MIME-Version: 1.0
  (.... some stuff deleted here)
  --===============6881579935569047077==
  Content-Type: text/plain; charset="us-ascii"
  MIME-Version: 1.0
  Content-Transfer-Encoding: 7bit
  
  See attachment for report.
  --===============6881579935569047077==
  Content-Type: application/octet-stream
  MIME-Version: 1.0
  Content-Transfer-Encoding: base64
  Content-Disposition: attachment; filename="TESTING.png"
  </code></pre>