In this tutorial, we are going to see how to send an email with attachment in Python using Amazon’s Boto library. In my current project I had an requirement to send a report in the email with attachment. I implemented it in Python. So I thought it will be good for my readers to learn how to send mail with attachment using Python.
Checkout my previous article on How to convert Text to Speech using Amazon Polly API
For that you must import some libraries of Python. In order to attach the file in the email content, you need to import the following libraries
- import boto3
- from botocore.exceptions import ClientError
- from email.mime.multipart import MIMEMultipart
- from email.mime.text import MIMEText
- from email.mime.application import MIMEApplication
- import urllib
- import os.path
Getting started with Boto 3 is easy, but requires a few steps. Install the latest Boto 3 release via pip:
pip install boto3
To use Boto 3, you must first import it and tell it what service you are going to use and A low-level client representing Amazon Simple Email Service (SES):
import boto3 client = boto3.client('ses')
In order to handle errors & exception in the email sending process, I would like import botocore.exceptions
from botocore.exceptions import ClientError
urllib library is used to download the content from the url. For python 3 users, please use urllib.request
To get the extension for the file url, I have used os.path library
extension = os.path.splitext(attachmentUrl)[1]
If a message has a multipart
Content-Type, that means it consists of multiple messages and each of them defines its own Content-Type (which can again be multipart or something else). Multipart messages are in Python represented by MIMEMultipart
class.
MIMEText is used to send either html email or plain text email
Contents
Sending Plain Text Email
part = MIMEText(body, 'plain')
Sending HTML Text Email
part = MIMEText(body, 'html')
Python code to Send an email with Attachment using AWS Boto
import boto3
from botocore.exceptions import ClientError
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.application import MIMEApplication
import urllib
import os.path
region = "AWS REGION"
sws_user = "AWS ACCESS KEY"
sws_key = "AWS SECRET KEY"
subject = 'Sending email with Attachment - W3lessons'
body = "Please find the attached content - Thanks, Team W3lessons"
client = boto3.client(service_name = 'ses', region_name = region, aws_access_key_id = sws_user, aws_secret_access_key = sws_key)
message = MIMEMultipart()
message['Subject'] = subject
message['From'] = "karthi@w3lessons.info"
message['To'] = "youremail@domain.com"
# message body
part = MIMEText(body, 'html')
message.attach(part)
attachmentUrl = "https://w3lessons.info/logo.png"
AttachementData = urllib.urlopen(attachmentUrl)
#get file extension
extension = os.path.splitext(attachmentUrl)[1]
txt = AttachementData.read()
fileName = "attachment"+extension
part = MIMEApplication(txt)
part.add_header('Content-Disposition', 'attachment', filename=fileName)
message.attach(part)
destination = { 'ToAddresses' : [message['To']], 'CcAddresses' : [], 'BccAddresses' : []}
try:
result = client.send_raw_email(Source = message['From'], Destinations = message['To'], RawMessage = {'Data': message.as_string(),})
return {'message': 'error','status' : 'fail'} if 'ErrorResponse' in result else {'message': 'mail sent successfully', 'status' : 'success'}
except ClientError as e:
return {'message': e.response['Error']['Message'],'status' : 'fail'}
Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above
`txt = AttachementData.read()`
Should be a new line here.
Why do you define `destinations` and not use it in the boto call?
You specify specific boto exceptions in your import statements and you don’t use them,
in your try/catch. Instead of e, don’t you think you should have `except botocore.exeception.ClientError as e:`?
I take back the last quibble, re-read the code!
Adding attachment from the remote url.. wow.. nice stuff