In this tutorial, we’ll show you how to send emails using Python.
We can easily automate the process of sending emails using Python. It’s handy when you are sending similar content over and over again. This automation could reduce human errors and free your time as well!
For example, if you need to update a list of contacts based on new daily data, you can use Python to create a new report and share it with them by sending emails. Or, if you have a Python program that takes a long time to run, you can ask Python to send you a reminder email when it’s done.
Following this tutorial, you’ll learn with examples:
- How to connect securely to your email’s SMTP server
- How to send Plain Text emails (with Subject, To, multiple recipients)
- How to send fancy HTML content emails (with attachments / images)
- And more!
We’ll show you how to use Python modules, including
If you want to send emails using Python, this tutorial will take you a long way!
Further learning: to generate reports using Python as Excel, HTML, PDF, check out our tutorial How to generate Reports with Python.
Let’s dive in!
To follow this tutorial, you need to know:
- Python basics, which you can learn with our FREE Python crash course: breaking into Data Science.
- HTML basics, which you can get a quick overview with HTML Introduction from W3 Schools.
Overview of Sending Emails using Python
Before we start, let’s look at an overview of the tools for sending emails using Python. This depends on the formats of emails you are sending.
Below are the two main types of emails and the Python libraries we’ll use in this tutorial. Don’t worry about all the new technical terms. You only need to know them at a high level.
- Plain Text
smtplib: this library defines a Simple Mail Transfer Protocol (SMTP) client session object that can be used to send mail to any Internet machine with an SMTP or ESMTP listener daemon.
What is SMTP? It is an internet standard communication protocol for electronic mail transmission.
In short, this module
smtplibenables Python to use such a protocol to send emails reliably and efficiently. So it’s a foundation library for sending emails using Python.
ssl: this module provides access to Transport Layer Security (TLS, also known as SSL) encryption and peer authentication facilities for network sockets.
In short, such a protocol makes communications over the computer network more secure.
- HTML (with attachments)
smtplib: to send HTML content emails, we still need
ssl: to send HTML content emails, we still need
This library makes managing email messages easier. We don’t have to know all the details behind the scenes when constructing complicated emails.
For example, we’ll use the
email.mimemodule to add HTML, and attach documents to the email. You can learn more about the Multipurpose Internet Mail Extensions (MIME) standard here.
By this point, you might be overwhelmed with all these new terms. But don’t worry, it will be more clear with examples.
One more thing before programming, we strongly suggest you create a new email account for testing purposes.
Set up your new Gmail account
For this tutorial, we created a new Gmail account. There are a couple of reasons for that. For example, we don’t want to expose our login information accidentally. Plus, the easiest way to allow access from Python to your Gmail account is to modify its security settings.
So it is good to have a new account for testing sending emails using Python, before applying it using your existing account. After the development stage, if you don’t want to lower the security setting of your existing Gmail account, you can search for a solution within the Gmail API section. But for now, let’s create a new Gmail account to keep things simple.
Here are the 2 steps procedure to set up your test Gmail account:
- Create a Gmail account
- Allow less secure apps: turn the switch ON to give Python access to your account
Please make sure you are changing the setting of the new account
If you don’t change this setting, when running the code later, you’ll get an error message like below:
SMTPAuthenticationError: (535, b'5.7.8 Username and Password not accepted. Learn more at\n5.7.8 https://support.google.com/mail/?p=BadCredentials - gsmtp')
Update: from May 30, 2022, the Less secure app access setting is no longer available for Gmail. But it might be available for other mail service providers.
To fix the problems with our tutorial on Gmail, please set up an App Password. The general steps are go to your Google Account -> Security -> turn on 2-Step Verification -> Security -> set up an App password. For more details, please visit here.
Then, you can use such a password to send emails in Python.
Note: Even though we use Gmail in our examples, you can follow similar procedures using other mail service providers.
If you are working in a large corporation, you might not have access to your SMTP server. In that case, you need to contact your IT team for support.
Now you should have your Gmail test account set up. We are ready to send emails using Python!
Send Plain Text Emails
We’ll start from the most basic email, with only plain text. Please don’t skip this section, since we need this basic knowledge in the later sections.
Send your first email with secure SMTP server connection
To send emails using Python, we need to connect securely to Gmail’s SMTP server, and send an email message through it.
Below are the details of this procedure. As mentioned in the overview, we use two Python modules:
- Create a secure default settings context
ssl.create_default_contextfunction to return a new SSLContext object with default security settings. This ensures our communication with the mailbox server is encrypted and secure.
- Connect to Gmail’s SMTP Outgoing Mail server with such context
You can find out about Gmail’s SMTP server (
smtp.gmail.com) and port (
465) here. If you are using a different email service, please look up and switch to their information.
- With such connection, we provide Gmail’s login information, and send a mail with the message as a Python string (plain text)
We use the
withstatement to connect, so that the connection automatically quits when the
Combining everything, below is the script to send a basic plain text email using Python. Please make sure to remove your password if you are sharing the code with others.
After running it successfully, you should get a mail in your receiver mailbox like below.
Congrats! You’ve sent your first email using Python.
If you click the small arrow to expand the details of the email, you can see that the security says Standard encryption (TLS). This confirms that we sent the message via a secure connection.
Add multiple recipients, Subject, To
As you might have noticed, the first email we’ve sent has no Subject. Also, the To field that usually shows the recipients’ email address is empty. We can add both by changing the email message. Plus, what if we want to send to multiple email addresses? Let’s add them as well.
Below is the code modified based on the previous example. The changes we’ve made are:
- Adding multiple recipients as a list
Python will send emails to all the email addresses listed. But Python will not automatically show these addresses in the To field.
- Adding Subject and To fields
We must have the Subject, To, and email message on separate lines. So please define the f-string as a multiline string with triple quotes (
Again, since Python does not automatically show the recipient emails in the To field, we must print them manually. The code
','.join(email_to)joins all the recipient emails stored in
email_to, using the string of comma (
,)as the separator. So it returns a string of
email@example.com,firstname.lastname@example.org, which will be printed as the To field in the email.
After running successfully, you should see an email like below, in all of the recipients’ mailboxes. And you should see the email with Subject as ‘A plain text email’, and To field as the recipient addresses.
Send HTML with attachment Emails
While plain text emails are good to share some information, we often want to add more to an email. For example, we might want to format the text with HTML so it’s easier for the recipients to read, or we might want to add more content to the email, such as a PDF document.
To include HTML content and attachments, we’ll use another Python module called
mime module to build these more fancy emails: the Multipurpose Internet Mail Extensions (MIME) standard emails.
The general procedure of creating a MIME email in our examples is:
- Create a
- Attach extra
MIMETextwith the email message,
MIMEApplicationwith attachments) to it
Let’s explore some examples below.
Send HTML content with the
HTML is the standard markup language for web pages. So there’s lots of content and formatting we could do with HTML. For example, we can make the text as headings, paragraphs, bold, or italic; we can also include other HTML elements such as data tables, images, etc. With HTML as the email message, we can display information-rich and well-structured content.
Below is an example of a basic HTML content email:
- Import modules
ssl, we also need some functions to create MIME subclasses from
email.mime. You can research different MIME classes here.
We also import the
pandaslibrary since we want to include the current date in the Subject, which is optional for sending emails.
- Define the HTML document
We only include a simple doc with an
pelement. But you can include other elements such as
If you are coming from How to generate Reports with Python tutorial, you can try to render the
htmlreport we’ve generated, except for the
imgelement needs some extra work to render, which will be shown soon.
- Set up the email addresses and password
Please note that you can also include multiple recipients as the plain text example.
- Create a
MIMEMultipartclass, and set up the From, To, Subject fields
Note that the
email.mimemodule makes it easier to set up the From, To, Subject fields. We don’t have to put each field on a separate line in the message string. Instead, we define them separately in a more clear way.
- Attach the
htmldoc defined earlier, as a
MIMETexthtml content type to the MIME message
Note that the default content type is ‘plain’, which won’t render the HTML document properly.
- Convert the
- Connect to the Gmail SMTP server and send Email, which is the same as before
By the end, you should receive an email like below. As you can see, the text is better formatted.
Now that you’ve learned how to send HTML emails using Python, you can modify the HTML document to include other elements such as
table as well!
Besides basic HTML content, we often want to include attachments to emails as well.
Based on the previous example, you can use the below code to include attachments to the email:
- Add a new MIME subclass for adding attachments
We can use the
MIMEApplicationclass to hold attachments.
- Define a function to attach files as
MIMEApplicationto the email
Since adding attachments is complicated, it’s better to write it as a function for reuse.
Please see the details in the comments.
- Attach more (documents) to email, by applying the function
We attach three documents: 1 PNG, 1 Excel, 1 PDF.
You can try to attach your files. Please make sure they are saved under the current working directory, if you don’t want to specify the path.
If you are coming from How to generate Reports with Python tutorial, you can now attach the chart, Excel, and PDF reports we’ve generated.
If you run the code, you should be able to receive an email like below, with the attachment files of your choice.
Add image to email body
Now, what if we want to include the chart in our email message? We need to include it as an
img element in the HTML content. But the email sent using Python doesn’t render the image without extra processing. So as one last example in this tutorial, we’ll render an image within the HTML email message.
Based on the previous example, here are the changes to include the image in HTML:
- Add an
srcas cid (Content ID) being myimageid
You can set the cid to other values if you’d like.
- Within the function to add attachments, add another input
This input has a default value of None:
– If it’s None, the function attaches the file as the previous example
– If this input is not None, i.e., when we set it to a specific value, it will add this
extra_header‘s value as header to the object, which can be used to set the cid for
- Apply function with
The Content-ID of myimageid matches with the
html. This renders the
chart.pngon the HTML content.
If you run the code now, you should get an email like below. The
chart.png or a chart of your choice is shown in the HTML content, rather than shown as an attachment.
This is great!
In this tutorial, you’ve learned how to send emails using Python, from the most basic plain text emails, to more fancy HTML emails with attachments.
Hope you can now automate the process of sending emails via Python!
Besides these foundation Python modules, there are also other libraries or products that help with sending emails using Python. For example, you can check out:
- yagmail: this module is in particular for Gmail, which simplifies the process a lot. But you have to make sure the package is updated based on the foundation modules and Gmail
- SendGrid: this service has a free tier. But since it’s a managed service, you do have to trust it.
- Mailgun: this service offers 3 months free trial. But since it’s a managed service, you do have to trust it.
Further learning: to learn about generating reports with Python, check out How to generate Reports with Python (3 Formats/4 Tools). So that you can generate reports, sending emails to share the reports, both automatically in Python!
We’d love to hear from you. Leave a comment for any questions you may have or anything else.