Amazon SES SMTP with Django
Question:
I’m trying to use Amazon’s new SMTP service for SES with Django 1.3.1 but I’m not having much luck.
I’ve created my SES SMTP credentials and have this in my settings:
EMAIL_USE_TLS = True
EMAIL_HOST = 'email-smtp.us-east-1.amazonaws.com'
EMAIL_HOST_USER = 'my-smtp-user'
EMAIL_HOST_PASSWORD = 'my-smtp-password'
EMAIL_PORT = 465
Then I try sending a test email (from and to verified email addresses):
from django.core.mail import send_mail
send_mail('Test subject', 'This is the body', '[email protected]',['[email protected]'], fail_silently=False)
But I get the following error:
SMTPServerDisconnected: Connection unexpectedly closed
I can telnet to the server:
telnet email-smtp.us-east-1.amazonaws.com 465
Answers:
http://aws.amazon.com/articles/2405502737055650
core python functionality sample
After long long searching and trying I found:
Instead using:
s = smtplib.SMTP(host, port)
s.starttls()
s.login(user, password)
For AmazonSES SMTP must be:
s = smtplib.SMTP_SSL(host, port)
s.login(user, password)
So, I think, for django you can either fix django code, or write you own simple email backend [based on default django email backend].
UPD:
I found another solution (but not tested it by myself): use SSLEmailBackend from link below
// settings.py
EMAIL_BACKEND = 'backends.smtp.SSLEmailBackend'
(From here: Mysterious issue with Django + uWSGI + send email )
UPD2:
AmazonSES supports STARTTLS from now 🙂
Amazon SES supports expanded attachment types, VERP, and STARTTLS for SMTP
(from Amazon Newsletter)
I found a much simpler solution that would allow me to use Django’s built-in mail classes so I can still get my admin error email reports etc.
Thanks to this little beauty I was able to use SES SMTP without any problems:
https://github.com/bancek/django-smtp-ssl
Download and install (python setup.py install)
Then just change your settings to use this new email backend:
EMAIL_BACKEND = 'django_smtp_ssl.SSLEmailBackend'
The rest of the settings are as per normal:
EMAIL_HOST = 'email-smtp.us-east-1.amazonaws.com'
EMAIL_PORT = 465
EMAIL_HOST_USER = 'my_smtp_username'
EMAIL_HOST_PASSWORD = 'my_smtp_password'
EMAIL_USE_TLS = True
I took like 3 hrs breaking my head over it. Your solution about the smtplib with s.starttls() and then s.login() is good with a python program with all the email credentials in the same file. But I don’t think it is a clean way to do it in Django. So I finally figured it out. Irrespective of whether your machine is a 32 or a 64 bit. Just do the following steps:
-
Install boto
pip install –upgrade boto
-
Install django-ses
pip install django-ses
-
In your djando settings.py file update the following info.
EMAIL_BACKEND = ‘django_ses.SESBackend’
AWS_ACCESS_KEY_ID = ‘your_username’
AWS_SECRET_ACCESS_KEY = ‘your_password’
-
In your django file where you want to send an email
from django.core.mail import send_mail
send_mail(‘Test subject’, ‘This is the body’, ‘[email protected]’,[‘[email protected]’],fail_silently=False)
Since Django 1.7, you can send email with SSL natively without third party library.
EMAIL_USE_SSL = True
I have tried smtp settings in order to @Givp(who answered above), I want to give complete AWS SMTP settings in django.
DEFAULT_FROM_EMAIL = '[email protected]'
ADMINS = [('name', '[email protected]')]
MANAGERS = ADMINS
SERVER_EMAIL = '[email protected]' # this is for to send 500 mail to admins
EMAIL_BACKEND = 'django_smtp_ssl.SSLEmailBackend'
MAIL_HOST = 'email-smtp.us-east-1.amazonaws.com'
EMAIL_PORT = 465
EMAIL_HOST_USER = 'Accesskeyofsmtp'
EMAIL_HOST_PASSWORD = 'secretkeyofsmtp'
EMAIL_USE_TLS = True
Here we have to verify all the mail-ids before sending email.then everything would work as our expectation
2019 Update: Django 2.2.1
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'email-smtp.us-east-1.amazonaws.com'
EMAIL_PORT = 587
EMAIL_HOST_USER = 'my_smtp_username'
EMAIL_HOST_PASSWORD = 'my_smtp_password'
EMAIL_USE_TLS = True
No library needed.
Credits : https://stackoverflow.com/a/32476190/5647272
Reference : https://docs.djangoproject.com/en/2.2/topics/email/
Aug, 2022 Update with Django-3.2.4:
No libraries needed such as django-ses
or django-amazon-ses
!!
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'email-smtp.ap-northeast-1.amazonaws.com'
EMAIL_PORT = 587
EMAIL_USE_TLS = True
EMAIL_HOST_USER = 'my_smtp_username' # Must create SMTP Credentials
EMAIL_HOST_PASSWORD = 'my_smtp_password' # Must create SMTP Credentials
DEFAULT_FROM_EMAIL = '[email protected]' # If don't need, comment out!!
I added DEFAULT_FROM_EMAIL
.
DEFAULT_FROM_EMAIL = '[email protected]'
If you don’t need it, comment it out!!
# DEFAULT_FROM_EMAIL = '[email protected]'
Moreover, for DEFAULT_FROM_EMAIL
, put one verified domain
or email address
whether or not your account is in the sandbox
.
So for the verified domain sender.com
below,
Three of them below are valid: (Use only one of three)
DEFAULT_FROM_EMAIL = '[email protected]' # OR
DEFAULT_FROM_EMAIL = '[email protected]' # OR
DEFAULT_FROM_EMAIL = '[email protected]'
But these two below are not valid: (These give you error)
*The format must be [email protected]
!!
DEFAULT_FROM_EMAIL = 'sender.com'
DEFAULT_FROM_EMAIL = '@sender.com'
Then, for the verified 2 email addresses
below,
Just use only one of two below:
DEFAULT_FROM_EMAIL = '[email protected]' # OR
DEFAULT_FROM_EMAIL = '[email protected]'
Finally, for EMAIL_HOST_USER
and EMAIL_HOST_PASSWORD
, you must create SMTP Credentials
.
Choose SMTP Settings
:
Press Create My SMTP Credentials
Button:
Given SMTP Credentials
:
Then, put the SMTP Credentials
as below:
EMAIL_HOST_USER = 'AKIAWP3TMGZN4OZH5H37'
EMAIL_HOST_PASSWORD = 'BB6dufiw96jJHUTrowXI8R4gcyOI+t1+Skbi51cdHYhV'
*(I’ve already deleted these SMTP Credentials
)
I’m trying to use Amazon’s new SMTP service for SES with Django 1.3.1 but I’m not having much luck.
I’ve created my SES SMTP credentials and have this in my settings:
EMAIL_USE_TLS = True
EMAIL_HOST = 'email-smtp.us-east-1.amazonaws.com'
EMAIL_HOST_USER = 'my-smtp-user'
EMAIL_HOST_PASSWORD = 'my-smtp-password'
EMAIL_PORT = 465
Then I try sending a test email (from and to verified email addresses):
from django.core.mail import send_mail
send_mail('Test subject', 'This is the body', '[email protected]',['[email protected]'], fail_silently=False)
But I get the following error:
SMTPServerDisconnected: Connection unexpectedly closed
I can telnet to the server:
telnet email-smtp.us-east-1.amazonaws.com 465
http://aws.amazon.com/articles/2405502737055650
core python functionality sample
After long long searching and trying I found:
Instead using:
s = smtplib.SMTP(host, port)
s.starttls()
s.login(user, password)
For AmazonSES SMTP must be:
s = smtplib.SMTP_SSL(host, port)
s.login(user, password)
So, I think, for django you can either fix django code, or write you own simple email backend [based on default django email backend].
UPD:
I found another solution (but not tested it by myself): use SSLEmailBackend from link below
// settings.py
EMAIL_BACKEND = 'backends.smtp.SSLEmailBackend'
(From here: Mysterious issue with Django + uWSGI + send email )
UPD2:
AmazonSES supports STARTTLS from now 🙂
Amazon SES supports expanded attachment types, VERP, and STARTTLS for SMTP
(from Amazon Newsletter)
I found a much simpler solution that would allow me to use Django’s built-in mail classes so I can still get my admin error email reports etc.
Thanks to this little beauty I was able to use SES SMTP without any problems:
https://github.com/bancek/django-smtp-ssl
Download and install (python setup.py install)
Then just change your settings to use this new email backend:
EMAIL_BACKEND = 'django_smtp_ssl.SSLEmailBackend'
The rest of the settings are as per normal:
EMAIL_HOST = 'email-smtp.us-east-1.amazonaws.com'
EMAIL_PORT = 465
EMAIL_HOST_USER = 'my_smtp_username'
EMAIL_HOST_PASSWORD = 'my_smtp_password'
EMAIL_USE_TLS = True
I took like 3 hrs breaking my head over it. Your solution about the smtplib with s.starttls() and then s.login() is good with a python program with all the email credentials in the same file. But I don’t think it is a clean way to do it in Django. So I finally figured it out. Irrespective of whether your machine is a 32 or a 64 bit. Just do the following steps:
-
Install boto
pip install –upgrade boto
-
Install django-ses
pip install django-ses
-
In your djando settings.py file update the following info.
EMAIL_BACKEND = ‘django_ses.SESBackend’
AWS_ACCESS_KEY_ID = ‘your_username’
AWS_SECRET_ACCESS_KEY = ‘your_password’ -
In your django file where you want to send an email
from django.core.mail import send_mail
send_mail(‘Test subject’, ‘This is the body’, ‘[email protected]’,[‘[email protected]’],fail_silently=False)
Since Django 1.7, you can send email with SSL natively without third party library.
EMAIL_USE_SSL = True
I have tried smtp settings in order to @Givp(who answered above), I want to give complete AWS SMTP settings in django.
DEFAULT_FROM_EMAIL = '[email protected]'
ADMINS = [('name', '[email protected]')]
MANAGERS = ADMINS
SERVER_EMAIL = '[email protected]' # this is for to send 500 mail to admins
EMAIL_BACKEND = 'django_smtp_ssl.SSLEmailBackend'
MAIL_HOST = 'email-smtp.us-east-1.amazonaws.com'
EMAIL_PORT = 465
EMAIL_HOST_USER = 'Accesskeyofsmtp'
EMAIL_HOST_PASSWORD = 'secretkeyofsmtp'
EMAIL_USE_TLS = True
Here we have to verify all the mail-ids before sending email.then everything would work as our expectation
2019 Update: Django 2.2.1
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'email-smtp.us-east-1.amazonaws.com'
EMAIL_PORT = 587
EMAIL_HOST_USER = 'my_smtp_username'
EMAIL_HOST_PASSWORD = 'my_smtp_password'
EMAIL_USE_TLS = True
No library needed.
Credits : https://stackoverflow.com/a/32476190/5647272
Reference : https://docs.djangoproject.com/en/2.2/topics/email/
Aug, 2022 Update with Django-3.2.4:
No libraries needed such as django-ses
or django-amazon-ses
!!
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'email-smtp.ap-northeast-1.amazonaws.com'
EMAIL_PORT = 587
EMAIL_USE_TLS = True
EMAIL_HOST_USER = 'my_smtp_username' # Must create SMTP Credentials
EMAIL_HOST_PASSWORD = 'my_smtp_password' # Must create SMTP Credentials
DEFAULT_FROM_EMAIL = '[email protected]' # If don't need, comment out!!
I added DEFAULT_FROM_EMAIL
.
DEFAULT_FROM_EMAIL = '[email protected]'
If you don’t need it, comment it out!!
# DEFAULT_FROM_EMAIL = '[email protected]'
Moreover, for DEFAULT_FROM_EMAIL
, put one verified domain
or email address
whether or not your account is in the sandbox
.
So for the verified domain sender.com
below,
Three of them below are valid: (Use only one of three)
DEFAULT_FROM_EMAIL = '[email protected]' # OR
DEFAULT_FROM_EMAIL = '[email protected]' # OR
DEFAULT_FROM_EMAIL = '[email protected]'
But these two below are not valid: (These give you error)
*The format must be [email protected]
!!
DEFAULT_FROM_EMAIL = 'sender.com'
DEFAULT_FROM_EMAIL = '@sender.com'
Then, for the verified 2 email addresses
below,
Just use only one of two below:
DEFAULT_FROM_EMAIL = '[email protected]' # OR
DEFAULT_FROM_EMAIL = '[email protected]'
Finally, for EMAIL_HOST_USER
and EMAIL_HOST_PASSWORD
, you must create SMTP Credentials
.
Choose SMTP Settings
:
Press Create My SMTP Credentials
Button:
Given SMTP Credentials
:
Then, put the SMTP Credentials
as below:
EMAIL_HOST_USER = 'AKIAWP3TMGZN4OZH5H37'
EMAIL_HOST_PASSWORD = 'BB6dufiw96jJHUTrowXI8R4gcyOI+t1+Skbi51cdHYhV'
*(I’ve already deleted these SMTP Credentials
)