How to Send an Email in Python

Send emails using SMTP mailer in Python. Detailed tutorial for sending mail in Python.

Introduction

To extend the functionality of any web application, it's essential to integrate the sending of notifications and emails. For such cases, Python has a built-in smtplib module for sending emails using Simple Mail Transfer Protocol (SMTP). In this tutorial, we'll discuss all the necessary steps to send emails through an SMTP server using Python programming language. We will also learn about the different kinds of sending emails, from emails with images and attachments to multiple emails at once.

How to send an email using SMTP?

The standard Python library includes an SMTP module for sending emails. There is no need for additional settings or procedures. The module can be imported using the following statement:

import smtplib

Type the following into an interactive Python process to make sure that the module has been successfully imported and to get a complete description of its classes and arguments:

help(smtplib)

Python SMTP server for email testing

To avoid spamming your mail and customers, it is important to experiment on a test server when creating a new application or adding features for the first time. That way, your domain will not be on the block due to spam.

Local SMTP server

You may test email functionality using Python's pre-installed smtpd module. It discards emails and prints their content to the console instead of sending them. Running a local debugging server eliminates the need to encrypt messages or log into an email server.

In Command Prompt, type:

python -m smtpd -n -c DebuggingServer localhost:1025

To run the SMTP server on port 25, you need access to root on Linux:

sudo python -m smtpd -n -c DebuggingServer localhost:25

It helps you test your code and identify any flaws. However, you won't be able to check your HTML email template.

How to send HTML email?

In most cases, you need to add some formatting, links, or images to your email notifications. We can simply put all of these with the HTML content. For this purpose, Python has an email package.

We will deal with the MIME message type, which is able to combine HTML and plain text. In Python, it is handled by email.mime module.

It is better to write text and HTML versions separately and then merge them with the MIMEMultipart("alternative") instance. It means that such a message has two rendering options accordingly. In case an HTML isn't rendered successfully for some reason, a text version will still be available.

# import ing the modules
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart

port = 2525
smtp_server = "smtp.example.com" # write your server's name
login = "1a2b3c4d5e6f7g" # paste your login
password = "1a2b3c4d5e6f7g" # paste your password
sender_email = "me@example.com"
receiver_email = "you@example.com"
message = MIMEMultipart("alternative")
message["Subject"] = "multipart test"
message["From"] = sender_email
message["To"] = receiver_email
# write the plain text part
text = """\
Hi,
Check out the new post about using Python for sending emails:
SMTP Server for Testing: Cloud-based or Local?
/blog/2018/09/27/cloud-or-local-smtp-server/
Feel free to let us know what content would be useful for you!"""
# write the HTML part
html = """\
<html>
  <body>
    <p>Hi,<br>
       Check out the new post about using Python for sending emails:</p>
    <p><a href="/blog/2018/09/27/cloud-or-local-smtp-server">SMTP Server for Testing: Cloud-based or Local?</a></p>
    <p> Feel free to <strong>let us</strong> know what content would be useful for you!</p>
  </body>
</html>
"""
# convert both parts to MIMEText objects and add them to the MIMEMultipart message
part1 = MIMEText(text, "plain")
part2 = MIMEText(html, "html")
message.attach(part1)
message.attach(part2)
# send your email
with smtplib.SMTP("smtp.example.com", 2525) as server:
    server.login(login, password)
    server.sendmail(
        sender_email, receiver_email, message.as_string()
    )
print('Sent')

Sending emails with attachments using Python

Let's learn how to attach various files to emails using Python. Python allows us to attach text, images, audio files, and applications. Attachments are MIME objects but must be base64 encoded. Use email.mime.audio.MIMEAudio or email.mime.image.MIMEImage to attach a file. Remember that you should not send files larger than 20 MB, although it is possible.

Receipts, tickets, boarding passes, order confirmations, etc., are usually sent in PDF format.

Let's see how to send boarding passes in PDF format:

import smtplib

# import the needed modules
from email import encoders
from email.mime.base import MIMEBase
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText

port = 2525
smtp_server = "smtp.example.com" # put your server's name
login = "1a2b3c4d5e6f7g" # paste your login
password = "1a2b3c4d5e6f7g" # paste your password

subject = "An example of boarding pass"
sender_email = "me@example.com"
receiver_email = "you@example.com"

message = MIMEMultipart()
message["From"] = sender_email
message["To"] = receiver_email
message["Subject"] = subject

# Add body to email
body = "This is an example of how we can send a boarding pass in attachment using Python"
message.attach(MIMEText(body, "plain"))

filename = "yourBP.pdf"
# Open PDF file in binary mode

# We assume that the file is in the directory where you run your Python script from
with open(filename, "rb") as attachment:
    # The content type "application/octet-stream" means that a MIME attachment is a binary file
    part = MIMEBase("application", "octet-stream")
    part.set_payload(attachment.read())

# Encode to base64
encoders.encode_base64(part)

# Add header
part.add_header(
    "Content-Disposition",
    f"attachment; filename= {filename}",
)

# Add attachment to your message and convert it to string
message.attach(part)
text = message.as_string()

# send your email
with smtplib.SMTP("smtp.example.com", 2525) as server:
    server.login(login, password)
    server.sendmail(
        sender_email, receiver_email, text
    )
print('Sent') 

To attach multiple files, you can use the message.attach() method several times.

Emails with images

Images are attachments, even if they are included in the message body. They come in three different varieties: linked images, base64 images, and CID attachments, which are all embedded as MIME objects. In this section, we'" cover their quirks, advantages and disadvantages, and compatibility with most email clients.

To add a CID attachment, we will create a multi-part MIME message with the MIMEImage component:

# import all necessary components
import smtplib
from email.mime.text import MIMEText
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart

port = 2525
smtp_server = "smtp.example.com" # type your server's name
login = "1a2b3c4d5e6f7g" # paste your login
password = "1a2b3c4d5e6f7g" # paste your password

sender_email = "me@example.com"
receiver_email = "you@example.com"
message = MIMEMultipart("alternative")
message["Subject"] = "CID image test"
message["From"] = sender_email
message["To"] = receiver_email

# write the HTML part
html = """\
<html>
 <body>
   <img src="cid:Mailtrapimage">
 </body>
</html>
"""

part = MIMEText(html, "html")
message.attach(part)

# We assume that the image file is in the same directory that you run your Python script from
fp = open('mailtrap.jpg', 'rb')
image = MIMEImage(fp.read())
fp.close()

# Specify the  ID according to the img src in the HTML part
image.add_header('Content-ID', '<Mailtrapimage>')
message.attach(image)

# send your email
with smtplib.SMTP("smtp.example.com", 2525) as server:
   server.login(login, password)
   server.sendmail(
       sender_email, receiver_email, message.as_string()
   )
print('Sent')

The CID picture is shown as an attachment and a component of an HTML message. However, many email applications, most notably Gmail, don't often display CID pictures since messages containing this image format are frequently seen as spam.

So let's look at how to attach a base64-encoded image.

# import the necessary components
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
import base64

port = 2525
smtp_server = "smtp.example.com" # paste your server's name
login = "1a2b3c4d5e6f7g" # paste your login
password = "1a2b3c4d5e6f7g" # paste your password

sender_email = "me@example.com"
receiver_email = "you@example.com"
message = MIMEMultipart("alternative")
message["Subject"] = "inline embedding"
message["From"] = sender_email
message["To"] = receiver_email

# We assume that the image file is in the same directory that you run your Python script from
encoded = base64.b64encode(open("mailtrap.jpg", "rb").read()).decode()

html = f"""\
<html>
 <body>
   <img src="data:image/jpg;base64,{encoded}">
 </body>
</html>
"""

part = MIMEText(html, "html")
message.attach(part)

# send your email
with smtplib.SMTP("smtp.example.com", 2525) as server:
   server.login(login, password)
   server.sendmail(
       sender_email, receiver_email, message.as_string()
   )
print('Sent')

The image is now embedded in the HTML message and is not available as an attachment and will not show up as spam.

Sending multiple emails using Python

The advantage of Python email is that you can send multiple emails to different recipients and personalize each one. Just insert the addresses of additional recipients, separating them with commas, and add CCs and BCCs. But Python loops will be handy if you're sending out bulk mail. One method is to create a database in.csv format and save it in the same directory as your Python script.

Let's create a simplest table with only two columns—name and email address—from the list:

#name,email
John Johnson,john@johnson.com
Peter Peterson,peter@peterson.com

The code below will open the file, loop through its rows line by line, and replace the value of the "name" column with the "name" placeholder.

import csv, smtplib

port = 2525
smtp_server = "smtp.example.com"
login = "1a2b3c4d5e6f7g" # paste your login
password = "1a2b3c4d5e6f7g" # paste your password

message = """Subject: Order confirmation
To: {recipient}
From: {sender}

Hi {name}, thanks for your order! We are processing it now and will contact you soon"""
sender = "you@example.com"

with smtplib.SMTP("smtp.example.com", 2525) as server:
    server.login(login, password)
    with open("contacts.csv") as file:
        reader = csv.reader(file)
        next(reader)  # it skips the header row
        for name, email in reader:
            server.sendmail(
               sender,
                email,
                message.format(name=name, recipient=email, sender=sender)
            )
            print(f'Sent to {name}')

We receive the following outcome after executing the script:

Sent to John Johnson
Sent to Peter Peterson

Sending emails via Gmail using Python

Set up your business server when you're ready to send emails to actual recipients. Your localhost or any external SMTP relies on your demands, objectives, and tastes. Let's look deeper at Gmail, one of the most well-liked choices. To use the Gmail server, you'll need to know:

server name = smtp.gmail.com
port = 465 for SSL/TLS connection (preferred)
Or port = 587 for STARTTLS connection.
username = your Gmail email address
password = your password.

You can use Yagmail, a specialized Gmail/SMTP, if you want something simple. Just compare the above examples with these few lines of code:

import smtplib, ssl

port = 465
password = input("your password")
context = ssl.create_default_context()
with smtplib.SMTP_SSL("smtp.gmail.com", port, context=context) as server:
    server.login("my@gmail.com", password)

Or using Yagmail:

import yagmail
yag = yagmail.SMTP()
contents = [
    "This is the body, and here is just text http://somedomain/image.png",
    "You can find an audio file attached.", '/local/path/to/song.mp3'
]
yag.send('to@someone.com', 'subject', contents)

Conclusion

So in this tutorial, we have demonstrated the essential alternatives for sending emails using Python. Studying Python documentation and just playing with your code are two things we advise you to do to get great results.

Related content

Java email library for SMTP and creating email addresses

MailSlurp Java SDK for sending and receive email and attachments on the JVM.

Python

Send and receive email in Python, create test email accounts and more with the official PyPI MailSlurp package.

SMTP email application libraries

How to send email in CSharp, PHP, Ruby, Java, Python, and NodeJS using the SMTP protocol and MailSlurp mailservers.

How to install Conda on Linux/OSX for python

Conda is a package management system that is popular in the machine learning and python space.

How to Send an Email in Python

Send emails using SMTP mailer in Python. Detailed tutorial for sending mail in Python.

How to send emails in Javascript (NodeJS)

JS SMTP email sending guide using HTML and NodeJS.

How to send an email using Powershell (Windows and cross-platform)

Use Send-MailMessage in Windows Powershell to send emails using an SMTP server or MailSlurp's free email API.

Test SMTP servers with Telnet

How to use Telnet to test the SMTP servers?

What Is Amazon Simple Storage Service (SES) - And How Can I Use It?

Amazon SES is an email service among virtual servers, AI apps, and libraries. Ideally, you can integrate your email system with your program hosted on Amazon.

Grab all details about an SMTP Port

What are common SMTP mail server ports and how do you find them?

Which SMTP Port Should I Use?

Picking the right port for SMTP mailservers

PyTest Email Testing

Send and receive email in Pytest Python tests.

Python Robot Framework email test

Python automation email testing Robotframework plugin

Avoiding email spam filters

How to send emails that don't trigger a spam warning.

BCC and CC in SMTP emails

BCC and CC in SMTP emails

BCC For Email: What It Means And When To Use It

What is BCC email field (blind carbon copy) and how does it differ to CC?

What Is The Best SMTP Port To Use?

MailServers use TCP ports to transmit emails. Picking the right port between 25 vs 2555, 465 vs 587 in SMTP is easy with this guide.

How to configure Mail desktop clients with MailSlurp

How to setup MailSlurp with Outlook, Gmail, Thunderbird, Mail app and more.

Send email with CSharp using SMTP Client and MailSlurp

Create a custom SMTP client and access MailSlurp inboxes from CSharp/DotNET.

DMARC – All Facts that you should know

DMARC – All Facts that you should know

Email size limits

Email size limits

The Fundamentals Of Email Subdomains

How to manage email subdomain custom mailboxes using SMTP/IMAP mailserver settings.

A guide to PHP Mailer

A guide to PHP Mailer

SMTP IMAP Settings

How to access MailSlurp email accounts using IMAP and SMTP servers

SMTP Relay for outbound smtp servers

How to use SMTP relay to address spam and security issues that affect outbound mail servers.

SMTP vs HTTP MailSlurp inboxes

The difference between HTTP and SMTP inboxes and domains in MailSlurp.

What are SMTP ports

What are SMTP ports

CSharp send SMTP email

How to use CSharp SMTP client to send email with MailSlurp mail server

Send SMTP email with Java

How to use Java SMTP client to send email with MailSlurp mail server on the JDK

Send emails in NodeJS using SMTP

How to use Javascript SMTP client (or Nodemailer) to send email with MailSlurp mail server

Send SMTP emails with PHP

Use PHPMailer to send emails with SMTP and MailSlurp

Send SMTP email with Python (using SMTPLib)

How to send emails with Python's built-in SMTP client and MailSlurp mail servers.

Ruby send SMTP email

How to use Ruby SMTP client to send email with the MailSlurp mail servers

Ready to dive in?Start building email applications today.