How to Send an Email with an Attachment in Python

In our last post, we went over how to send a simple email. In this post, we’ll go over how to send an email with an attachment, just like last time, we’ll be using Gmail. Before we get started, ensure that your Gmail account has 2-Step Verification enabled. If you haven’t enabled it, go check out the post on how to send a simple email for detailed instructions.

In this post we’ll go over:

  • Set Up Your Gmail Configuration for Python
  • Python Code to Send an Email with an Attachment
    • Creating and Attaching the Attachment
  • Summary of How to Send Emails with Attachments in Python w/ Gmail

Set Up Your Gmail Configuration for Python

First we’ll need to create a config file. The gmail_pass, user, host, and port will be the same as we defined in our last post. Your gmail_pass will be the 16 character code you got after setting up app passwords and 2-Step Verification, and the user will be your Gmail address. Host and Port will be “smtp.gmail.com” and 465 for all Gmail applications.

gmail_pass = "<your app password here>"
user = "<your gmail here>"
host = "smtp.gmail.com"
port = 465

Python Code to Send an Email with an Attachment

Let’s start off with our imports. Our first two imports are for our Simple Mail Transfer Protocol library (native to Python), and os for accessing the operating system. MIMEText is a Multipurpose Internet Mail Extension (MIME) text object that we’ll use to create the body. MIMEMultipart is a MIME object with multiple parts (duh). MIMEApplication is the object type that we’ll use to create our attachment. Header is our header object that we use to declare the “to”, “from”, and “subject” parts of our email.

import smtplib
import os
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.application import MIMEApplication
from email.header import Header
 
from email_config import gmail_pass, user, host, port

Now we’ll define our function as send_email_w_attachment, which will take four parameters this time. It’ll take a “to”, “subject”, “body”, and “filename”. Just like before, we’ll build our message using a MIMEMultipart object and attach the From, To, and Subject headers. Then we’ll add our body as plaintext.

def send_email_w_attachment(to, subject, body, filename):
    # create message object
    message = MIMEMultipart()
 
    # add in header
    message['From'] = Header(user)
    message['To'] = Header(to)
    message['Subject'] = Header(subject)
 
    # attach message body as MIMEText
    message.attach(MIMEText(body, 'plain', 'utf-8'))

Creating and Attaching the Attachment

Here’s where we’ll switch things up before we send out the email. We’ll use os.path.basename to find the name of the file. This command will extract the basename of the file from the passed in filename (that is the name without the directory extensions). We’ll open the file to read in as bytes, and use our MIMEApplication object to read in our file. Make sure to specify your file type using the “_subtype” parameter. Ours will be a “txt” file. Then close our file to prevent memory leaks. Once we’ve created our attachment object, we need to add a header to it to let the MIMEMultipart object know what we’re attaching. Finally, we simply call the MIMEMultipart object, “message”, and attach our attachment object before we call the server to send the mail.

    # locate and attach desired attachments
    att_name = os.path.basename(filename)
    _f = open(filename, 'rb')
    att = MIMEApplication(_f.read(), _subtype="txt")
    _f.close()
    att.add_header('Content-Disposition', 'attachment', filename=att_name)
    message.attach(att)
 
    # setup email server
    server = smtplib.SMTP_SSL(host, port)
    server.login(user, gmail_pass)
 
    # send email and quit server
    server.sendmail(user, to, message.as_string())
    server.quit()

To send an example email, I set up variables for the parameters we’ll pass in. Internshipsdiscord@gmail.com is the official gmail for the Internships discord server. I created a small text file as an example attachment in the same folder that I have this file in.

# who are we sending this email to?
to = "internshipdiscord@gmail.com"
 
# what is our subject line?
subject = "An example email"
 
# what is the body of the email?
body = "Hi,\nThis email is an example of how to send emails in Python\nBest, Yujian Tang"
 
# what is the name of the file we want to attach?
filename = "attachment.txt"

To run our program we simply call it using python as shown below:

Executing our Python Script to Send an Email

Then we can check the destination email and we should expect to see an email with a subject line of “An example email” and with a text file attachment like below.

Email with Attachment sent with Python received

Summary of How to Send Emails with Attachments in Python w/ Gmail

Further Reading

I run this site to help you and others like you find cool projects and practice software skills. If this is helpful for you and you enjoy your ad free site, please help fund this site by donating below! If you can’t donate right now, please think of us next time.

Yujian Tang

7 thoughts on “How to Send an Email with an Attachment in Python

  1. Pingback: Discord
  2. Can a script design to read a .csv which contains a list of Name,email,file name.extension, and send each email accordingly?

Leave a Reply

Discover more from PythonAlgos

Subscribe now to keep reading and get access to the full archive.

Continue reading