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.

Reply via email to