Jun 08 2022 · Aleksandra Płońska, Piotr Płoński

How to send email in Python? (the simplest approach)

Python send email banner Sending emails from Python code is simple. It can be used for automation and notification apps. In this article we will create send_email() function that will simplify the email sending. We will use Python built-in packages smtplib and email. Let's start sending emails with Python!

How to send email in Python?

The simplest approach is to use the following code:

# import packages
# below packages are built-in - no need to install anything new!
# yupi :)
import smtplib
from email.message import EmailMessage

# set your email and password
# please use App Password
email_address = "my-gmail-address@gmail.com"
email_password = "app-password-for-gmail"

# create email
msg = EmailMessage()
msg['Subject'] = "Email subject"
msg['From'] = email_address
msg['To'] = "to-address@gmail.com"
msg.set_content("This is eamil message")

# send email
with smtplib.SMTP_SSL('smtp.gmail.com', 465) as smtp:
    smtp.login(email_address, email_password)
    smtp.send_message(msg)

The email is sent with 3 last lines of code! And you don't need to install any additional packages to make it work (I like it!). The above code snippet is using Gmail SMTP (Simple Mail Transfer Protocol) server. If you are using different email provider then you need to change the smtp.gmail.com to your provider address and change the port number (465). You need to set email_address and email_password variables to yours. For email password please generate the App Password for your Gmail. Here is a link with docs how to generate the App Password for Gmail account. It might be a good idea to create a new Gmail account only for use in Python scripts (a throwaway account).

The above code construct EmailMessage object. It is easy to manipulate. To set the subject of the email just change the string assigned to msg['Subject']. The email content is set with msg.set_content("This is email message").

The above code is simple and can be used for quick experiments. If you are going to use it in serious project let's do some code refactoring.

Don't keep password in the code!

Please don't keep secrets hard coded. Please don't push them to the repository. Please keep all secrets as environment variables or in the .env file. There is a fatnatstic package python-dotenv for loading environment variables from .env file. Please do not push .env file to the repository. Please add .env to .gitignore.

You can easily install python-dotenv with:

pip install python-dotenv

Then create .env file:

EMAIL_ADDRESS=my-gmail-address@gmail.com
EMAIL_PASSWORD=app-password-for-gmail

Please keep the .env file in the same directory as your code. To load values from .env you can use the following code:

import os
from dotenv import load_dotenv
_ = load_dotenv()

email_address = os.environ.get("EMAIL_ADDRESS")
email_password = os.environ.get("EMAIL_PASSWORD")

OK, our code looks better. The next step will be to turn it into a nice function.

Python send email as a single function

The Python code for email sending can be included in a single send_email() function. It will accept three arguments:

  • to - address to whom send an email,
  • subject - the email subject,
  • message - the email content.

The code is below:

import os
import smtplib
from email.message import EmailMessage
from dotenv import load_dotenv
_ = load_dotenv()


def send_email(to, subject, message):

    email_address = os.environ.get("EMAIL_ADDRESS")
    email_password = os.environ.get("EMAIL_PASSWORD")

    # create email
    msg = EmailMessage()
    msg['Subject'] = subject
    msg['From'] = email_address
    msg['To'] = to
    msg.set_content(message)

    # send email
    with smtplib.SMTP_SSL('smtp.gmail.com', 465) as smtp:
        smtp.login(email_address, email_password)
        smtp.send_message(msg)

The above code is not perfect, but it's simple. Why is it not perfect? Because there are no error handling ... Let's try to improve a little:

import os
import smtplib
from email.message import EmailMessage
from dotenv import load_dotenv
_ = load_dotenv()


def send_email(to, subject, message):
    try:
        email_address = os.environ.get("EMAIL_ADDRESS")
        email_password = os.environ.get("EMAIL_PASSWORD")

        if email_address is None or email_password is None:
            # no email address or password
            # something is not configured properly
            print("Did you set email address and password correctly?")
            return False

        # create email
        msg = EmailMessage()
        msg['Subject'] = subject
        msg['From'] = email_address
        msg['To'] = to
        msg.set_content(message)

        # send email
        with smtplib.SMTP_SSL('smtp.gmail.com', 465) as smtp:
            smtp.login(email_address, email_password)
            smtp.send_message(msg)
        return True
    except Exception as e:
        print("Problem during send email")
        print(str(e))
    return False

The above code is better. We added exception handling and check for email and password setup. The function send_email() returns True for successful email send and False otherwise.

Summary

The above Python code makes email sending easy. It can be a great start for creating some automation or notification systems. If you would like to have more functionality, you can code it yourself or use existing packages. I would recommend yagmail for advanced email sending (if you would like to send attachments, HTML version of the content). The usage of yagmail is simple:

# after installation with
# pip install yagmail[all]

import yagmail
yag = yagmail.SMTP(EMAIL_ADDRESS, EMAIL_PASSWORD)
yag.send("to@someone.com", "subject", "message")

If you are using Django web framework, you can use send_mail() or send_mass_mail() from django.core.mail. If you are going to send many emails daily you sould consider transactional email service providers like: AWS SES, SendGrid, MailGun, MailJet. They have some free plans. The Gmail service let's you send 500 emails per day. You need to check which one fits you.

If you have any questions or need help please subscribe to the newsletter below. In the form, you can leave feedback, comment, or question. We do our best to respond quickly :)