Giter Site home page Giter Site logo

django-ses / django-ses Goto Github PK

View Code? Open in Web Editor NEW
973.0 973.0 222.0 556 KB

A Django email backend for Amazon's Simple Email Service

Home Page: http://hmarr.com/2011/jan/26/using-amazons-simple-email-service-ses-with-django/

License: MIT License

Python 94.88% HTML 5.12%

django-ses's Introduction

Django-SES

Info

A Django email backend for Amazon's Simple Email Service

Author

Harry Marr (http://github.com/hmarr, http://twitter.com/harrymarr)

Collaborators

Paul Craciunoiu (http://github.com/pcraciunoiu, http://twitter.com/embrangler)

pypi pypi-downloads build python django

A bird's eye view

Django-SES is a drop-in mail backend for Django. Instead of sending emails through a traditional SMTP mail server, Django-SES routes email through Amazon Web Services' excellent Simple Email Service (SES).

Please Contribute!

This project is maintained, but not actively used by the maintainer. Interested in helping maintain this project? Reach out via GitHub Issues if you're actively using django-ses and would be interested in contributing to it.

Changelog

For details about each release, see the GitHub releases page: https://github.com/django-ses/django-ses/releases or CHANGES.md.

Using Django directly

Amazon SES allows you to also setup usernames and passwords. If you do configure things that way, you do not need this package. The Django default email backend is capable of authenticating with Amazon SES and correctly sending email.

Using django-ses gives you additional features like deliverability reports that can be hard and/or cumbersome to obtain when using the SMTP interface.

Why SES instead of SMTP?

Configuring, maintaining, and dealing with some complicated edge cases can be time-consuming. Sending emails with Django-SES 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).
  • 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.
  • You want to improve delivery rate and inbox cosmetics by DKIM signing your messages using SES's Easy DKIM feature.
  • Django-SES is a truely drop-in replacement for the default mail backend. Your code should require no changes.

Getting going

Assuming you've got Django installed, you'll just need to install django-ses:

pip install django-ses

To receive bounces or webhook events install the events "extra":

pip install django-ses[events]

Add the following to your settings.py:

EMAIL_BACKEND = 'django_ses.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'

# Additionally, if you are not using the default AWS region of us-east-1,
# you need to specify a region, like so:
AWS_SES_REGION_NAME = 'us-west-2'
AWS_SES_REGION_ENDPOINT = 'email.us-west-2.amazonaws.com'

# If you want to use the SESv2 client
USE_SES_V2 = True

Alternatively, instead of AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY, you can include the following two settings values. This is useful in situations where you would like to use a separate access key to send emails via SES than you would to upload files via S3:

AWS_SES_ACCESS_KEY_ID = 'YOUR-ACCESS-KEY-ID'
AWS_SES_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.

Since SES imposes a rate limit and will reject emails after the limit has been reached, django-ses will attempt to conform to the rate limit by querying the API for your current limit and then sending no more than that number of messages in a two-second period (which is half of the rate limit, just to be sure to stay clear of the limit). This is controlled by the following setting:

AWS_SES_AUTO_THROTTLE = 0.5 # (default; safety factor applied to rate limit)

To turn off automatic throttling, set this to None.

Check out the example directory for more information.

Monitoring email status using Amazon Simple Notification Service (Amazon SNS)

To set this up, install django-ses with the events extra:

pip install django-ses[events]

Then add a event url handler in your `urls.py`:

from django_ses.views import SESEventWebhookView
from django.views.decorators.csrf import csrf_exempt
urlpatterns = [ ...
                url(r'^ses/event-webhook/$', SESEventWebhookView.as_view(), name='handle-event-webhook'),
                ...
]

SESEventWebhookView handles bounce, complaint, send, delivery, open and click events. It is also capable of auto confirming subscriptions, it handles SubscriptionConfirmation notification.

On AWS

  1. Add an SNS topic.

2. In SES setup an SNS destination in "Configuration Sets". Use this configuration set by setting AWS_SES_CONFIGURATION_SET. Set the topic to what you created in 1.

3. Add an https subscriber to the topic. (eg. https://www.yourdomain.com/ses/event-webhook/) Do not check "Enable raw message delivery".

Bounces

Using signal 'bounce_received' for manager bounce email. For example:

from django_ses.signals import bounce_received
from django.dispatch import receiver


@receiver(bounce_received)
def bounce_handler(sender, mail_obj, bounce_obj, raw_message, *args, **kwargs):
    # you can then use the message ID and/or recipient_list(email address) to identify any problematic email messages that you have sent
    message_id = mail_obj['messageId']
    recipient_list = mail_obj['destination']
    ...
    print("This is bounce email object")
    print(mail_obj)

Complaint

Using signal 'complaint_received' for manager complaint email. For example:

from django_ses.signals import complaint_received
from django.dispatch import receiver


@receiver(complaint_received)
def complaint_handler(sender, mail_obj, complaint_obj, raw_message,  *args, **kwargs):
    ...

Send

Using signal 'send_received' for manager send email. For example:

from django_ses.signals import send_received
from django.dispatch import receiver


@receiver(send_received)
def send_handler(sender, mail_obj, raw_message,  *args, **kwargs):
    ...

Delivery

Using signal 'delivery_received' for manager delivery email. For example:

from django_ses.signals import delivery_received
from django.dispatch import receiver


@receiver(delivery_received)
def delivery_handler(sender, mail_obj, delivery_obj, raw_message,  *args, **kwargs):
    ...

Open

Using signal 'open_received' for manager open email. For example:

from django_ses.signals import open_received
from django.dispatch import receiver


@receiver(open_received)
def open_handler(sender, mail_obj, raw_message, *args, **kwargs):
    ...

Click

Using signal 'click_received' for manager send email. For example:

from django_ses.signals import click_received
from django.dispatch import receiver


@receiver(click_received)
def click_handler(sender, mail_obj, raw_message, *args, **kwargs):
    ...

Testing Signals

If you would like to test your signals, you can optionally disable AWS_SES_VERIFY_EVENT_SIGNATURES in settings. Examples for the JSON object AWS SNS sends can be found here: https://docs.aws.amazon.com/sns/latest/dg/sns-message-and-json-formats.html#http-subscription-confirmation-json

SES Event Monitoring with Configuration Sets

You can track your SES email sending at a granular level using SES Event Publishing. To do this, you set up an SES Configuration Set and add event handlers to it to send your events on to a destination within AWS (SNS, Cloudwatch or Kinesis Firehose) for further processing and analysis.

To ensure that emails you send via django-ses will be tagged with your SES Configuration Set, set the AWS_SES_CONFIGURATION_SET setting in your settings.py to the name of the configuration set:

AWS_SES_CONFIGURATION_SET = 'my-configuration-set-name'

This will add the X-SES-CONFIGURATION-SET header to all your outgoing e-mails.

If you want to set the SES Configuration Set on a per message basis, set AWS_SES_CONFIGURATION_SET to a callable. The callable should conform to the following prototype:

def ses_configuration_set(message, dkim_domain=None, dkim_key=None,
                            dkim_selector=None, dkim_headers=()):
    configuration_set = 'my-default-set'
    # use message and dkim_* to modify configuration_set
    return configuration_set

AWS_SES_CONFIGURATION_SET = ses_configuration_set

where

  • message is a django.core.mail.EmailMessage object (or subclass)
  • dkim_domain is a string containing the DKIM domain for this message
  • dkim_key is a string containing the DKIM private key for this message
  • dkim_selector is a string containing the DKIM selector (see DKIM, below for explanation)
  • dkim_headers is a list of strings containing the names of the headers to be DKIM signed (see DKIM, below for explanation)

DKIM

Using DomainKeys is entirely optional, however it is recommended by Amazon for authenticating your email address and improving delivery success rate. See http://docs.amazonwebservices.com/ses/latest/DeveloperGuide/DKIM.html. Besides authentication, you might also want to consider using DKIM in order to remove the via email-bounces.amazonses.com message shown to gmail users -see http://support.google.com/mail/bin/answer.py?hl=en&answer=1311182.

Currently there are two methods to use DKIM with Django-SES: traditional Manual Signing and the more recently introduced Amazon Easy DKIM feature.

Easy DKIM

Easy DKIM is a feature of Amazon SES that automatically signs every message that you send from a verified email address or domain with a DKIM signature.

You can enable Easy DKIM in the AWS Management Console for SES. There you can also add the required domain verification and DKIM records to Route 53 (or copy them to your alternate DNS).

Once enabled and verified Easy DKIM needs no additional dependencies or DKIM specific settings to work with Django-SES.

For more information and a setup guide see: http://docs.aws.amazon.com/ses/latest/DeveloperGuide/easy-dkim.html

Manual DKIM Signing

To enable Manual DKIM Signing you should install the pydkim package and specify values for the DKIM_PRIVATE_KEY and DKIM_DOMAIN settings. You can generate a private key with a command such as openssl genrsa 512 and get the public key portion with openssl rsa -pubout <private.key. The public key should be published to ses._domainkey.example.com if your domain is example.com. You can use a different name instead of ses by changing the DKIM_SELECTOR setting.

The SES relay will modify email headers such as Date and Message-Id so by default only the From, To, Cc, Subject headers are signed, not the full set of headers. This is sufficient for most DKIM validators but can be overridden with the DKIM_HEADERS setting.

Example settings.py:

DKIM_DOMAIN = 'example.com'
DKIM_PRIVATE_KEY = '''
-----BEGIN RSA PRIVATE KEY-----
xxxxxxxxxxx
-----END RSA PRIVATE KEY-----
'''

Example DNS record published to Route53 with boto:

route53 add_record ZONEID ses._domainkey.example.com. TXT '"v=DKIM1; p=xxx"' 86400

Identity Owners

With Identity owners, you can use validated SES-domains across multiple accounts: https://docs.aws.amazon.com/ses/latest/DeveloperGuide/sending-authorization-delegate-sender-tasks-email.html

This is useful if you got multiple environments in different accounts and still want to send mails via the same domain.

You can configure the following environment variables to use them as described in boto3-docs:

AWS_SES_SOURCE_ARN=arn:aws:ses:eu-central-1:012345678910:identity/example.com
AWS_SES_FROM_ARN=arn:aws:ses:eu-central-1:012345678910:identity/example.com
AWS_SES_RETURN_PATH_ARN=arn:aws:ses:eu-central-1:012345678910:identity/example.com

SES Sending Stats

Django SES comes with two ways of viewing sending statistics.

The first one is a simple read-only report on your 24 hour sending quota, verified email addresses and bi-weekly sending statistics.

To enable the dashboard to retrieve data from AWS, you need to update the IAM policy by adding the following actions:

{
    "Effect": "Allow",
    "Action": [
        "ses:ListVerifiedEmailAddresses",
        "ses:GetSendStatistics"
    ],
    "Resource": "*"
}

To generate and view SES sending statistics reports, include, update INSTALLED_APPS:

INSTALLED_APPS = (
    # ...
    'django.contrib.admin',
    'django_ses',
    # ...
)

... and urls.py:

urlpatterns += (url(r'^admin/django-ses/', include('django_ses.urls')),)

Optional enhancements to stats:

Override the dashboard view

You can override the Dashboard view, for example, to add more context data:

class CustomSESDashboardView(DashboardView):
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context.update(**admin.site.each_context(self.request))
        return context

Then update your urls:

urlpatterns += path('admin/django-ses/', CustomSESDashboardView.as_view(), name='django_ses_stats'),

You can use adminplus for this (https://github.com/jsocol/django-adminplus):

from django_ses.views import DashboardView
admin.site.register_view('django-ses', DashboardView.as_view(), 'Django SES Stats')

Store daily stats

If you need to keep send statistics around for longer than two weeks, django-ses also comes with a model that lets you store these. To use this feature you'll need to run:

python manage.py migrate

To collect the statistics, run the get_ses_statistics management command (refer to next section for details). After running this command the statistics will be viewable via /admin/django_ses/.

Django SES Management Commands

To use these you must include django_ses in your INSTALLED_APPS.

Managing Verified Email Addresses

Manage verified email addresses through the management command.

python manage.py ses_email_address --list

Add emails to the verified email list through:

python manage.py ses_email_address --add [email protected]

Remove emails from the verified email list through:

python manage.py ses_email_address --delete [email protected]

You can toggle the console output through setting the verbosity level.

python manage.py ses_email_address --list --verbosity 0

Collecting Sending Statistics

To collect and store SES sending statistics in the database, run:

python manage.py get_ses_statistics

Sending statistics are aggregated daily (UTC time). Stats for the latest day (when you run the command) may be inaccurate if run before end of day (UTC). If you want to keep your statistics up to date, setup cron to run this command a short time after midnight (UTC) daily.

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

Requirements

django-ses requires supported version of Django or Python.

Full List of Settings

AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY

Required. Your API keys for Amazon SES.

AWS_SES_ACCESS_KEY_ID, AWS_SES_SECRET_ACCESS_KEY

Required. Alternative API keys for Amazon SES. This is useful in situations where you would like to use separate access keys for different AWS services.

AWS_SES_SESSION_TOKEN, AWS_SES_SECRET_ACCESS_KEY

Optional. Use AWS_SES_SESSION_TOKEN to provide session token when temporary credentials are used. Details: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp.html https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_use-resources.html

AWS_SES_REGION_NAME, AWS_SES_REGION_ENDPOINT

Optionally specify what region your SES service is using. Note that this is required if your SES service is not using us-east-1, as omitting these settings implies this region. Details: http://readthedocs.org/docs/boto/en/latest/ref/ses.html#boto.ses.regions http://docs.aws.amazon.com/general/latest/gr/rande.html

USE_SES_V2

Optional. If you want to use client v2, you'll need to add USE_SES_V2=True. Some settings will need this flag enabled. See https://boto3.amazonaws.com/v1/documentation/api/1.26.31/reference/services/sesv2.html#id87

AWS_SES_FROM_EMAIL

Optional. The email address to be used as the "From" address for the email. The address that you specify has to be verified. For more information please refer to https://boto3.amazonaws.com/v1/documentation/api/1.26.31/reference/services/sesv2.html#SESV2.Client.send_email

AWS_SES_RETURN_PATH

Optional. Use AWS_SES_RETURN_PATH to receive complaint notifications You must use the v2 client by setting USE_SES_V2=True for this setting to work, otherwise it is ignored. https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_SendEmail.html#API_SendEmail_RequestSyntax

AWS_SES_CONFIGURATION_SET

Optional. Use this to mark your e-mails as from being from a particular SES Configuration Set. Set this to a string if you want all messages to have the same configuration set. Set this to a callable if you want to set configuration set on a per message basis.

TIME_ZONE

Default Django setting, optionally set this. Details: https://docs.djangoproject.com/en/dev/ref/settings/#time-zone

DKIM_DOMAIN, DKIM_PRIVATE_KEY

Optional. If these settings are defined and the pydkim module is installed then email messages will be signed with the specified key. You will also need to publish your public key on DNS; the selector is set to ses by default. See http://dkim.org/ for further detail.

AWS_SES_SOURCE_ARN

Instruct Amazon SES to use a domain from another account. For more information please refer to https://docs.aws.amazon.com/ses/latest/DeveloperGuide/sending-authorization-delegate-sender-tasks-email.html

AWS_SES_FROM_ARN

Instruct Amazon SES to use a domain from another account. For more information please refer to https://docs.aws.amazon.com/ses/latest/DeveloperGuide/sending-authorization-delegate-sender-tasks-email.html

AWS_SES_RETURN_PATH_ARN

Instruct Amazon SES to use a domain from another account. For more information please refer to https://docs.aws.amazon.com/ses/latest/DeveloperGuide/sending-authorization-delegate-sender-tasks-email.html

AWS_SES_VERIFY_EVENT_SIGNATURES, AWS_SES_VERIFY_BOUNCE_SIGNATURES

Optional. Default is True. Verify the contents of the message by matching the signature you recreated from the message contents with the signature that Amazon SNS sent with the message. See https://docs.aws.amazon.com/sns/latest/dg/sns-verify-signature-of-message.html for further detail.

EVENT_CERT_DOMAINS, BOUNCE_CERT_DOMAINS

Optional. Default is 'amazonaws.com' and 'amazon.com'.

Proxy

If you are using a proxy, please enable it via the env variables.

If your proxy server does not have a password try the following:

import os
os.environ["HTTP_PROXY"] = "http://proxy.com:port"
os.environ["HTTPS_PROXY"] = "https://proxy.com:port"

if your proxy server has a password try the following:

import os
os.environ["HTTP_PROXY"] = "http://user:[email protected]:port"
os.environ["HTTPS_PROXY"] = "https://user:[email protected]:port"

Source: https://stackoverflow.com/a/33501223/1331671

Contributing

If you'd like to fix a bug, add a feature, etc

  1. Start by opening an issue.

    Be explicit so that project collaborators can understand and reproduce the issue, or decide whether the feature falls within the project's goals. Code examples can be useful, too.

  2. File a pull request.

    You may write a prototype or suggested fix.

  3. Check your code for errors, complaints.

    Use check.py

  4. Write and run tests.

    Write your own test showing the issue has been resolved, or the feature works as intended.

Git hooks (via pre-commit)

We use pre-push hooks to ensure that only linted code reaches our remote repository and pipelines aren't triggered in vain.

To enable the configured pre-push hooks, you need to [install](https://pre-commit.com/) pre-commit and run once:

pre-commit install -t pre-push -t pre-commit --install-hooks

This will permanently install the git hooks for both, frontend and backend, in your local [.git/hooks](./.git/hooks) folder. The hooks are configured in the [.pre-commit-config.yaml](.pre-commit-config.yaml).

You can check whether hooks work as intended using the [run](https://pre-commit.com/#pre-commit-run) command:

pre-commit run [hook-id] [options]

Example: run single hook:

pre-commit run ruff --all-files --hook-stage push

Example: run all hooks of pre-push stage:

pre-commit run --all-files --hook-stage push

Running Tests

To run the tests:

python runtests.py

If you want to debug the tests, just add this file as a python script to your IDE run configuration.

Creating a Release

To create a release:

  • Run poetry version {patch|minor|major} as explained in the docs. This will update the version in pyproject.toml.
  • Commit that change and use git to tag that commit with a version that matches the pattern v*.*.*.
  • Push the tag and the commit (note some IDEs don't push tags by default).

django-ses's People

Contributors

adamchainz avatar agsimmons avatar dependabot[bot] avatar dlo avatar dsanders11 avatar ericmillsio avatar gitron avatar hmarr avatar ianlewis avatar jdufresne avatar jleclanche avatar ksze avatar mdw123 avatar michaelhelmick avatar mikob avatar mlissner avatar ondrarehounek avatar paulegan avatar pcraciunoiu avatar peidrao avatar quodlibetor avatar rozza avatar selwin avatar sevdog avatar ticosax avatar timgraham avatar troygrosfield avatar tswicegood avatar whyscream avatar winhamwr avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

django-ses's Issues

PyPI v0.2 and Github tag v0.2 don't match

I'm going to roll a v0.3 release once I can verify that the tests do indeed pass, but want to bring it up that the tag was made in January by the package on PyPI was created last November.

Document how to setup SES dashboard

Currently there's no documentation on how to setup the dashboard view.

EDIT: Sorry but I mean better documentation like example of how it should be done in urls.py

PyPi Release

I've seen this mentioned in a few other places, but I though I'd raise a specific issue for it. Could a PyPi release be done for the project? I'm currently pulling in from GitHub in order to get Python 3 support.

Am I right in thinking @pcraciunoiu has permission to do this?

Email address is not verified - SQL Database and Amazon SES error

Hi,

I am trying to configure SQL Database mail through Amazon Simple Email Service. I have verified the email address. The "To", "From" and "Reply To" email addresses are the same mail address which i have verified.

This is the log message i receive when i try to test mail through database mail. I have already verified the email addresses in management console. Also both the "From" address and "To" address are the same verified email address.

Date 8/21/2012 12:25:18 PM
Log Database Mail (Database Mail Log)

Log ID 102
Process ID 2952
Mail Item ID 28
Last Modified 8/21/2012 12:25:18 PM
Last Modified By sa

Message
The mail could not be sent to the recipients because of the mail server failure. (Sending Mail using Account 2 (2012-08-21T12:25:18). Exception Message: Cannot send mails to mail server. (Transaction failed. The server response was: Message rejected: Email address is not verified.).
)

Documentation Update required

Hi

Can you also please update the documentation that django-ses has a built-in endpoint for amazon SNS notifications

Thanks
Bala

Support for Django 1.8

Does this support Django 1.8. I have not seen anything related to that. Do you have any plans to add the support, if yes when it will be up.
Thanks.

Unable to send out emails getting <unknown>:1:0: syntax error

am firing up a celery task that sends out emails to users, the task though is failing to send and below is the console output

[2012-11-13 11:45:28,103: DEBUG/MainProcess] Method: POST
[2012-11-13 11:45:28,107: DEBUG/MainProcess] Path: /
[2012-11-13 11:45:28,107: DEBUG/MainProcess] Data: Action=GetSendQuota
[2012-11-13 11:45:28,107: DEBUG/MainProcess] Headers: {'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'}
[2012-11-13 11:45:28,109: DEBUG/MainProcess] Host: email-smtp.us-east-1.amazonaws.com
[2012-11-13 11:45:28,109: DEBUG/MainProcess] establishing HTTPS connection: host=email-smtp.us-east-1.amazonaws.com, kwargs={}
[2012-11-13 11:45:28,109: DEBUG/MainProcess] Token: None
[2012-11-13 11:45:28,702: DEBUG/MainProcess] wrapping ssl socket; CA certificate file=/home/mo/projects/garageenv/local/lib/python2.7/site-packages/boto/cacerts/cacerts.txt
[2012-11-13 11:45:29,385: DEBUG/MainProcess] validating server certificate: hostname=email-smtp.us-east-1.amazonaws.com, certificate hosts=[u'email-smtp.us-east-1.amazonaws.com']
[2012-11-13 11:45:39,618: ERROR/MainProcess] :1:0: syntax error

Clarify documentation for use with built-in views

It may be helpful to note in the documentation that DEFAULT_FROM_EMAIL should be explicitly set in your settings.py if you want to take advantage of built-in views that send mail. It's a PITA gotcha.

Passing profile_name into SESConnection

Would be nice to be able to pass profile_name into SESConnection, such that multiple boto installations could be used from the same machine.

conn =  connection.SESConnection(aws_access_key_id=settings.AWS_ACCESS_KEY_ID, aws_secret_access_key=settings.AWS_SECRET_ACCESS_KEY, profile_name=settings.BOTO_PROFILE_NAME)

Support Python 2.6

SESBackend.send_messages use timedelta.total_seconds() when calculating the rate throttling delay (line 142 of django_ses.init.py in the current PyPI package). This method is new in Python 2.7, so I am getting AttributeError under Python 2.6. How about doing the calculation that total_seconds() does instead of using the shortcut? The calculation is in the Python docs:

http://docs.python.org/library/datetime.html#datetime.timedelta.total_seconds

timedelta.total_seconds()

    Return the total number of seconds contained in the duration. Equivalent to (td.microseconds + (td.seconds + td.days * 24 * 3600) * 10**6) / 10**6 computed with true division enabled.

    Note that for very large time intervals (greater than 270 years on most platforms) this method will lose microsecond accuracy.

    New in version 2.7.

Missing migrations

I see that this app does not include the initial migrations. Is this intentional or am I missing something here?

Configure travis-ci integration

Now that PR #33 is merged, django-ses can be tested against the Travis CI community-driven continuous integration server. It requires some configuration by the project admin, however. I have this turned on for my fork, but it'd be great if this main repository had it as well.

Need to update docs to point to new pydkim location

pydkim hasn't been updated since 2008. The author recently updated his website suggesting that people use the the actively maintained fork dkimpy

NOTE: This page describes the last release of pydkim from 2008. The latest version is a fork found at dkimpy in Launchpad and is under active development.

https://launchpad.net/dkimpy

https://pypi.python.org/pypi/dkimpy

I noticed this because pip was complaining the pydkim didn't have a secure/verifiable version available for download.

Probably should update the docs to have people use the actively maintained fork instead...

Remove django from required package

Hi,
Thank you for your piece of software, i'm using it production and it's so simple.
BTW, today i had to upgrade django-ses in order to stay up-to-date with my requirements, and i noticed that django-ses installed django==1.2.5 within. This is quite dangerous because it may breaks lot of sites - not all sites have migrated to 1.2.5, which implies to modify AJAX script in order to handle CSRF.
Can you remove this dependency, please ?
Cheers.

django-ses-0.2.tar.gz @ pypi is missing the templates dir

Trying to access the dashboard view from django_ses.urls causes TemplateDoesNotExist when django-ses is installed using pip, because django_ses/templates/django_ses/send_stats.html is missing from the package.

I find this rather confusing. Am I missing something?

update pypi

Pypi version is a year and a half out of date. Looks like there have been lots of changes since then.

ses_email_address raises exception

./manage.py ses_email_address
/usr/local/creatarr/lib/python2.6/site-packages/registration/models.py:4: DeprecationWarning: the sha module is deprecated; use the hashlib module instead
import sha
Traceback (most recent call last):
File "./manage.py", line 11, in
execute_manager(settings)
File "/usr/local/creatarr/lib/python2.6/site-packages/django/core/management/init.py", line 438, in execute_manager
utility.execute()
File "/usr/local/creatarr/lib/python2.6/site-packages/django/core/management/init.py", line 379, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/usr/local/creatarr/lib/python2.6/site-packages/django/core/management/base.py", line 191, in run_from_argv
self.execute(_args, *_options.dict)
File "/usr/local/creatarr/lib/python2.6/site-packages/django/core/management/base.py", line 220, in execute
output = self.handle(_args, *_options)
File "/usr/local/creatarr/lib/python2.6/site-packages/django_ses/management/commands/ses_email_address.py", line 35, in handle
SESConnection.DefaultHost)
AttributeError: type object 'SESConnection' has no attribute 'DefaultHost'

Documentation addition: Troubleshooting SAX issue.

In case anyone ever gets this random unhelpful error:

Traceback (most recent call last):
....
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/xml/sax/handler.py", line 38, in fatalError
raise exception xml.sax._exceptions.SAXParseException: <unknown>:1:0: syntax error

It's because you've set the AWS_SES_REGION_ENDPOINT incorrectly. As of today, the correct setting is:
AWS_SES_REGION_ENDPOINT = 'email.us-east-1.amazonaws.com'

Don't use the SMTP server setting set in the AWS dashboard.

Throttling bug on multiple recipients

http://sesblog.amazon.com/blog/tag/Throttle

Anyway, regarding what happens when you hit your limits during a call to send to multiple recipients – first remember that normally, sending limits are based on recipients rather than on messages. For example, an email to five recipients counts as five against your daily sending quota. When you send to multiple recipients, though, if you have any emails remaining in your daily sending quota, then your API call (as long as other factors are ok, like none of the addresses are on the blacklist) will go through. Keep in mind however that the amount you have left in your daily sending quota is being continuously calculated by Amazon SES, so it’s not good to be hovering too close to this limit. If you find yourself frequently cutting it this close, submit an Extended Access Request.

It’s a similar story with your send rate quota – if, at the rate you are sending, you have any emails left in your send rate quota, you can send to multiple recipients. However, you will not be able to send further emails until you have built up enough quota again. For example, if your send rate quota is one message per second, and you send a message to five recipients at once, Amazon SES lets you do that. For the next five seconds, though, Amazon will return errors for all send attempts. Once five seconds have passed, you'll have available quota and you will be able to send again. This way, emails with many recipients can get through, and they’ll get through at the overall rate allowed by the quota.

I had this message:

    <Code>Throttling</Code>
    <Message>Maximum sending rate exceeded.</Message>

You need to consider number of recipients for every message.
I can propose this:

n_recipients = len(set(previous_message.recipients()))
additional_delay = 1000 / rate_limit * (n_recipients - 1)

It adds 1/rate_limit seconds for every additional recipient. If there is only one, additional_delay is 0.

Set message-id to fixed value before sending, or else will break on Google App Engine

Firstly, AWS sets message-id to its own value, so whatever it receives from client is unimportant, as explained here: https://forums.aws.amazon.com/message.jspa?messageID=262855

However, if you do not set it explicitly to something when calling message.message() in send_messages(), then Django will try to set it based on socket connection which fails on Google App Engine (since GAE only support http/https requests).

Therefore, to work on GAE, it should be set explicitly, which, again, is okay since AWS uses its own value.

"Email address is not verified" for verified email

TBH, I'm not sure where this bug is coming from, Boto, SES or my own configuration.

Here it is though:

BotoServerError at /accounts/signup/

BotoServerError: 400 Bad Request


Sender
MessageRejected
Email address is not verified.

9360bdd6-c549-11e0-82fb-b9b4121fdb69

$ ./manage.py ses_email_address -l
Fetching list of verified emails:
[email protected]

Settings.py:
EMAIL_BACKEND = 'django_ses.SESBackend'
EMAIL_FROM = '[email protected]'
EMAIL_HOST_USER='[email protected]'
DEFAULT_FROM_EMAIL='[email protected]'
SERVER_EMAIL='[email protected]'

Went through the notification confirmation email from Amazon.. so why the rejected message?

Views should be implemented using admin views

Django 1.2 added lots of support for custom views in the model admin. The statistics views should be implemented using the model admin and use the permissions settings associated with that model.

Request: Support for SES SMTP

Hi,
Thanks so much for this great package! I've used it on a couple of sites and it works like a charm.
My client wants me to use the smtp version of ses - is there any way to do that with this package?

Thanks!

0.7.1 doesn't show-up nor install in pip

0.7.1 is listed on pypi: https://pypi.python.org/pypi/django-ses/0.7.1 for a few weeks now.

I tried installing it with python 3.5 on ubuntu, using pip 8.1.1 but I keep getting this error:

Could not find a version that satisfies the requirement django-ses==0.7.1 (from versions: 0.1, 0.2, 0.3.0, 0.4.0, 0.4.1, 0.6.0, 0.7.0)

I tried --no-cache-dir and then just removing ~/.cache/pip altogether. I also tried installing on a few other machines but none of their pip's can see 0.7.1.

Boto send_mail is unsupported

The sending of mails is done using Boto's ses.connection.send_raw_mail function and this is a dog's breakfast to use when trying to send HTML emails with a plain text version (if it's even possible). If it is practical for where this project is going, exposing the ses.connection.send_mail function would be be immensely useful to get SES functionality with Django SES reporting functionality (as well as a better expression of SES functionality as a service).

Version calculation in setup.py isn't correct

Installing the latest version (0.2.0) results in a package name of:
django-ses-.join-str-x-.for.x.in.VERSION-

The following change in setup.py fixes the problem:
VERSION = '.'.join(version_line.split(' = ')[-1][1:-2].split(', '))

Problems with utf8 from MySQL, UnicodeDecodeError exception thrown for emails with content from db.

Application database is MySQL, configured with UTF8 (utf8_general_ci).

While trying to send emails with data from the database and using django templates (render_to_string) I get this exception:

UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 336: ordinal not in range(128)

In order to fix it, I had to monkey patch boto/ses/connection.py to use Django's smart_unicode on line 299.

But probably problems are arising from this line https://github.com/hmarr/django-ses/blob/master/django_ses/__init__.py#L156

Django version to support

Should django be listed in requirements section of the docs? And if so, which versions are we supporting? I have only tried this on 1.3.

broken with boto 2.1.0

If I bump to boto 2.1.0 django_ses breaks:

>>> from django.core.mail import send_mail
>>> send_mail('subject', 'message', '[email protected]', ['[email protected]'])
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/opt/virtualenvs/proj/src/django/django/core/mail/__init__.py", line 59, in send_mail
    fail_silently=fail_silently)
  File "/opt/virtualenvs/proj/src/django/django/core/mail/__init__.py", line 41, in get_connection
    return klass(fail_silently=fail_silently, **kwds)
  File "/opt/virtualenvs/proj/lib/python2.6/site-packages/django_ses/__init__.py", line 22, in __init__
    SESConnection.DefaultHost)
AttributeError: type object 'SESConnection' has no attribute 'DefaultHost'
>>> import boto
>>> boto.__version__
'2.1.0'
>>> import django_ses
>>> django_ses.__version__
'0.2'

Support for "IAM roles for EC2"

Hi guys,

Is it possible to make this package support "IAM roles for EC2" feature?

I think the workable change would be something like below:

_Orginal_

connection = SESConnection(
                aws_access_key_id=access_key_id,
                aws_secret_access_key=access_key,
                region=region)

_Support for IAM_

connection = boto.ses.connect_to_region(region=region) If aws_access_key_id is None or aws_secret_access_key is None else boto.ses.connect_to_region(aws_access_key_id=access_key_id, aws_secret_access_key=access_key, region=region)

No way to change the return-path/source

According to FAQ #39 in order to change where bounce messages are sent you have to change the source parameter. That's why I came up with this patch that allows you to change the source parameter, https://gist.github.com/1105465.

Example Usage:

msg = EmailMultiAlternatives(subject, message_text, from_email, [to]) msg.attach_alternative(message_html, "text/html") msg.return_path = '[email protected]' # The address I want the bounce message to go to msg.send()

django_ses.SESBackend writes to email headers

Not sure if you count this as a bug or not.

My emails started to fail after using this backend because the headers dictionary I was passing in had the status, message_id and header_id written into it when sent. I reused this dictionary for subsequent emails so it failed after the first message was sent.

It's easy to work around by creating a new dictionary when sending each email rather than reusing it but it might be good to note this in the readme?

Retry error

I just had an unusual 500 error from SES with this response:

<ErrorResponse xmlns="http://ses.amazonaws.com/doc/2010-12-01/">
  <Error>
    <Type>Receiver</Type>
    <Code>InternalFailure</Code>
    <Message>An internal failure has occurred.</Message>
  </Error>
  <RequestId>2e7d4c8d-3746-11e5-a140-b919bcc9ecab</RequestId>
</ErrorResponse>

Normally, when an error occurs, my server has logic to queue a task to retry the message later. But, on each subsequent retry, I got this error:

  File "/base/data/home/apps/s~f/1.386013588458176163/django_ses/mail.py", line 35, in _send_deferred
    backend.send_messages([message])
  File "/base/data/home/apps/s~f/1.386013588458176163/django_ses/mail.py", line 203, in send_messages
    raw_message=unicode(dkim_sign(message.message().as_string()), 'utf-8')
  File "/base/data/home/apps/s~f/1.386013588458176163/django/core/mail/message.py", line 260, in message
    msg[name] = value
  File "/base/data/home/apps/s~fare/1.386013588458176163/django/core/mail/message.py", line 190, in __setitem__
    name, val = forbid_multi_line_headers(name, val, self.encoding)
  File "/base/data/home/apps/s~fare-clock/1.386013588458176163/django/core/mail/message.py", line 86, in forbid_multi_line_headers
    raise BadHeaderError("Header values can't contain newlines (got %r for header %r)" % (val, name))
BadHeaderError: Header values can't contain newlines (got u'<ErrorResponse xmlns="http://ses.amazonaws.com/doc/2010-12-01/">\n  <Error>\n    <Type>Receiver</Type>\n    <Code>InternalFailure</Code>\n    <Message>An internal failure has occurred.</Message>\n  </Error>\n  <RequestId>2e7d4c8d-3746-11e5-a140-b919bcc9ecab</RequestId>\n</ErrorResponse>\n' for header 'body')

What's strange is it looks like the message had a header containing the error response from the original attempt to send the message. I looked through the code, and noticed that the exception handler in send_messages() looks like this:

            except SESConnection.ResponseError as err:
                # Store failure information so to post process it if required
                error_keys = ['status', 'reason', 'body', 'request_id',
                              'error_code', 'error_message']
                for key in error_keys:
                    message.extra_headers[key] = getattr(err, key, None)
                if not self.fail_silently:
                    raise

So it's storing the error as a message header, and sending it in the subsequent retry. Is it wrong to retry a message, or is this a bug?

django ses issue (with celery): BotoServerError: BotoServerError: 403 Forbidden

I am using django-ses:

Please find settings for it

EMAIL_BACKEND = 'django_ses.SESBackend'
EMAIL_HOST = 'email.us-east-1.amazonaws.com'
EMAIL_PORT = 465
EMAIL_HOST_USER = '----------------'
EMAIL_HOST_PASSWORD = '-------------------'

AWS_ACCESS_KEY_ID = '-------------------'
AWS_SECRET_ACCESS_KEY = '------------------------------'
AWS_SES_REGION_ENDPOINT = 'email.us-east-1.amazonaws.com'

Find the error stack:

BotoServerError: BotoServerError: 403 Forbidden
<ErrorResponse xmlns="http://ses.amazonaws.com/doc/2010-12-01/">
  <Error>
    <Type>Sender</Type>
    <Code>AccessDenied</Code>
    <Message>User: arn:aws:iam::00000000000:user/ses-smtp-user.20160209-000000 is not authorized to perform: ses:GetSendQuota</Message>
  </Error>
  <RequestId>0000000-0000-0000-0000-0000000000</RequestId>
</ErrorResponse>

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.