Sending Emails With Python
You probably found this tutorial because you want to send emails with Python to automate confirmation messages, password resets, or scheduled notifications. Python’s standard library covers the whole pipeline, from making a server connection to building the message and sending it to one or many recipients. This tutorial walks through every step in working code.
By the end of this tutorial, you’ll understand that:
- A safe testing setup uses a throwaway Gmail account with an app password, a local
aiosmtpddebug server, or a privacy-focused provider like Posteo or Proton Mail. - A secure SMTP session uses
.SMTP_SSL()withssl.create_default_context(), which validates the server certificate and encrypts your credentials and message content. - The
EmailMessageclass from theemailpackage assembles plain text, HTML alternatives, file attachments, and personalized fields through.set_content(),.add_alternative(), and.add_attachment(). - Setting
msg["reply-to"]or any other RFC 5322 header on anEmailMessageroutes replies to a different mailbox than the sender address. - For high-volume sending, transactional email services like SendGrid, Mailgun, and Brevo provide deliverability, statistics, and API libraries that go beyond what
smtplibalone offers.
Before you jump into the code, you’ll set up a throwaway email account or a local debug server so you can experiment freely without spamming real inboxes.
Get Your Code: Click here to download the free sample code you’ll use to learn how to send plain-text and HTML emails, attach files, and automate email delivery with Python.
Take the Quiz: Test your knowledge with our interactive “Sending Emails With Python” quiz. You’ll receive a score upon completion to help you track your learning progress:
Interactive Quiz
Use Python’s standard library to send email through secure SMTP connections, attach files, include HTML content, and route replies.
Setting Up an Email Service
Email is sent from a client to an email server, and from one email server to another, using the Simple Mail Transfer Protocol, or SMTP, defined under RFC 821. Python comes with the built-in smtplib module, which implements this protocol, allowing you to programmatically send email through any accessible email server.
While you can certainly use your own email account for this tutorial, it’s recommended that you set up a throwaway email account instead. There are several free and paid email services you can use. In this tutorial, you’ll explore the following options:
- Setting up a Gmail account for development: You’ll learn how to create a dedicated testing account and use app passwords to satisfy modern security requirements.
- Setting up a local SMTP server: You’ll use the
aiosmtpdlibrary to run a server on your own machine, allowing you to inspect email content without sending any live messages. - Setting up other email accounts for development: You’ll see how to connect to alternative services like Posteo or Proton Mail to ensure your code works across different providers.
Understanding the distinction between secure (encrypted) and insecure (unencrypted) connections is vital. Most modern providers require encryption via SSL or TLS to protect your data, while the local debugging server uses no encryption. By the end of this section, you’ll know how to choose the right connection type for your specific service choice.
Setting Up a Gmail Account for Development
To set up a Gmail account for testing your code, follow these steps:
- Create a new Google account. You need to provide a name, a birthday, and a unique username for the account.
- Set up two-factor authentication for the new account.
- Add a new app password to allow password sign-ins to the account.
An app password is a temporary password generated by Google. Instead of using your main account password to authenticate with your username, you use the app password. You can delete and recreate app passwords whenever you like.
App passwords allow access to Gmail when modern security measures like OAuth2 aren’t available. When creating one, make sure you copy it to a secure location, as you won’t be able to review it after leaving the page.
If you don’t want to use an app password, check out Google’s documentation on how to obtain access credentials for your Python script using the OAuth2 authorization framework.
A nice feature of Gmail is that you can use the + sign to add modifiers to your email address right before the @ sign. For example, emails sent to my+person1@gmail.com and my+person2@gmail.com will both arrive at my@gmail.com. When testing email functionality, you can use this to simulate multiple addresses that all point to the same inbox.
Setting Up a Local SMTP Server
You can test email functionality by running a local Simple Mail Transfer Protocol (SMTP) debugging server with the aiosmtpd module. Rather than sending emails to a specific address, the local debug server discards the message after printing its content to the console. Running a local debugging server makes it unnecessary to deal with encryption of messages or use credentials to log in to an email server.
Note: aiosmtpd is a third-party library that replaces the former built-in smtpd module, which was initially deprecated in Python 3.4.7. Deprecation notices were repeated in 3.5.4 and 3.6.1, and the module was eventually removed in Python 3.12, as outlined in PEP 594.
Install the aiosmtpd module with the following command:
$ python -m pip install aiosmtpd
Then, start a local SMTP debugging server with this command:
$ python -m aiosmtpd -n
Read the full article at https://realpython.com/python-send-email/ »
[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short & sweet Python Trick delivered to your inbox every couple of days. >> Click here to learn more and see examples ]
