Permalink
Browse files

Initial import from django-ses.

  • Loading branch information...
Greg Taylor
Greg Taylor committed Apr 13, 2011
0 parents commit cbf4d82bcbd09a7dc43d30833f220b462afdee23
Showing with 229 additions and 0 deletions.
  1. +8 −0 .gitignore
  2. +22 −0 LICENSE
  3. +4 −0 MANIFEST.in
  4. +71 −0 README.rst
  5. +2 −0 seacucumber/__init__.py
  6. +84 −0 seacucumber/backend.py
  7. +38 −0 setup.py
@@ -0,0 +1,8 @@
+*.pyc
+.project
+.settings
+.pydevproject
+build
+dist
+MANIFEST
+*.egg-info
22 LICENSE
@@ -0,0 +1,22 @@
+Copyright (c) 2011 Harry Marr and DUO Interactive, LLC
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,4 @@
+include AUTHORS
+include LICENSE
+include README.rst
+
@@ -0,0 +1,71 @@
+============
+Sea Cucumber
+============
+:Info: A Django email backend for Amazon Simple Email Service, backed by celery_
+:Author: DUO Interactive, LLC
+:Inspired by: Harry Marr's django-ses_.
+
+A bird's eye view
+=================
+Sea Cucumber is a mail backend for Django_. Instead of sending emails
+through a traditional SMTP mail server, Sea Cucumber routes email through
+Amazon Web Services' excellent Simple Email Service (SES_) via celery.
+
+Why SES instead of SMTP?
+========================
+Configuring, maintaining, and dealing with some complicated edge cases can be
+time-consuming. Sending emails with Sea Cucumber might be attractive to you if:
+
+* You don't want to maintain mail servers.
+* You are already deployed on EC2 (In-bound traffic to SES is free from EC2
+ instances). This is not a big deal either way, but is an additional perk if
+ you happen to be on AWS.
+* You need to send a high volume of email.
+* You don't want to have to worry about PTR records, Reverse DNS, email
+ whitelist/blacklist services.
+
+Getting going
+=============
+Assuming you've got Django_ and django-celery_ installed, you'll need
+Boto_ 2.0b4 or higher. Boto_ is a Python library that wraps the AWS API.
+
+You can do the following to install Boto_ 2.0b4 (we're using --upgrade here to
+make sure you get 2.0b4)::
+
+ pip install --upgrade boto
+
+Install Sea Cucumber::
+
+ pip install seacucumber
+
+Add the following to your settings.py::
+
+ EMAIL_BACKEND = 'seacucumber.backend.SESBackend'
+
+ # These are optional -- if they're set as environment variables they won't
+ # need to be set here as well
+ AWS_ACCESS_KEY_ID = 'YOUR-ACCESS-KEY-ID'
+ AWS_SECRET_ACCESS_KEY = 'YOUR-SECRET-ACCESS-KEY'
+
+Now, when you use ``django.core.mail.send_mail``, Simple Email Service will
+send the messages by default.
+
+Django Builtin-in Error Emails
+==============================
+
+If you'd like Django's `Builtin Email Error Reporting`_ to function properly
+(actually send working emails), you'll have to explicitly set the
+``SERVER_EMAIL`` setting to one of your SES-verified addresses. Otherwise, your
+error emails will all fail and you'll be blissfully unaware of a problem.
+
+*Note:* You will need to sign up for SES_ and verify any emails you're going
+to use in the `from_email` argument to `django.core.mail.send_email()`. Boto_
+has a `verify_email_address()` method: https://github.com/boto/boto/blob/master/boto/ses/connection.py
+
+.. _django-ses: https://github.com/hmarr/django-ses
+.. _django-celery: http://ask.github.com/django-celery/
+.. _celery: http://docs.celeryproject.org/en/v2.2.5/index.html
+.. _Builtin Email Error Reporting: http://docs.djangoproject.com/en/1.2/howto/error-reporting/
+.. _Django: http://djangoproject.com
+.. _Boto: http://boto.cloudhackers.com/
+.. _SES: http://aws.amazon.com/ses/
@@ -0,0 +1,2 @@
+# Major, minor
+VERSION = (1, 0)
@@ -0,0 +1,84 @@
+from django.core.mail.backends.base import BaseEmailBackend
+from django.conf import settings
+
+import threading
+
+from boto.ses import SESConnection
+
+class SESBackend(BaseEmailBackend):
+ """
+ A Django Email backend that uses Amazon's Simple Email Service.
+ """
+ def __init__(self, fail_silently=False, *args, **kwargs):
+ super(SESBackend, self).__init__(fail_silently=fail_silently, *args,
+ **kwargs)
+
+ self._access_key_id = getattr(settings, 'AWS_ACCESS_KEY_ID', None)
+ self._access_key = getattr(settings, 'AWS_SECRET_ACCESS_KEY', None)
+ self._api_endpoint = getattr(settings, 'AWS_SES_API_HOST',
+ SESConnection.DefaultHost)
+
+ self.connection = None
+
+ def open(self):
+ """Create a connection to the AWS API server. This can be reused for
+ sending multiple emails.
+ """
+ if self.connection:
+ return False
+
+ try:
+ self.connection = SESConnection(
+ aws_access_key_id=self._access_key_id,
+ aws_secret_access_key=self._access_key,
+ host=self._api_endpoint,
+ )
+ except:
+ if not self.fail_silently:
+ raise
+
+ def close(self):
+ """Close any open HTTP connections to the API server.
+ """
+ try:
+ self.connection.close()
+ self.connection = None
+ except:
+ if not self.fail_silently:
+ raise
+
+ def send_messages(self, email_messages):
+ """Sends one or more EmailMessage objects and returns the number of
+ email messages sent.
+ """
+ if not email_messages:
+ return
+
+ new_conn_created = self.open()
+ if not self.connection:
+ # Failed silently
+ return
+
+ num_sent = 0
+ for message in email_messages:
+ try:
+ response = self.connection.send_raw_email(
+ source=message.from_email,
+ destinations=message.recipients(),
+ raw_message=message.message().as_string(),
+ )
+ send_response = response['SendRawEmailResponse']
+ send_result = send_response['SendRawEmailResult']
+ message.extra_headers['Message-Id'] = send_result['MessageId']
+
+ num_sent += 1
+ except SESConnection.ResponseError:
+ if not self.fail_silently:
+ raise
+ pass
+
+ if new_conn_created:
+ self.close()
+
+ return num_sent
+
@@ -0,0 +1,38 @@
+from setuptools import setup, find_packages
+import os
+import seacucumber
+
+DESCRIPTION = "A Django email backend for Amazon Simple Email Service, backed by celery"
+
+LONG_DESCRIPTION = None
+try:
+ LONG_DESCRIPTION = open('README.rst').read()
+except:
+ pass
+
+version_str = '%d.%d' % (seacucumber.VERSION[0], seacucumber.VERSION[1])
+
+CLASSIFIERS = [
+ 'Development Status :: 4 - Beta',
+ 'Intended Audience :: Developers',
+ 'License :: OSI Approved :: MIT License',
+ 'Operating System :: OS Independent',
+ 'Programming Language :: Python',
+ 'Topic :: Software Development :: Libraries :: Python Modules',
+ 'Framework :: Django',
+]
+
+setup(
+ name='seacucumber',
+ version=version_str,
+ packages=['seacucumber'],
+ author='Gregory Taylor',
+ author_email='gtaylor@duointeractive.com',
+ url='https://github.com/duointeractive/sea-cucumber/',
+ license='MIT',
+ description=DESCRIPTION,
+ long_description=LONG_DESCRIPTION,
+ platforms=['any'],
+ classifiers=CLASSIFIERS,
+ install_requires=['boto'],
+)

0 comments on commit cbf4d82

Please sign in to comment.