These days, almost all websites & apps need to email their users as well as administrators on a regular basis. For example, you may need to email users for account activation, password reset, newsletters, and even send error notifications to administrators. If you are running a Python-based website or app, then you can easily do this from within your site or app itself. In this tutorial, we will learn how to send HTML email with attachments using Python’s smtplib library
First, we will learn the individual steps involved in this process. Then we will put them together to get the complete code.
We need to import Smtplib, which provides many out-of-the-box functions to quickly configure and send emails using Python.
import smtplib
Next, we need to import a few necessary functions from the email package, that allow you to easily define and manage email messages. Among them, we will import MIMEBase, MIMEText, and MIMEMultipart classes.
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 allows you to set the content header of email messages. MIMEText allows you to set the email text and MIMEMultipart allows you to manage emails & its attachments.
We need to create a MIMEMultipart object which includes the email subject, sender, recipient, and file path of attachment.
msg = MIMEMultipart("alternative")
msg["Subject"] = "multipart test"
msg["From"] = sender_email
msg["To"] = receiver_email
filename = "document.pdf"
We will define sender_email & receiver_email values below when we put everything together.
Next, we create an HTML message. First, we define a string to contain the entire message.
html = """\
<html>
<body>
<p><b>Python Mail Test</b><br>
This is an HTML email with attachment.<br>
Click on <a href="https://techosha.com">Techosha Resources</a>
for more python articles.
</p>
</body>
</html>
"""
Then, we create MIMETextObject from this string.
part = MIMEText(html, "html")
Lastly, we attach the file to the MIMEMultipart object we created above.
msg.attach(part)
We will open the attachment file using open() function, set its content header as ‘application/octet-stream’ using MIMEBase() function and lastly, attach it to the message using set_payload() function.
with open(filename, "rb") as attachment:
part = MIMEBase("application", "octet-stream")
part.set_payload(attachment.read())
We will also encode our attachment to send email.
encoders.encode_base64(part)
We also need to add a ‘Content-Disposition’ header to the attachment before sending the email.
part.add_header(
"Content-Disposition",
"attachment", filename= filename
)
msg.attach(part)
If you do not want to add an attachment, you can skip this step.
We will create an SMTP connection, using smtplib.SMTP_SSL() function, to send emails. It will require login credentials of your email account. For our example, we will be using GMail servers. That is why we have mentioned ‘smtp.gmail.com’ below. Replace sender_email and password below with your GMail address and its password. It is the sendmail() function that does the actual sending of 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()
)
Now we will look at the complete code to send emails in Python. Create an empty Python file.
$ sudo vi /home/email.py
Add the following code to it. Replace SENDER_EMAIL_ADDRESS with your GMail address that you will use to send emails. Replace PASSWORD with its password. Replace RECEIVER_EMAIL_ADDRESS with the email address of email recipient.
Replace document.pdf with the full file path to your attachment file.
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()
)
Save and close the file. You can test the above Python script using the following command.
$ sudo python /home/mail.py
That’s it!
In this tutorial, we have learned how to create and send an HTML email with attachments in Python. To summarize, create MIMEText() and MIMEMultipart() objects, and assemble them to create the complete email message along with required headers. Use sendmail() function to send emails.