How to send attachments with email using Python

Introduction

We have seen various examples on sending text email, RFC 822 standard email, HTML email but here we will see how to send attachments with email using Python 3. Attachments may be any type of files such as image, pdf, text etc. We will send email message over TLS and SSL ports using Gmail SMTP Server.

We are going to show you how to attach inline image as well as a pdf document. Inline means your image will be displayed in the message body itself. You may also attach an image as a normal attachment like other documents. We will use here email package from Python programming language.

Here we will read the image or pdf file from a directory and add as attachments. For web based message sending functionality you need to upload and add as an attachment.

Sometimes, sending only text message or HTML message does not fulfill the requirements of your purpose for sending message. Therefore, you need to send email message with attachments because it’s a convenient way to send a file or document to someone.

Prerequisites

Python 3.8.0, Gmail Security Settings, Gmail SMTP Server -smtp.gmail.com, Gmail Ports – 587, 465

Creating Python Script

We will create below Python script called html_email_attachments.py. You may choose any location to place this file. Make sure your Python is accessible from anywhere using command prompt.

import smtplib

from email.message import EmailMessage
from email.utils import make_msgid

msg = EmailMessage()

asparagus_cid = make_msgid()
msg.set_content('This is a text message')
msg.add_alternative("""\
<html>
  <head></head>
  <body>
    <p>Hello</p>
    <p>
		Here is an example of sending attachments in email using Python.        
    </p>
	<img src="cid:{asparagus_cid}" />
  </body>
</html>
""".format(asparagus_cid=asparagus_cid[1:-1]), subtype='html')

with open("sample.jpg", 'rb') as img:
	msg.get_payload()[1].add_related(img.read(), 'image', 'jpeg', cid=asparagus_cid)
	
with open("sample.pdf", 'rb') as fp:
	pdf_data = fp.read()
	ctype = 'application/octet-stream'
	maintype, subtype = ctype.split('/', 1)
	msg.add_attachment(pdf_data, maintype=maintype, subtype=subtype, filename='sample.pdf')

fromEmail = 'gmail@gmail.com'
toEmail = 'gmail@gmail.com'

msg['Subject'] = 'HTML message with attachments'
msg['From'] = fromEmail
msg['To'] = toEmail

s = smtplib.SMTP('smtp.gmail.com', 587)

s.starttls()

s.login(fromEmail, 'gmail password')
s.send_message(msg)
s.quit()

In the above Python script, we first import smtplib for sending the email.

In the next line we import email module for creating email message.

Related Posts:

Next we create the EmailMessage() object and set the body of the message using set-content() for text message and msg.add_alternative() for HTML message.

Notice we have <img src="" /> tag inside the HTML message. This is where we will insert the image as an inline attachment. The below code snippets read and add the as an inline attachment:

with open("sample.jpg", 'rb') as img:
	msg.get_payload()[1].add_related(img.read(), 'image', 'jpeg', cid=asparagus_cid)

Next we read pdf document and add as an attachment to the message:

with open("sample.pdf", 'rb') as fp:
	pdf_data = fp.read()
	ctype = 'application/octet-stream'
	maintype, subtype = ctype.split('/', 1)
	msg.add_attachment(pdf_data, maintype=maintype, subtype=subtype, filename='sample.pdf')

Then we set the subject for the email and we also set from and to email addresses to send and receive the email respectively.

Next we create a session using Gmail SMTP server – smtp.gmail.com and port – 587.

We need to issue STARTTLS command otherwise you will get the following error:

#smtplib.SMTPSenderRefused: (530, b'5.7.0 Must issue a STARTTLS command first. p7sm24605501pfn.14 - gsmtp', 'gmailaddress@gmail.com')

You will get below error if your security level is high in gmail settings:

#smtplib.SMTPAuthenticationError: (535, b'5.7.8 Username and Password not accepted. Learn more at\n5.7.8  https://support.google.com/mail/?p=BadCredentials x10sm26098036pfn.36 - gsmtp')

Therefore you need to lower your Gmail’s security settings to send email from your gmail address.

Using SSL Port 465

If you want to use SSL port 465 to establish the secure connection with Gmail SMTP server then do the following changes:

Replace s = smtplib.SMTP_SSL('smtp.gmail.com', 587) by s = smtplib.SMTP_SSL('smtp.gmail.com', 465).

Remove line s.starttls().

Testing the Email Sending

Just executing the file html_email_attachments.py using command line tool will send the email.

You will also see the pdf attachment in the below image. You won’t be able to see image attachment until you open the email message because it’s an inline attachment.

Once your email successfully sent you will see the following output in Gmail Inbox:

send attachments with email using python

As I have sent from my gmail address to my gmail address, so the from email address you see as me in the above image.

When you open the message you will see below output as shown in the image:

send attachments with email using python

Hovering mouse over sample.pdf file will give you option for download.

Source Code

Download

Thanks for reading.

Leave a Reply

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