send html email with attachments in python

How to Send HTML Mail with Attachment Using Python

Python is a powerful language that allows you to do tons of things. It even allows you to send HTML emails. In this article, we will look at how to send HTML mail with attachment using python.


How to Send HTML Mail with Attachment Using Python

Here is how to send HTML mail with attachment using python.


1. Import smtplib

Python provides smtplib module that allows you to send emails. First we need to import it into our python script

import smtplib


2. Import Email package

Next, we need to import email package along with a few important classes – MIMEText, MIMEBase and MIMEMultipart.

import email
from email import encoders
from email.mime.base import MIMEBase
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart

MIMEBase class adds content header to emails. MIMEText class allows you to set text items of your email. MIMEMultipart allows you to add attachments.


3. Compose MIMEMultipart Object

To send an HTML email with attachment, we need to create a MIMEMultipart object with subject, to email address, from email address and attachment. Please change the values of each of the following variables as per your requirement.

msg = MIMEMultipart("alternative")
msg["Subject"] = "multipart test"
msg["From"] = sender_email
msg["To"] = receiver_email
filename = "document.pdf"

We will set sender_email and receiver_email below when we combine all the above parts into a single python script.


4. HTML Message

Next, we compose the HTML message.

html = """\
<html>
  <body>
    <p><b>Python Mail Test</b><br>
       This is HTML email with attachment.<br>
       Click on <a href="https://fedingo.com">Fedingo Resources</a> 
       for more python articles.
    </p>
  </body>
</html>
"""

We need to convert above string to MIMEText object.

part = MIMEText(html, "html")

We attach this MIMEText object to MIMEMultipart object we created above.

msg.attach(part)


5. Add Attachment

Next, we need to add attachment with the following line. We use set_payload() function for this purpose.

with open(filename, "rb") as attachment:
    part = MIMEBase("application", "octet-stream")
    part.set_payload(attachment.read())

We also encode the above parts to send email.

encoders.encode_base64(part)

We need to also add specific content header to the attachment.

part.add_header(
    "Content-Disposition",
    "attachment", filename= filename
)
msg.attach(part)


6. Create SMTP Connection

Finally, we create an SMTP connection to send email using smtplib.SMTP_SSL function which takes user login credential. In our example, we are sending email via GMail servers.

context = ssl.create_default_context()
with smtplib.SMTP_SSL("smtp.gmail.com", 465, context=context) as server:
    server.login(sender_email, password)
    server.sendmail(
        sender_email, receiver_email, msg.as_string()
    )


7. Complete Code

Here is the complete code to send HTML email. Create a blank python file.

$ sudo vi /home/email.py

Add the following code to it. Replace SENDER_EMAIL_ADDRESS, RECEIVER_EMAIL_ADDRESS and PASSWORD with sender email address, receiver email address and password respectively for their GMail account, since we are using their servers to send email. Also replace document.pdf with full file path to your attachment.

import smtplib, ssl, email
from email import encoders
from email.mime.base import MIMEBase
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart

sender_email = "SENDER_EMAIL_ADDRESS"
receiver_email = "RECEIVER_EMAIL_ADDRESS"
password = "PASSWORD"

#Create MIMEMultipart object
msg = MIMEMultipart("alternative")
msg["Subject"] = "multipart test"
msg["From"] = sender_email
msg["To"] = receiver_email
filename = "document.pdf"

#HTML Message Part
html = """\
<html>
  <body>
    <p><b>Python Mail Test</b>
    <br>
       This is HTML email with attachment.<br>
       Click on <a href="https://fedingo.com">Fedingo Resources</a> 
       for more python articles.
    </p>
  </body>
</html>
"""

part = MIMEText(html, "html")
msg.attach(part)

# Add Attachment
with open(filename, "rb") as attachment:
    part = MIMEBase("application", "octet-stream")
    part.set_payload(attachment.read())
   
encoders.encode_base64(part)

# Set mail headers
part.add_header(
    "Content-Disposition",
    "attachment", filename= filename
)
msg.attach(part)

# Create secure SMTP connection and send email
context = ssl.create_default_context()
with smtplib.SMTP_SSL("smtp.gmail.com", 465, context=context) as server:
    server.login(sender_email, password)
    server.sendmail(
        sender_email, receiver_email, msg.as_string()
    )

You can run the above script with a simple command

$ sudo python /home/mail.py

That’s it. We have created python script to send HTML email with attachment. The key is to create MIMEText and MIMEMultipart message objects, assemble them and send it via sendmail() function.

Also read:

Postfix Email Server Configuration Step by Step
How to Install GoAccess Log Analyzer in Ubuntu
How to Check Python Package Version
How to Install Go (Golang) in Ubuntu
How to Extract Substring from String in Bash

4 thoughts on “How to Send HTML Mail with Attachment Using Python

  1. Nice. I got it to work to attach an html report internally (without tls for now). There is something strange regarding using a list of e-mail adx’s for msg[“To”]. Says cannot encode list object, but if I give it an index slice it sends to them all, but only shows the index’s address on client. Works for me (built-in BCC 🙂

    Thanks!

Leave a Reply

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