How to Send Emails using Python: Tutorial with examples
 Plain text, HTML with attachments

Lianne & Justin

Lianne & Justin

send email using python
Source: Unsplash

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 smtplib and email, with plenty of examples.

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:

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 smtplib enables 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 smtplib.
    • ssl: to send HTML content emails, we still need ssl.
    • email: use the email module if we want to send fancy emails.
      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.mime module to add HTML, and attach documents to the email. You can learn more about the Multipurpose Internet Mail Extensions (MIME) standard here.

All right!

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 - 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: smtplib and ssl.

  • Create a secure default settings context
    Use the ssl.create_default_context function 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
    Use the smtplib.SMTP_SSL function
    You can find out about Gmail’s SMTP server ( 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 with statement to connect, so that the connection automatically quits when the with statement exits.

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.

send plain text email using python

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.

send plain text email via python

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,, 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 plain text email with multiple recipients, subject, to

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 email. More specifically, we’ll use the email.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:

  1. Create a MIMEMultipart class
  2. Attach extra MIME classes (e.g., MIMEText with the email message, MIMEApplication with attachments) to it

Let’s explore some examples below.

Send HTML content with the email.mime module

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
    Besides smtplib and ssl, we also need some functions to create MIME subclasses from email.mime. You can research different MIME classes here.
    We also import the pandas library 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 h1 and a p element. But you can include other elements such as table.
    If you are coming from How to generate Reports with Python tutorial, you can try to render the html report we’ve generated, except for the img element. The img element 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 MIMEMultipart class, and set up the From, To, Subject fields
    Note that the email.mime module 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 html doc defined earlier, as a MIMEText html content type to the MIME message
    Note that the default content type is ‘plain’, which won’t render the HTML document properly.
  • Convert the email_message as string
  • 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.

send HTML content email using python

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!

Add attachments

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 MIMEApplication class to hold attachments.
  • Define a function to attach files as MIMEApplication to 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.

HTML content email with attachment

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 img element with src as 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 extra_headers
    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 img
  • Apply function with extra_header on chart.png
    The Content-ID of myimageid matches with the img element in html. This renders the chart.png on 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.

HTML content email with attachment and image

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.

Lianne & Justin

Lianne & Justin

22 thoughts on “How to Send Emails using Python: Tutorial with examples<br /><div style='color:#7A7A7A;font-size: large;font-family:roboto;font-weight:400;'> Plain text, HTML with attachments</div>”

  1. Hi, since 30.05.2022 gmail doesn’t allow “access with less secure apps”, so it doesn’t work anymore.
    Are there other providers, which still work with your described method?

    1. Lianne & Justin

      Hi thanks for letting us know. If you want to stick to Gmail, you can set up an app password as we’ve updated in the article. For other providers, I haven’t tested, but outlook might be still available.

  2. Wow!
    Since Google changed the terms for Gmail to non-secure apps I have spent many hours looking at and creating apps that use OAuth 2.0 and Workspace services. But none (for various reasons) have been a complete substitute for what existed before the change.

    Your post is easy to understand and implement while also giving back the functionality that previously existed. What really blows me away is that I have never seen any mention of “To fix the problems with our tutorial on Gmail, please set up an App Password.”

    So thanks for that.

  3. Hi

    when I am trying to run the code on the server its giving the error

    f”attachment; filename= {filename}”,
    SyntaxError: invalid syntax


    this is the output that I am getting

    1. Hi Venkat, it’s hard to tell based on this. But since it’s a Syntax error, it could be the wrong indentation.

  4. When using this code, it’s embedding the photo and attaches it as a file. How do I get it to not attach but only show the image?

    1. Hi Brandon, I believe we’ve covered the similar topic within the article under the section Add image to email body.

  5. Hi Lianne and Justin, I would just like to say how helpful your lessons are! I have been learning a lot of code from you guys. Thank you.

Leave a Comment

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

More recent articles

Scroll to Top

Learn Python for Data Analysis

with a practical online course

lectures + projects

based on real-world datasets

We use cookies to ensure you get the best experience on our website.  Learn more.