Python Send Html, Image And Attachment Email Example

In the last article Python SMTP Send Email Example we had learnt how the email transfer from the internet to the receiver’s email address, we have also learnt the basic source code to send email to SMTP server in Python program. In this article, we will tell you how to send more complex email content such as Html format content, image, and attachment through SMTP server.

1. Send HTML Content In Email.

What if we want to send HTML messages instead of plain text in email? The method is simple. When you construct the MIMEText object, pass in the HTML string, and change the second parameter from ‘plain’ to ‘html’, other codes are the same. When you send the email again, you can see Html content in the email body.

from email.MIMEText import MIMEText
msg = MIMEText('<html><body><h1>Hello World</h1>' +
'<p>this is hello world from <a href="">Python</a>...</p>' +
'</body></html>', 'html', 'utf-8')

2. Send Email With Attachments.

Mail with attachments can be regarded as mail with several parts: text and attachments. So, we can construct a MIMEMultipart object to represent the mail itself, then add a MIMEText object that contains email content to the mail body, and then add a MIMEBase object to the mail body to represent the attachment. Then, follow the normal send process to send the message ( MIMEMultipart object ) to an SMTP server, then the email with attachments will be received.

from email.MIMEMultipart import MIMEMultipart
from email.MIMEText import MIMEText

# get user input
# input sender email address and password:
from_addr = input('From: ')
password = input('Password: ')
# input receiver email address.
to_addr = input('To: ')
# input smtp server ip address:
smtp_server = input('SMTP server: ')

# email object that has multiple part:
msg = MIMEMultipart()
msg['From'] = from_addr
msg['To'] = to_addr
msg['Subject'] = Header('hello world from smtp server', 'utf-8').encode()

# attache a MIMEText object to save email content
msg_content = MIMEText('send with attachment...', 'plain', 'utf-8')

# to add an attachment is just add a MIMEBase object to read a picture locally.
with open('/Users/jerry/img1.png', 'rb') as f:
    # set attachment mime and file name, the image type is png
    mime = MIMEBase('image', 'png', filename='img1.png')
    # add required header data:
    mime.add_header('Content-Disposition', 'attachment', filename='img1.png')
    mime.add_header('X-Attachment-Id', '0')
    mime.add_header('Content-ID', '<0>')
    # read attachment file content into the MIMEBase object
    # encode with base64
    # add MIMEBase object to MIMEMultipart object

server = smtplib.SMTP(smtp_server, 25)
server.login(from_addr, password)
server.sendmail(from_addr, [to_addr], msg.as_string())

3. Send Email With Image.

What if you want to embed an image in the body of the mail? Is it okay to link the image address directly in HTML mail? The answer is that most email service providers automatically block pictures with external links because they don’t know whether these links point to malicious websites or not.

To embed the image into the body of the mail, we just need to add the image as an attachment in the way of sending attachments. Then, in HTML, we can embed the attachment as an image by referring an image to src= “cid:0”. If you have multiple pictures, numbering them in turn and then referring each image to a different cid: x(image number).

from email.MIMEText import MIMEText

msg.attach(MIMEText('<html><body><h1>Hello</h1>' +
'<p><img src="cid:0"></p>' +
'</body></html>', 'html', 'utf-8'))

4. Support Both HTML And Plain Text Formats.

If we send HTML mail, the recipient can browse the content of the mail normally through the browser or software such as Outlook, but what if the device used by the recipient is too old to view HTML mail? The solution is to attach a plain text while sending HTML. If the recipient can’t view the mail in HTML format, it can automatically degrade to view the plain text mail.

Using MIMEMultipart, you can combine HTML and Plain Text content in one email. Note that subtype should be alternative.

from email.MIMEMultipart import MIMEMultipart
from email.MIMEText import MIMEText

# Pass 'alternative' to the MIMEMultipart constructor.
msg = MIMEMultipart('alternative')
msg['From'] = input('From: ')
msg['To'] = input('To: ')
msg['Subject'] = input('Subject: ')

msg.attach(MIMEText('hello this is a plain text version.', 'plain', 'utf-8'))
msg.attach(MIMEText('<html><body><h1>Hello this is html version</h1></body></html>', 'html', 'utf-8'))

5. Encrypted SMTP.

When connecting to SMTP server using standard port 25, it uses plaintext transmission, and the whole process of sending mail may be eavesdropped. To send email safer, you can encrypt SMTP sessions, which is essential to create an SSL secure connection before sending mail using the SMTP protocol.

# define smtp server domain and port number.
smtp_server = ''
smtp_port = 989
# create smtp server object.
server = smtplib.SMTP(smtp_server, smtp_port)
# use ssl protocol to secure the smtp session connection, all the data transferred by the session will be secured. 
# send the email as normal.

6. Send Both Html, Image & Alternative Text Example.

This example will use Python to send an email with HTML content, if the email client is too old to support HTML content, it also sends an alternate text content with it. The below source code embed an image in the email Html content also.

# Import smtplib library to send email in python.
import smtplib
# Import MIMEText, MIMEImage and MIMEMultipart module.
from email.MIMEImage import MIMEImage
from email.MIMEMultipart import MIMEMultipart
from email.MIMEText import MIMEText

# Define the source and target email address.
strFrom = '[email protected]'
strTo = '[email protected]'

# Create an instance of MIMEMultipart object, pass 'related' as the constructor parameter.
msgRoot = MIMEMultipart('related')
# Set the email subject.
msgRoot['Subject'] = 'This email contain both Html, text and one image.'
# Set the email from email address.
msgRoot['From'] = strFrom
# Set the email to email address.
msgRoot['To'] = strTo

# Set the multipart email preamble attribute value. Please refer to learn more.
msgRoot.preamble = '====================================================='

# Create a 'alternative' MIMEMultipart object. We will use this object to save plain text format content.
msgAlternative = MIMEMultipart('alternative')
# Attach the bove object to the root email message.

# Create a MIMEText object, this object contains the plain text content.
msgText = MIMEText('This object contains the plain text content of this email.')
# Attach the MIMEText object to the msgAlternative object.

# Create a MIMEText object to contains the email Html content. There is also an image in the Html content. The image cid is image1.
msgText = MIMEText('<b>This is the <i>HTML</i> content of this email</b> it contains an image.<br><img src="cid:image1"><br>', 'html')
# Attach the above html content MIMEText object to the msgAlternative object.

# Open a file object to read the image file, the image file is located in the file path it provide.
fp = open('/usr/var/test.jpg', 'rb')
# Create a MIMEImage object with the above file object.
msgImage = MIMEImage(
# Do not forget close the file object after using it.

# Add 'Content-ID' header value to the above MIMEImage object to make it refer to the image source (src="cid:image1") in the Html content.
msgImage.add_header('Content-ID', '<image1>')
# Attach the MIMEImage object to the email body.

# Create an smtplib.SMTP object to send the email.
smtp = smtplib.SMTP()
# Connect to the SMTP server.
# Login to the SMTP server with username and password.
smtp.login('hello', 'haha')
# Send email with the smtp object sendmail method.
smtp.sendmail(strFrom, strTo, msgRoot.as_string())
# Quit the SMTP server after sending the email.

1 thought on “Python Send Html, Image And Attachment Email Example”

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.