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:
amazonses.py
from email.utils import COMMASPACE | |
from email.mime.multipart import MIMEMultipart | |
from email.mime.text import MIMEText | |
from boto.ses import SESConnection | |
from django.conf import settings | |
class SESMessage(object): | |
def __init__(self, source, to_addresses, subject, **kw): | |
self.ses = 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 self.ses: | |
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.ses.send_email(self._source, self.subject, | |
self.text or self.html, | |
self._to_addresses, self._cc_addresses, | |
self._bcc_addresses, | |
format='text' if self.text else 'html') | |
else: | |
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) | |
else: | |
message['To'] = self._to_addresses | |
message.attach(MIMEText(self.text, 'plain')) | |
message.attach(MIMEText(self.html, 'html')) | |
else: | |
raise NotImplementedError, 'Attachments are not currently supported.' | |
return self.ses.send_raw_email(message.as_string(), source=self._source, | |
destinations=self._to_addresses) |
You’ll also need to add your AWS access key and secret to your settings file:
settings.py
# Amazon AWS | |
AWS_ACCESS_KEY = 'AKIA……..' | |
AWS_SECRET_KEY = 'w71v……..' |
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 = 'recipient@site.com' | |
# 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('valid_sending_address@site.com', recipient, subject) | |
msg.text = rendered | |
msg.html = rendered + ' html' | |
msg.send() | |
messages.add_message(request, messages.INFO, 'Your contact enquiry was successfully sent. Thank you!') | |
return HttpResponseRedirect(reverse('contact')) | |
else: | |
form = ContactForm() | |
return render(request, 'contact.html', {'form': form}) |