Sending Django Emails via AWS SES

Boto is the de facto standard for working with the AWS API from Python. Unfortunately their SES implementation only sends text or html emails, not both. You need to drop down to their send_raw_email method to send a multi-part email.

Using this Gist as a guideline, here’s an implementation of sending a multi-part email via a library class:

from email.utils import COMMASPACE
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from import SESConnection
from django.conf import settings
class SESMessage(object):
def __init__(self, source, to_addresses, subject, **kw): = SESConnection(settings.AWS_ACCESS_KEY, settings.AWS_SECRET_KEY)
self._source = source
self._to_addresses = to_addresses
self._cc_addresses = None
self._bcc_addresses = None
self.subject = subject
self.text = None
self.html = None
self.attachments = []
def send(self):
if not
raise Exception, 'No connection found'
if (self.text and not self.html and not self.attachments) or\
(self.html and not self.text and not self.attachments):
return, self.subject,
self.text or self.html,
self._to_addresses, self._cc_addresses,
format='text' if self.text else 'html')
if not self.attachments:
message = MIMEMultipart('alternative')
message['Subject'] = self.subject
message['From'] = self._source
if isinstance(self._to_addresses, (list, tuple)):
message['To'] = COMMASPACE.join(self._to_addresses)
message['To'] = self._to_addresses
message.attach(MIMEText(self.text, 'plain'))
message.attach(MIMEText(self.html, 'html'))
raise NotImplementedError, 'Attachments are not currently supported.'
return, source=self._source,

view raw
hosted with ❤ by GitHub

You’ll also need to add your AWS access key and secret to your settings file:

# Amazon AWS
AWS_SECRET_KEY = 'w71v……..'

view raw
hosted with ❤ by GitHub

You can then use the class like this:

from app.lib.amazonses import SESMessage
def contact(request):
if request.method == 'POST':
form = ContactForm(request.POST)
if form.is_valid():
# grab the form data
name = form.cleaned_data['name']
email = form.cleaned_data['email']
subject = form.cleaned_data['subject']
body = form.cleaned_data['body']
recipient = ''
# render the template with the submitted data
rendered = render_to_string('email/contact.html', {'name': name, 'email': email, 'subject': subject, 'body': body})
# create the message and send the email
# the from address must be a verified sender in SES
msg = SESMessage('', recipient, subject)
msg.text = rendered
msg.html = rendered + ' html'
messages.add_message(request, messages.INFO, 'Your contact enquiry was successfully sent. Thank you!')
return HttpResponseRedirect(reverse('contact'))
form = ContactForm()
return render(request, 'contact.html', {'form': form})

view raw
hosted with ❤ by GitHub