How to Send Emails With Python

If you have an app built with Python or planning to create one, then you may want to add some new functions related to email sending or notifications. In this case, you may find this tutorial useful as we are going to tell you how to send emails with Python. Today we will provide you with a few steps that you will need to follow if you want to send emails via an SMTP server.

How to Send an Email Using SMTP

Python can send emails via SMTP with help of a built-in module in its standard library. So, if you want to import it you just need to use the next statement:

import smtplib

In order to ensure that the module is imported and works properly, you will need to type the next statement in your interactive Python session:

help(smtplib)

Also, this statement allows you to check the full description of the module’s classes and arguments. If you want to test your email sending function you can use local SMTP server or any email sandbox service, and Python has the smtpd module for this purpose.

How to Send an HTML Email

Some things like links or images are important for different email notifications. If you want to add one of these things then you can try to put it with the HTML content. In order to do it, you will have to use an email package that Python has for this purpose.

If you want to combine plain text and HTML you will have to work with the MIME message type and Python allows you to do it with help of the email.mime module. In order to deal with it, you should write an HTML version and a plain text version separately. After that, you will need to merge them with help of the instance galled MIMEMultipart(“alternative”). So, your message will have two rendering options. Here is the input:

# import the necessary components first
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
port = 2525
smtp_server = "smtp.mailtrap.io"
login = "1a2b3c4d5e6f7g" # paste your login generated by Mailtrap
password = "1a2b3c4d5e6f7g" # paste your password generated by Mailtrap
sender_email = "[email protected]"
receiver_email = "[email protected]"
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 on the Mailtrap blog:
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 on the Mailtrap blog:</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.mailtrap.io", 2525) as server:
    server.login(login, password)
    server.sendmail(
        sender_email, receiver_email, message.as_string()
    )
print('Sent')

Sending Emails With Attachments

Sending emails with attachments in Pythons is the next thing that you should master. These attachments are the MIME objects that you don’t have to encode with the base64 module. To attach some files, images, or audio, you should use the appropriate email class. For example, you could try to do it with email.mime.audio.MIMEAudio or email.mime.image.MIMEImage. Here is the section of the Python documentation that refers to this information and some examples provided by Python.

If you want to send a transactional email then you will likely use PDF files. So, here is a short tutorial on how to send a boarding pass as such a file.

import smtplib

# import the corresponding 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.mailtrap.io"
login = "1a2b3c4d5e6f7g" # paste your login generated by Mailtrap
password = "1a2b3c4d5e6f7g" # paste your password generated by Mailtrap

subject = "An example of boarding pass"
sender_email = "[email protected]"
receiver_email = "[email protected]"

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

# Add body to email
body = "This is an example of how you can send a boarding pass in attachment with 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.mailtrap.io", 2525) as server:
    server.login(login, password)
    server.sendmail(
        sender_email, receiver_email, text
    )
print('Sent')

In order to attach a few files, you will need to use the message.attach() method a few times.

Sending an Email With Images

Images are the attachments to the message and they are divided into different types. The first type is known as CID attachments embedded as a MIME object. Such an image will be shown as an attachment and a part of the HTML message. Here is an example of how to create it.

# 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.mailtrap.io"
login = "1a2b3c4d5e6f7g" # paste your login generated by Mailtrap
password = "1a2b3c4d5e6f7g" # paste your password generated by Mailtrap

sender_email = "[email protected]"
receiver_email = "[email protected]"
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.mailtrap.io", 2525) as server:
   server.login(login, password)
   server.sendmail(
       sender_email, receiver_email, message.as_string()
   )
print('Sent')

The second type is base64 images (inline embedding). Here is an example with the same image file. You can see that the image is only embedded into the HTML message.

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

port = 2525
smtp_server = "smtp.mailtrap.io"
login = "1a2b3c4d5e6f7g" # paste your login generated by Mailtrap
password = "1a2b3c4d5e6f7g" # paste your password generated by Mailtrap

sender_email = "[email protected]"
receiver_email = "[email protected]"
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.mailtrap.io", 2525) as server:
   server.login(login, password)
   server.sendmail(
       sender_email, receiver_email, message.as_string()
   )
print('Sent')

Sending Multiple Emails

If you have a few recipients and you want to send multiple emails to them you can just write their addresses and separate them with commas. However, if you want to make a balk email sending then you should use some Python features that will save you with loops. We recommend you create a database in a .csv format and organize the list of recipients. Here is an example of such a list:

#name,email

John Johnson,[email protected]

Peter Peterson,[email protected]

The input that we provide you with will open the file and start to loop it over. So, it will be replacing the {name} with values that you can write in the name column.

import csv, smtplib

port = 2525
smtp_server = "smtp.mailtrap.io"
login = "1a2b3c4d5e6f7g" # paste your login generated by Mailtrap
password = "1a2b3c4d5e6f7g" # paste your password generated by Mailtrap

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 = "[email protected]"

with smtplib.SMTP("smtp.mailtrap.io", 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}')

Here you can see a message for John Jonson and a message for Peter Peterson. After you run this script you should be able to see the following response:

Sent to John Johnson

Sent to Peter Peterson

>>>

Sending an Email via Gmail

If you are ready to send your emails to real recipients you will need to configure your production server. Gmail is one of the most popular services for this purpose and we are going to tell you how to send an email with it.

The first thing that you will need to do is to create a new Gmail account. In order to be able to send your messages with a Gmail account, you will need to provide your app with access to it. You can try to use the OAuth2 authorization protocol or allow less secure apps. Also, if you want to use a Gmail server you will need to learn the next information about it:

  • The server name = smtp.gmail.com
  • Port = 465 for SSL/TLS connection (preferred)
  • Port = 587 for STARTTLS connection
  • Username = your Gmail address
  • Password = your password
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("[email protected]", password)

If you want to make email sending easier then you can use Yagmail. Just compare the examples that we mentioned above with the next lines of code:

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('[email protected]', 'subject', contents)

Next Steps With Emails in Python

This tutorial provided you with a couple of basic options for email sending with Python. If you want to get a better result then you should read the Python documentation and experiment with your codes.

Python has a lot of different frameworks and libraries which can help you to make your apps more dedicated and convenient. Here is the list of the most popular frameworks:

Article by Nataliia Polomkina

Submit your guest post