How to Easily Send an Email from Python

Send email from Python

Hey there! Some links on this page may be affiliate links which means that, if you choose to make a purchase, I may earn a small commission at no extra cost to you. I greatly appreciate your support!

It is quite easy to send an email from Python. With just a few simple lines of Python code, you can send an email with a subject and body to one or more recipients with optional attachments.

The hardest part of sending email with Python is probably setting up your mail server. While email server setup is outside of the scope of this tutorial, I’m going to assume you’ve taken care of this. So let’s jump right into it.

Send Email from Python

The follow Python code was tested with Python 3.6.5, but any python version above Python 3.0 should work for you.  If you have an older version of Python, you can get setup with the latest and greatest version of Python on your Mac or Linux by watching this video.

Enough delay. Let’s send an email from Python!

From in a Python interpreter (i.e. simply type python from a terminal window), import the following packages.

import smtplib
from email import message

Next, let’s define a few variables: one for the from email address and one for the to email address.  Additionally, define strings for the subject content and body content.

from_addr = 'you@example.com'
to_addr = 'me@example.com'
subject = 'I just sent this email from Python!'
body = 'How neat is that?'

Moving on, we will create our message object next with a header and body.  In this case, the payload is the body of the email.

msg = message.Message()
msg.add_header('from', from_addr)
msg.add_header('to', to_addr)
msg.add_header('subject', subject)
msg.set_payload(body)

Finally, make a connection to the email server and send your first email from Python!  Of course, change the value of ‘password’ to be the actual password for that email address. Also, if you are not using DreamHost email hosting, modify the SMTP object to have the correct mail server address. For those of you who aren’t familiar, SMTP stands for Simple Mail Transfer Protocol.

server = smtplib.SMTP('smtp.dreamhost.com', 587)
server.login(from_addr, 'password')
server.send_message(msg, from_addr=from_addr, to_addrs=[to_addr])

Next, hop on over to the destination email client and your Python email should be right there at the top.

Email sent from Python in Gmail inbox

Send Email from Python with Attachment

To send email from python with an attachment, things get slightly more complicated, but definitely doable!  Consequently, our email will have multiple parts now:  a header, body, and attachment.  Thus, we will use the MIMEMultipart class MIME type from the email package to build up our an email object.

Let’s take it from square one.

Import the following packages.  You’ll see that instead of importing message, we are importing MIMEText, MIMEMultipart, and MIMEApplication.

import smtplib
from os.path import basename
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.application import MIMEApplication

Similar to above, let’s define some variables.

from_addr = 'you@example.com'
to_addr = 'me@example.com'
subject = 'I just sent this attachment from Python!'
content = 'How neat is that?'

This time, we will build our MIMEMultipart object a bit differently and attach the body to the message as MIMEText.

msg = MIMEMultipart()
msg['From'] = from_addr
msg['To'] = to_addr
msg['Subject'] = subject
body = MIMEText(content, 'plain')
msg.attach(body)

Moving right along, we will next read our text file into memory and attach it to our message as MIMEApplication. Of course, make sure a file called test.txt exists in the same directory that you opened the Python interpreter.

filename = 'test.txt'
with open(filename, 'r') as f:
    part = MIMEApplication(f.read(), Name=basename(filename))
    part['Content-Disposition'] = 'attachment; filename="{}"'.format(basename(filename))
msg.attach(part)

As before, login to the email server and send the email. Don’t forget to change the value of ‘password’ to the proper password. Also, if you are not using Dreamhost email hosting, change the SMTP server to the correct address for your setup.

server = smtplib.SMTP('smtp.dreamhost.com', 587)
server.login(from_addr, 'password')
server.send_message(msg, from_addr=from_addr, to_addrs=[to_addr])

Finally, open up your email client and you’ll find a nice looking message with an attachment waiting to be opened.

Email sent from Python with attachment in Gmail inbox

Taking It a Step Further

Now that you know how to send simple emails with Python, here are additional ways that you can expand on your newly found knowledge.

 Send Email to Multiple Recipients from Python

It’s also worth pointing out that to_addr can be a list and the send_message command can accept multiple email addresses as recipients.  For example, you can send to multiple email addresses like this.

to_addr = ['him@example.com', 'her@example.com']

Send Email with Multiple Attachments from Python

In addition, if you have multiple attachments to send out, you can loop over the filenames in a way similar to below.

filenames = ['test1.txt', 'test2.txt', 'test3.txt']
for filename in filenames:
    with open(filename, 'r') as f:
        part = MIMEApplication(f.read(), Name=basename(filename))
        part['Content-Disposition'] = 'attachment; filename="{}"'.format(basename(filename))
    msg.attach(part)

 


As a result of making it all the way through this Python tutorial, you now have all the knowledge you need to send email from Python. If you are interested in more tutorials like this, check out some of my other Python tutorials here.

Most of all, thank you for stopping by. Please let me know if you have questions in the comments below.

Facebook
Twitter
Pinterest
LinkedIn
Reddit

Meet Tony

Tony from Tony Teaches Tech headshot

With a strong software engineering background, Tony is determined to demystify the web. Discover why Tony quit his job to pursue this mission. You can join the Tony Teaches Tech community here.

One Response

  1. Regarding the “with” statement, everything following the colon must be indented (four spaces, not a tab).

    with open(filename, 'r') as f:
        part = MIMEApplication(f.read(), Name=basename(filename)) 
        part['Content-Disposition'] = 'attachment; filename="{}"'.format(basename(filename))
        msg.attach(part)

Leave a Reply

Your email address will not be published. Required fields are marked *