edit-icon download-icon

How can I send emails with attachments using SMTP?

Last Updated: Oct 11, 2017

Sending emails with attachments using SMTP requires you to build emails in MIME format.

MIME basic

  • MIME stands for Multipurpose Internet Mail Extensions. MIME extends the text-oriented basic Internet email system, allowing binary attachments in emails.

  • MIME emails are normal Internet text emails, which are composed of headers and formatted message contents that conform to RFC 2822/5322.

For more information about RFC addresses in the MIME protocol, click here.

MIME messages

A common text-based email is comprised of a header including From, To, Subject, and content. Generally, the content is either a single-part, such as text, image, audio, video, application, or multipart. The header and content are separated with a space, and the type of the body is described by the header Content-Type.

  • The meanings of headers are described in the following table:
Domain Name Meaning
Received Transfer path
Return-Path Reply address
Delivered-To Sending address
Reply-To Reply address
From The sender address
To The recipient address
Cc Carbon copy address
Bcc Blind carbon copy address
Date Date and time
Subject Subject
Message-ID Message ID
MIME-Version MIME version
Content-Type Content type
Content-Transfer-Encoding Content transfer encoding
  • Content type is in the form of: Content-Type: [type]/[subtype].

    The type is in the form of:

    • Text: for standard representation of a text message, which may consist of various character sets or formats.
    • Image: for transfer of static image data.
    • Audio: for transfer of audio or sound data.
    • Video: for transfer of dynamic image data, which may be a video data format that includes audio.
    • Application: for transfer of application data or binary data.
    • Message: for packing an email message.
    • Multipart: for connecting multiple content parts to form a message, the parts can be different types of data.

    The subtype form can be:

    • text/plain (plain text)
    • text/html (HTML document)
    • application/xhtml+xml (XHTML document)
    • image/gif (GIF image)
    • image/jpeg (JPEG image)
    • image/png (PNG image)
    • video/mpeg (MPEG video)
    • application/octet-stream (Any binary data)
    • message/rfc822 (RFC 822 form)
    • multipart/alternative (HTML form and plain text form of HTML mail, the same content is expressed in different forms.)
  • Content Transfer Encoding specifies the character encoding method used in the content area. Typical methods include 7bit, 8bit, binary, quoted-printable, and base64.

MIME email body

  • Common simple email types include text/plain (plain text) and text/html (hyper text).

  • Complex email content format uses multipart, which can include types of plain text/hyper text, embedded resource and attachment. A multipart email body contains multiple sections. Each section is comprised of a header and a body, which are also separated with a space.

The meanings of section headers are explained in the following table:

Domain Name Meaning
Content-Type Content type
Content-Transfer-Encoding Content transfer encoding
Content-Disposition Content disposition
Content-ID Content ID
Content-Location Content location (path)
Content-Base Content base

Three common multipart types are multipart/mixed, multipart/related, and multipart/alternative.

A sample graph of complex type hierarchy is shown as follows:

SMTP sample graph

Child sections within the content of multipart types are defined by the boundary parameter string specified in headers. All child sections start with —boundary, while parent sections end with —boundary—. Sections are separated with spaces.

Code example (python)

  1. # -*- coding:utf-8 -*-
  2. import urllib, urllib2
  3. import smtplib
  4. from email.mime.multipart import MIMEMultipart
  5. from email.mime.text import MIMEText
  6. from email.mime.application import MIMEApplication
  7. # Sender address, created in the console
  8. username = 'xxx@xxx.com'
  9. # Sender password, created in the console
  10. password = 'XXXXXXXX'
  11. # Recipient address list, supports up to 30 recipients
  12. rcptlist = ['to1@to.com', 'to2@to.com']
  13. receivers = ','.join(rcptlist)
  14. # Build multipart mail message
  15. msg = MIMEMultipart('mixed')
  16. msg['Subject'] = 'Test Email'
  17. msg['From'] = username
  18. msg['To'] = receivers
  19. # Build text/plain part of multipart/alternative
  20. alternative = MIMEMultipart('alternative')
  21. textplain = MIMEText ('plain text part')
  22. alternative.attach(textplain)
  23. # Build text/html part of multipart/alternative
  24. textplain = MIMEText ('hyper text part')
  25. alternative.attach(texthtml)
  26. # Add alternative into mixed
  27. msg.attach(alternative)
  28. # Attachment type
  29. # xlsx type attachment
  30. xlsxpart = MIMEApplication(open('1.xlsx', 'rb').read())
  31. xlsxpart.add_header('Content-Disposition', 'attachment', filename='1.xlsx')
  32. msg.attach(xlsxpart)
  33. # jpg type attachment
  34. jpgpart = MIMEApplication(open('2.jpg', 'rb').read())
  35. jpgpart.add_header('Content-Disposition', 'attachment', filename='2.jpg')
  36. msg.attach(jpgpart)
  37. # mp3 type attachment
  38. mp3part = MIMEApplication(open('3.mp3', 'rb').read())
  39. mp3part.add_header('Content-Disposition', 'attachment', filename='3.mp3')
  40. msg.attach(mp3part)
  41. # Send mail
  42. try:
  43. client = smtplib.SMTP()
  44. # SSL may be needed to create a client in python 2.7 or later
  45. #client = smtplib.SMTP_SSL()
  46. client.connect('smtpdm.aliyun.com')
  47. client.login(username, password)
  48. # Sender has to match the authorized address
  49. client.sendmail(username, rcptlist, msg.as_string())
  50. client.quit()
  51. Print 'Email delivered successfully!'
  52. except smtplib.SMTPRecipientsRefused:
  53. Print 'Email delivery failed, invalid recipient'
  54. except smtplib.SMTPAuthenticationError:
  55. Print 'Email delivery failed, authorization error'
  56. except smtplib.SMTPSenderRefused:
  57. Print 'Email delivery failed, invalid sender'
  58. except smtplib.SMTPException,e:
  59. Print 'Email delivery failed, ' e.message