-
Notifications
You must be signed in to change notification settings - Fork 70
Django backend #57
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Django backend #57
Changes from all commits
c3a5400
fcc363c
ee99ba2
370e9a6
cdfd0de
afe157f
e75916a
ccf05a0
e8e389a
eb590c5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -62,3 +62,4 @@ venv/ | |
|
||
# Mac OSX | ||
.DS_Store | ||
.idea |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,3 +5,4 @@ requests==2.5.1 | |
responses==0.3.0 | ||
wheel | ||
twine | ||
Django>=1.8,<1.9 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
Django Email Backend | ||
==================== | ||
|
||
The SparkPost python library comes with an email backend for Django. | ||
|
||
Configure Django | ||
---------------- | ||
|
||
To configure Django to use SparkPost, put the following configuration in `settings.py` file. | ||
|
||
.. code-block:: python | ||
|
||
SPARKPOST_API_KEY = 'API_KEY' | ||
EMAIL_BACKEND = 'sparkpost.django.email_backend.SparkPostEmailBackend' | ||
|
||
Replace *API_KEY* with an actual API key. | ||
|
||
|
||
Sending an email | ||
---------------- | ||
|
||
Django is now configured to use the SparkPost email backend. You can now send mail using Django's `send_mail` method: | ||
|
||
.. code-block:: python | ||
|
||
from django.core.mail import send_mail | ||
|
||
send_mail( | ||
subject='hello from sparkpost', | ||
message='Hello Rock stars!' | ||
from_email='from@yourdomain.com', | ||
recipient_list=['to@friendsdomain.com'], | ||
html_message='<p>Hello Rock stars!</p>', | ||
) | ||
|
||
|
||
Supported version | ||
----------------- | ||
SparkPost will support all versions of Django that are within extended support period. Refer to `Django Supported_Version`_. | ||
|
||
Current supported versions are: | ||
* 1.7 | ||
* 1.8 | ||
* 1.9b1 | ||
|
||
|
||
.. _Django Supported_Version: https://www.djangoproject.com/download/#supported-versions | ||
|
||
|
||
Additional documentation | ||
------------------------ | ||
|
||
See our `Using SparkPost with Django`_ in support article. | ||
|
||
.. _Using SparkPost with Django: https://support.sparkpost.com/customer/en/portal/articles/2169630-using-sparkpost-with-django?b_id=7411 | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
from django.conf import settings | ||
from django.core.mail.backends.base import BaseEmailBackend | ||
|
||
from sparkpost import SparkPost | ||
|
||
from .exceptions import UnsupportedContent | ||
from .exceptions import UnsupportedParam | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. for imports let's follow this convention:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ya, I think that's a PEP8 recommendation too. I'll update it. |
||
|
||
class SparkPostEmailBackend(BaseEmailBackend): | ||
""" | ||
SparkPost wrapper for Django email backend | ||
""" | ||
|
||
def __init__(self, fail_silently=False, **kwargs): | ||
super(SparkPostEmailBackend, self)\ | ||
.__init__(fail_silently=fail_silently, **kwargs) | ||
|
||
sp_api_key = getattr(settings, 'SPARKPOST_API_KEY', None) | ||
|
||
self.client = SparkPost(sp_api_key) | ||
|
||
def send_messages(self, email_messages): | ||
""" | ||
Send emails, returns integer representing number of successful emails | ||
""" | ||
success = 0 | ||
for message in email_messages: | ||
try: | ||
response = self._send(message) | ||
success += response['total_accepted_recipients'] | ||
except Exception: | ||
if not self.fail_silently: | ||
raise | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. will this just pass the exception through? or do you need to explicitly pass the exception that was caught? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it'll re-throw the caught exception |
||
return success | ||
|
||
def _send(self, message): | ||
self.check_unsupported(message) | ||
self.check_attachments(message) | ||
|
||
params = dict( | ||
recipients=message.to, | ||
text=message.body, | ||
from_email=message.from_email, | ||
subject=message.subject | ||
) | ||
|
||
if hasattr(message, 'alternatives') and len(message.alternatives) > 0: | ||
for alternative in message.alternatives: | ||
|
||
if alternative[1] == 'text/html': | ||
params['html'] = alternative[0] | ||
else: | ||
raise UnsupportedContent( | ||
'Content type %s is not supported' % alternative[1] | ||
) | ||
|
||
return self.client.transmissions.send(**params) | ||
|
||
@staticmethod | ||
def check_attachments(message): | ||
if len(message.attachments): | ||
raise UnsupportedContent( | ||
'The SparkPost Django email backend does not ' | ||
'currently support attachment.' | ||
) | ||
|
||
@staticmethod | ||
def check_unsupported(message): | ||
unsupported_params = ['cc', 'bcc', 'reply_to'] | ||
for param in unsupported_params: | ||
if len(getattr(message, param, [])): | ||
raise UnsupportedParam( | ||
'The SparkPost Django email backend does not currently ' | ||
'support %s.' % param | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
class UnsupportedContent(Exception): | ||
pass | ||
|
||
|
||
class UnsupportedParam(Exception): | ||
pass |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rather than install and uninstall, can we just create a separate test-requirements.txt without Django in it and use that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we could do that but then we've to update documentation. i thought it's much easier. at least for now, until we introduce more other similar cases.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
how so? this is just for CI
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we can do this afterwards in a separate ticket - I think we can reduce the build times by doing this