Пример кода здесь для отправки сырой электронной почты SES с использованием составного тела (обычный / html / attachment):
from email.mime.text import MIMEText
from email.mime.application import MIMEApplication
from email.mime.multipart import MIMEMultipart
from google.appengine.api import urlfetch
from google.appengine.runtime import DeadlineExceededError
import urllib
import hmac
import base64
import hashlib
from datetime import datetime
import logging
def ses_multi_part(msg_subject, msg_to, msg_body='', msg_cc=None, msg_bcc=None, file_name=None, file_reader=None,
msg_type='plain', msg_from='noreply@....', msg_reply_to='contact@....'):
""" send an html or plain e-mail. Use file_name and file_reader to pass an attachment
inspiration: https://codeadict.wordpress.com/2010/02/11/send-e-mails-with-attachment-in-python/
"""
msg = MIMEMultipart()
msg.set_charset("utf-8")
msg['Subject'] = msg_subject
msg['From'] = msg_from
msg['Reply-to'] = msg_reply_to
msg['To'] = msg_to
if msg_cc:
msg['Cc'] = msg_cc
if msg_bcc:
msg['Bcc'] = msg_bcc
logging.debug(msg)
msg.preamble = 'Multipart massage.\n'
part = MIMEText(msg_body, msg_type, "utf-8")
msg.attach(part)
if file_name:
part = MIMEApplication(file_reader.read())
part.add_header('Content-Disposition', 'attachment', filename=file_name)
msg.attach(part)
return msg.as_string()
class SES(object):
""" SES send RAW e-mail
inspiration: https://github.com/richieforeman/python-amazon-ses-api/blob/master/amazon_ses.py
"""
def __init__(self, accessKeyID, secretAccessKey, return_path='contact@....'):
self._accessKeyID = accessKeyID
self._secretAccessKey = secretAccessKey
self.ses_return_path = return_path
def _getSignature(self, dateValue):
h = hmac.new(key=self._secretAccessKey, msg=dateValue, digestmod=hashlib.sha256)
return base64.b64encode(h.digest()).decode()
def _getHeaders(self):
headers = {'Content-type': 'application/x-www-form-urlencoded', 'Return-Path': self.ses_return_path}
d = datetime.utcnow()
dateValue = d.strftime('%a, %d %b %Y %H:%M:%S GMT')
headers['Date'] = dateValue
signature = self._getSignature(dateValue)
headers['X-Amzn-Authorization'] = 'AWS3-HTTPS AWSAccessKeyId=%s, Algorithm=HMACSHA256, Signature=%s' % (self._accessKeyID, signature)
return headers
def _performAction(self, actionName, params=None):
if not params:
params = {}
params['Action'] = actionName
response = None
#https://email.us-east-1.amazonaws.com/
retry = 0 # download error retry
while retry <= 1: # dan een eenmalige 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 += 1
continue # retry
else:
logging.warning('fetcherror' + str(e))
raise # bij een dubbele fout stoppen
if response.status_code != 200:
logging.warning(response.headers)
logging.warning(response.content)
raise ValueError('status_code : %s' % (str(response.status_code)))
logging.debug(response.content)
return response.content
def sendRawEmail(self, raw_msg_data):
return self._performAction("SendRawEmail", params={"RawMessage.Data": base64.b64encode(raw_msg_data)})
Пример использования:
ses = SES(settings.AMAZON_ACCESS_KEY_ID, settings.AMAZON_SECRET_ACCESS_KEY, settings.SES_RETURN_PATH[country])
raw_msg_data = ses_multi_part(msg_subject=subject.encode('utf-8'), msg_to=mail_to, msg_body=body_text.encode('utf-8'),
msg_bcc=settings.MAIL_BCC, msg_reply_to=reply_to, msg_from=sender, msg_type=msg_type)
ses.sendRawEmail(raw_msg_data)