Python Training by Dan Bader

How to Send an Email With Python

Learn how to send emails using Python code via the built-in “smtplib” module from the standard library.

Sending Emails with Python

In most applications, you need to communicate with your users using electronic methods. Email is used to send password resets, confirmation of orders, and verification of user accounts. Whatever your reason, the process of emailing is always the same no matter what language you use.

In this tutorial you’ll learn how to send emails using Python.  

Understanding Email Basics

Before we get into the code, you should understand basic email workflow. When you send an email either from a web-based application or local software running on your computer, your client application packages the message and sends it using an SMTP (Simple Mail Transfer Protocol) server.

You need this server to send email regardless if it’s from an email client like Outlook or Thunderbird, or a Python program. When you open a hosting account with any company, they will give you SMTP credentials to send email using their servers.

There are numerous open, free-to-use SMTP servers, but these are often used by spammers and blocked by most incoming mail servers. It’s best to use a password-protected SMTP server, because your mail will likely reach the recipient instead of getting filtered and dumped into the recipient’s spam folder.

An SMTP server isn’t always an external server on the host. In some cases, you will send email from the same machine running your Python code. You would then use “localhost” as your SMTP server. To find out the right configurations for this Python email example, please review your email provider’s documentation. I’ll use Gmail for this example.

When you want to send email to a recipient, first you need to gather the email’s parameters. This can be either from input entered by the user or hardcoded in your code.

A typical email requires the following parameters:

  • Recipient email address
  • Sender email address
  • Message Subject
  • Message Body
  • Attachments (if any, not required)
  • SMTP server address
  • SMTP port (usually 25, but could also be 2525 or 587 as alternatives)

A note about the sender address: You can use any email address that you want, but some incoming servers (i.e. Gmail) detect fake sender addresses and may drop your email into the spam folder for security purposes.

So it’s better to use a “real” email address that actually exists. You can then set it up as a “Do Not Reply” sender to alert users not to reply to the message rather than use a fake email sender address. In some cases, the SMTP server will reject the message and the recipient won’t get the email message at all.

Sending Email in Python With the smtplib Module

The first step is to import Python’s built-in smtplib library. This library takes care of most of the code in its own methods and properties, so you don’t need much code to send an email at all.

Type the following code at the beginning of your file:

import smtplib

With this library imported, we can set up email parameters. We know that at least recipient, sender, subject and body is needed, so let’s set up those variables:

import smtplib

sender = "sss@yourdomain.com"
recipient = "rrr@gmail.com"
subject = "Test email from Python"
text = "Hello from Python"

Easy enough. But now we need to send the email using an SMTP sever. In this example, we’ll use Gmail since it’s free and open to anyone with a Google account.  Just keep in mind that if you’re hosting a website or web-based application, your host will have an SMTP server associated with your hosting account and you’ll need to adjust the SMTP server address and credentials for this example to work.

🔐 Enabling SMTP access in Gmail

To allow your Python app to log into the Gmail servers using your account in order to send emails, you need to allow it in your account settings. Go to this link while signed into your account and flip this feature on.

If you forget to turn on access to less secure applications, you will receive an SMTPAuthenticationError exception.

Gmail’s SMTP server is “smtp.gmail.com” and they use port 587. The username is your email address, and the password is your email password. Let’s add another variable to hold the password since we already have the username in the “sender” variable:

import smtplib

sender = "sss@yourdomain.com"
recipient = "rrr@gmail.com"
password = "thepassword" # Your SMTP password for Gmail
subject = "Test email from Python"
text = "Hello from Python"

Notice that the text variable only contains one sentence. If you need multi-line support, you can use the \\n character to add line-feeds:

text = "Hello from Python\nThis is line 2\nAnd line 3"

With our basic email parameters set up, we can now use the smtplib library to send the email. You can communicate with the SMTP server in plain text or encrypted using SSL.

Because privacy is an important issue, we’ll use the SMTP_SSL class to ensure communication between your Python program and the SMTP server is encrypted.

Please note that this is true only for the first “hop” in the chain—email is a distributed system and any email you send likely travels through many independent email servers that can access the full unencrypted contents of your email. There are also no guarantees that emails are encrypted in transit from one email server to the next, so email can’t be deemed a secure medium.

It’s always a good idea to use SMTP_SSL here because it will ensure we’re not leaking your SMTP credentials when connecting to the email server:

import smtplib

sender = "sss@yourdomain.com"
recipient = "rrr@gmail.com"
password = "xxxxxx" # Your SMTP password for Gmail
subject = "Test email from Python"
text = "Hello from Python"

smtp_server = smtplib.SMTP_SSL("smtp.gmail.com", 465)
smtp_server.login(sender, password)
message = "Subject: {}\n\n{}".format(subject, text)
smtp_server.sendmail(sender, recipient, message)
smtp_server.close()

Let’s review what happens in the above code snippet. 

First, the SMTP_SSL method sets up the server settings using SSL. Then, the login() method verifies your username and password. If it’s incorrect, you’ll receive an authentication error:

smtplib.SMTPAuthenticationError: (535, b'5.7.8 Username and Password not accepted. Learn more at\n5.7.8  https://support.google.com/mail/?p=BadCredentials o22 sm62348871wrb.40 - gsmtp')

Also, with Gmail, if the wrong username and password is used, you receive an alert on your account that a failed login attempt was made. If you use Gmail to practice emailing with Python, try to avoid too many incorrect login attempts or Google will lock the account for security purposes. It’s always better to use a throwaway account when practicing.

Next, the sendmail() method tells the SMTP server to deliver the actual email payload. You’ll notice this method doesn’t accept separate arguments for the message subject and body. Instead, the email subject is denoted by a Subject: prefix in the message payload. So we’ll need to prepare the message body first by formatting the subject and text variables, and then passing the result to sendmail().

This will hand over the message to the SMTP server and deliver it to the recipient. If there’s an issue with your SMTP username and password or the login() call failed, you might encounter a SMTPSenderRefused exception:

smtplib.SMTPSenderRefused: (530, b'5.5.1 Authentication Required. Learn more at\n5.5.1  https://support.google.com/mail/?p=WantAuthError o22sm62348871wrb.40 - gsmtp', 'sss@yourdomain.com')

If all goes well and you run the code above with your own email accounts, the email message will be delivered to the recipient address.

You can send more than one email that way simply by repeatedly calling the sendmail() method. Once you’re done sending you should close the SMTP connection by calling the close() method on the SMTP_SSL object.

That’s all it takes to send an email in Python.

Just remember to limit the number of emails that you send at once, or you could run into spam filters. Gmail rate limits the number of messages that you can send at once, so you might want to place a delay between sending messages, for example with Python’s time.sleep() function.

Additional Resources

  • Python’s smptlib module documentation (Python 2, Python 3)
  • Simple Mail Transfer Protocol (SMTP) on Wikipedia
  • Python’s email module documentation (Python 2, Python 3): The email module included with Python’s standard library helps you format and parse email messages. Instead of assembling the message payload manually using string formatting you can use the functions in the email module and make your code more robust and readable.
  • Instead of directly connecting to an SMTP server and sending your emails that way, you can sign up with an email service provider that offers its own Python SDK or generic web API for sending email. Two services I can recommend are SendGrid and MailJet.

<strong><em>Improve Your Python</em></strong> with a fresh 🐍 <strong>Python Trick</strong> 💌 every couple of days

Improve Your Python with a fresh 🐍 Python Trick 💌 every couple of days

🔒 No spam ever. Unsubscribe any time.

This article was filed under: email, and python.

Related Articles:
Latest Articles:
← Browse All Articles