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:
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.
Summary of How to Send Emails with Attachments in Python w/ Gmail
Further Reading
- Slicing Python Strings
- War Game in Python
- Build Your Own AI Text Summarizer in Python
- Python GRU RNN in Keras
- Fast Track Your Junior to Senior Engineer Promotions
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.
Make a one-time donation
Make a monthly donation
Make a yearly donation
Choose an amount
Or enter a custom amount
Your contribution is appreciated.
Your contribution is appreciated.
Your contribution is appreciated.
DonateDonate monthlyDonate yearly
Can a script design to read a .csv which contains a list of Name,email,file name.extension, and send each email accordingly?
Yes, if you would like some help in this area, feel free to reach out to me on LinkedIn to chat more!