Open-Source Internship opportunity by OpenGenus for programmers. Apply now.
In this article, we have explained the idea of using Python to send file/ attachment in Gmail with a complete Python implementation example.
Table of contents:
- Introduction to SMTP and MIME
- Generate App password in Google
- Email config file setup
- Difference between sending a text email vs sending an attachment
- Example of an email header
- Implementation in Python
Introduction to SMTP and MIME
The application level protocol, Simple Mail Transfer Protocol (SMTP), handles message service over TCP/IP networks. It is limited to only 7 bit ASCII characters and hence do not support languages such as Arabic, Chinese, Korean, Japanese, etc. SMTP cannot used to transmit binary files such as vidoe, images and document files created by office productivity software.
Multipurpose Internet Mail Extensions (MIME) remove the limitation faced by SMTP. Email messages can support languages such as Arabic, Chinese, Korean, Japanese, etc. It is possible to attach video, images, and document files created by office productivity software in email messages.
The structure of a MIME is as follow type/subtype;parameter=value
. The type
refer to the category that the data represent in general, for example text
or video
. The subtype
provide more details with regards to the MIME type
represented. For example, for type
text, the subtext
could be plain
or html
. The parameter
is an optional value that can provide additional details, for example to attach a UTF-8 text file, one could specify the MIME as follow text/plain;charset=UTF-8
.
Putting it all together, if I attached an HTML document specifying the MIME type text/html
, this will allow the client software (web browser) to render it internally". If I attached a pdf file with the MIME type specified as application/pdf
, the client software will lauch the PDF Reader software that is installed and registered as the application/pdf handler.
Generate App password in Google
Go to myaccount.google.com/security, ensure that you have enabled 2-Step Verification.
Next click into the App passwords section to generate your password for our python script
Email config file setup
Create an email_config.py
file with the following
gmail_pass = "[this will be the App password you generated in the previous step]"
user = "[replace it with your gmail address, for example hello-world@gmail.com]"
host = "smtp.gmail.com"
port = 465
Difference between sending a text email vs sending an attachment
In order to send a text email, we will just need to attach the message body as MIMEText.
# attach nessage body as MIMEText
message.attach(MIMEText(body,'plain', 'utf-8'))
For sending an attachement in the email, we add the filename to the header and then attach the file to the email message.
# Add to header attachment filename
attachedfile.add_header('content-disposition', 'attachment', filename=file_to_open.name)
# Then attach to message attachment file
message.attach(attachedfile)
Example of an email header
Below is an example of how an email header would look like.
Return-Path: <redacted-info>
Received: from <redacted-info>
by mx.google.com with SMTP id <redacted-info>
for <redacted-info>;
Wed, 19 Jun 2021 10:09:38 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sendgrid.info; h=
content-type:mime-version:from:to:subject; s=smtpapi; bh=<redacted-info>=
Received: by <redacted-info> with SMTP id <redacted-info>
Wed, 19 Jun 2021 17:09:33 +0000 (UTC)
Content-Type: multipart/alternative;
MIME-Version: 1.0
From: redacted-address
To: redacted-address
Subject: Hello World
Message-ID: <redacted-info>
Date: Wed, 19 Jun 2021 17:09:33 +0000 (UTC)
Implementation in Python
Let's review the following code on how to use Python to send email in Gmail. We first need to import the following modules. smtplib
for sending emails using the Simple Mail Transfer Protocol (SMTP). pathlib
provides an object oriented approach to handling filesystem paths. email
for managing email messages. email_config
which is the email_config.py
file which we had created earlier.
import smtplib
from pathlib import Path
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
Thereafter we create a send_email_attach
function which take in four inputs. The email address to send to, the subject, the content (body) and the filename of the attachment(s) of the email message. The email to be sent is formatted in plain text
.
def send_email_attach(to, subject, body, files= None)):
# create message object
message = MIMEMultipart()
# add the header
message['From'] = Header(user)
message['To'] = Header(to)
message['Subject'] = Header(subject)
# attach nessage body as MIMEText
message.attach(MIMEText(body,'plain', 'utf-8'))
The pathlib
module that we import earlier provides an object oriented approach to handling filesystem paths. We will write a for
loop to go through the list of files that we wish to attach in the email. Here we will specify the path to the directory where our files are located. Using the with open
statement , the file is opened in binary format for reading. MIMEApplication
is used to handle the attachment of the file(s) in the email message.
# attach file(s)
data_folder = Path("data/")
for f in files or []:
file_to_open = data_folder / f
with open(file_to_open, "rb") as fil:
attachedfile = MIMEApplication(fil.read(), _subtype = file_to_open.suffix)
attachedfile.add_header(
'content-disposition', 'attachment', filename=file_to_open.name )
message.attach(attachedfile)
We had previously stored the host, port, user, gmail_pass
information in the email_config.py
file. At the beginning of our Python script, we had import these data which allow us to setup the email server below. With our email server setup , we are now ready to send the email.
# 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()
The below codes will request the user input for the recipient email address, subject, the content (body) and the list of filenames that the user want to attach in the email message . Once the input is received, the send_email_attach
function will be called and our email is sent in Gmail by our Python program.
print(f"Preparing to send email")
to = input("Recipient email address please ")
subject = input("Enter the subject of this email? ")
body = input("Type your email message here: ")
files = []
while True:
i = input("Enter name of the file you want to attach? Type Q to stop adding attachment ").rstrip()
if i.casefold() == 'q':
break
files.append(i)
send_email_attach(to, subject, body, files)
Here is the entire code block for reference
import smtplib
from pathlib import Path
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
def send_email_attach(to, subject, body, files= None):
# create message object
message = MIMEMultipart('mixed')
# add the header
message['From'] = Header(user)
message['To'] = Header(to)
message['Subject'] = Header(subject)
# attach nessage body as MIMEText
message.attach(MIMEText(body,'plain', 'utf-8'))
# attach file(s)
data_folder = Path("data/")
for f in files or []:
file_to_open = data_folder / f
with open(file_to_open, "rb") as fil:
attachedfile = MIMEApplication(fil.read(), _subtype = file_to_open.suffix)
attachedfile.add_header(
'content-disposition', 'attachment', filename=file_to_open.name )
message.attach(attachedfile)
# 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()
print(f"Preparing to send email")
to = input("Recipient email address please ")
subject = input("Enter the subject of this email? ")
body = input("Type your email message here: ")
files = []
while True:
i = input("Enter name of the file you want to attach? Type Q to stop adding attachment ").rstrip()
if i.casefold() == 'q':
break
files.append(i)
send_email_attach(to, subject, body, files)
With this article at OpenGenus, you must have the complete idea of using Python to send file/ attachment in Gmail .