I have SES up and running making use of this python 2.6 SES API.
https://github.com/pankratiev/python-amazon-ses-api
As you said, this is working fine. And I'am now able to handle bounced
e-mail messages with Return-Path.
To use this API for GAE Python 2.5 I had to make some changes by overriding
two methods. Here is the code for sending e-mails.
To make the code even more reliable, reviews are welcome. This is my first
experience with Amazon services.
#!/usr/bin/python
# -*- coding: utf-8 -*-
from my_settings import AMAZON_ACCESS_KEY_ID, AMAZON_SECRET_ACCESS_KEY
from amazon_ses import AmazonSES, EmailMessage
from google.appengine.api import urlfetch
from google.appengine.runtime import DeadlineExceededError
import urllib, logging
class gaeAmazonSES(AmazonSES):
# make the API work for GAE python 2.5
def _performAction(self, actionName, params=None):
if not params:
params = {}
params['Action'] = actionName
#https://email.us-east-1.amazonaws.com/
reason = ''
# exception
retry = 0
# download error retry
while retry <= 1 :
# a one time retry
try :
url = 'https://email.us-east-1.amazonaws.com'
response = urlfetch.fetch(url=url,
payload=urllib.urlencode(params), method=urlfetch.POST,
headers=self._getHeaders())
break
except (urlfetch.DownloadError, DeadlineExceededError),e :
logging.debug('Amazon SES download or deadline error : %d'
%(retry + 1))
if retry == 0 :
retry = retry + 1
continue
# retry
else :
reason = e
break
if reason == '' :
# check for fetch errors
responseResult = response.content
status_code = response.status_code
logging.debug(response.headers)
else :
responseResult = None
status_code = -1
result = self._responseParser.parse(actionName, status_code,
reason, responseResult)
logging.debug(result)
return result
def sendEmail(self, source, toAddresses, message,
replyToAddresses=None, returnPath=None, ccAddresses=None,
bccAddresses=None):
params = { 'Source': source }
if not replyToAddresses : replyToAddresses = [source,]
# always reply_to
for objName, addresses in zip(["ToAddresses", "CcAddresses",
"BccAddresses", "ReplyToAddresses" ],
[toAddresses, ccAddresses,
bccAddresses, replyToAddresses]):
if addresses:
if not isinstance(addresses, basestring) and
getattr(addresses, '__iter__', False):
for i, address in enumerate(addresses):
if objName == 'ReplyToAddresses' :
# reply_to
params['ReplyToAddresses.member.%d' %(i + 1)] =
address
else :
# destination
params['Destination.%s.member.%d' % (objName, i
+ 1)] = address
else:
if objName == 'ReplyToAddresses' :
params['ReplyToAddresses.member.1'] = addresses
else :
params['Destination.%s.member.1' % objName] =
addresses
if not returnPath:
returnPath = source
params['ReturnPath'] = returnPath
params['Message.Subject.Charset'] = message.charset
params['Message.Subject.Data'] = message.subject.encode('utf-8')
if message.bodyText:
params['Message.Body.Text.Charset'] = message.charset
params['Message.Body.Text.Data'] =
message.bodyText.encode('utf-8')
if message.bodyHtml:
params['Message.Body.Html.Charset'] = message.charset
params['Message.Body.Html.Data'] =
message.bodyHtml.encode('utf-8')
logging.debug(params)
return self._performAction('SendEmail', params)
def sesMail(sender, mail_to, subject, body_text, reply_to=None, bcc=None):
amazonSes = gaeAmazonSES(AMAZON_ACCESS_KEY_ID, AMAZON_SECRET_ACCESS_KEY)
message = EmailMessage()
message.subject = subject
message.bodyText = body_text
result = amazonSes.sendEmail(sender, mail_to, message, reply_to,
'return path@ mydomain.com', None, bcc)
logging.debug(result)
--
You received this message because you are subscribed to the Google Groups
"Google App Engine" group.
To view this discussion on the web visit
https://groups.google.com/d/msg/google-appengine/-/3udAOhcOB6oJ.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/google-appengine?hl=en.