[PYTHON] Django-A story that got stuck when trying to operate mail with SES and Amazon SES (also introduces the fastest operation procedure)

Introduction

This is the 24th day article of Django Advent Calendar 2019. I wrote the article with pride in thinking about Django on Christmas Eve. Lol

I'm still a beginner, but I've been studying Django and at some point I've been stuck for hours (a little new way to get stuck?). Even if the reference was in English, there was no article that was just right, so I decided to write this article with the feeling that "I don't want other people to stumble here."

Structure of this article

First, I'll show you the fastest way to deliver emails using Django-ses and Amazon-SES to broaden your readership (. ・ _ ・.). Next, I would like to introduce the packed part that is the main subject of this time!

Target audience

As the title says, this is an article for "people who want to deliver emails using ** django-ses ** and ** Amazon SES ** (Amazon Simple Email Service)".

Development environment

Confirm this goal

This time, "If you can send_mail using Amazon SES and Django-SES, you will reach your goal! I will say.

The completed form of the program (the ant that needs to change the settings with the KEY setting of Amazon SES) is listed in GitHub here.

Create a program

Docker files

First of all, I will put a Docker file. Create the following files under the docker-ses-sample directory.

dockerfile


FROM python:3

ENV PYTHONUNBUFFERED 1

RUN mkdir /code
WORKDIR /code

COPY requirements.txt /code/
RUN pip install -r requirements.txt
COPY . /code/

docker-compose.yml


version: "3"
services: 
    django-ses-sample:
        build: .
        volumes: 
            - .:/code
        ports: 
            - "8000:8000"
        command: python manage.py runserver 0.0.0.0:8000

This is a list of packages to be installed next.

requirements.txt


Django==2.2.9
boto3==1.10.44
django-ses==0.8.13

↓ Current directory like this ↓

Working directory


django-ses-sample
           ├ dockerfile
           ├ docker-compose.yml
           └ requirements.txt

From here to the start project at once. First, open the CLI where you can play with docker. (I use the Ubuntu 18.04 LTS CLI)

Then move to your working directory.

CLI that docker can mess with


~/$ cd django-ses-sample
~/django-ses-sample$ docker-compose run --rm django-ses-sample django-admin startproject config .

This makes it easy because you can go to the start project while building. And when such a display comes, it is successful.

CLI that docker can mess with


Successfully tagged djangosessample_django-ses-sample:latest

And if you see a start project under django-ses-sample, let's move on!

Django files

Next, we will play with settings.py in the config created by startproject. There is a column called INSTALLED_APPS in settings.py, so add django_ses here.

settings.py


     :
INSTALLED_APPS = [
         :
    'django_ses', #Added
]

Then scroll to the bottom and add the following new program.

settings.py


    :
# AWS settings 
AWS_ACCESS_KEY_ID = 'AKI***********'       #Access key ID
AWS_SECRET_ACCESS_KEY = '****************************'     #Secret access key

# Email settings
EMAIL_BACKEND = 'django_ses.SESBackend'         #This is mandatory
DEFAULT_FROM_EMAIL = SERVER_EMAIL = '**** <****@******>' #Sender's username and email address(Example:'Asuka<[email protected]>')

It is necessary to set the access key ID and secret access key in this way. This will be created on AWS in the next chapter, so you can leave it blank for now. In addition, mail delivery is set by EMAIL_BACKEND. I'm declaring to use Django-SES here. The last line holds the sender's information.

The program at this point is on GitHub here.

Go to AWS for various settings

Amazon SES registration procedure

  1. First, prepare an AWS account.

  2. After signing in, enter SES (Simple Email Service) in the service and jump to that page.

  3. If you've probably set the standard region to Tokyo here, you'll be asked to select a region, so be sure to select ** US East (N. Virginia): us-east-1 *. ( I'm stuck here. [Jump down the article](# I'm going into the main subject of this article)

  4. Email Addresses will appear in the left column, so select it.

  5. Select [Varify a New mail a dress] and register a receivable e-mail address.

  6. Here, please register another receivable e-mail address with [Varify a New mail a dress].

  7. Next, an email will be sent from AWS to the email address registered in 5 and 6, so please access that URL and authenticate your email address.

  8. This completes

IAM registration

To use AmazonSES, you need to generate the access key ID and secret access key introduced earlier.

  1. Search the IAM page in the service and fly
  2. Select a user in the left column
  3. Select Add User
  4. Enter the user name as you like
  5. Check programmatic access
  6. Select Next Step below
  7. Select Attach existing policy directly
  8. Search for SES and select Amazon SES Full Access
  9. After that, please go through and create a user
  10. You can download csv when you create it, so download it
  11. Check the access key ID and secret access key with csv
  12. This completes

Finally, enter the access key ID and secret access key in config / settings.py! !!

Check if SES works with Django

The confirmation method was the goal of this time, "If you can send_mail using Amazon SES and Django-SES, you will reach the goal! ], So send_mail is used, so import it with a python shell and execute it.

CLI


~/django-ses-sample$ docker-compose run --rm django-ses-sample python3 manage.py shell
>>> from django.core.mail import send_mail
>>> title = 'This is Asuka Saito.'
>>> content = 'Isn't Christmas free tomorrow?'
>>> host_email = 'Email address registered with SES ①'    #Example:[email protected]
>>> rece_email = ['Email address registered with SES ②']  #Example:['[email protected]']
>>> send_mail(title,content,host_email,rece_email)

You should now receive an email (crying)

Let's get into the main subject of this article! !! !! (Checkmate story)

Please take a look at it as a side note. Lol

I'll tell you where I stumbled first!

  1. ** Building the environment with Django 3.0 **
  2. ** Setting Region to Mumbai, Asia Pacific **

① About building an environment with Django 3.0

You'll want to use it when it's officially released ... lol

However, when I build the environment with Django 3.0, I get this error related to the files of boto or django-ses.

CLI


ImportError: cannot import name 'python_2_unicode_compatible' from 'django.utils.encoding

It seems that Django 3.0 started throwing errors due to the removal of the Python 2 compatibility API. * 2 Django Official Documentation * 3 GitHub issues

Apparently, it seems to be cured if I mess with the file, but the file was not found in the DB in the Docker container (originally developed with PostgreSQL), and by using Django 2.2 series, I no longer throw an error.

(2) Regarding the matter of setting Region to Mumbai in Asia Pacific

The information that I see here and there, "The response is faster in the region closer to my area", has moved my body ...

I searched various documents for the problem here, but none of them seemed to fit. So I decided to write this time.

However, it is likely that experts will point out, so I will write here first.

It was impossible to write the settings in settings.py

By setting AWS_SES_REGION_NAME and AWS_SES_REGION_ENDPOINT, you can set regions other than "US East (N. Virginia)" (us-east-1).

For example, in the case of "Western United States (Oregon)" (us-west-2), you can send an email by writing this in settings.py after authenticating your email address with Amazon SES.

settings.py


AWS_ACCESS_KEY_ID = 'AKI***********'       #Access key ID
AWS_SECRET_ACCESS_KEY = '**************************'        #Secret access key
AWS_SES_REGION_NAME = 'us-west-2'          #Added
AWS_SES_REGION_ENDPOINT = 'email.us-west-2.amazonaws.com'   #Added

but! !! !! ** With "Asia Pacific (Mumbai)" (ap-south-1), you cannot send an email even if you set it like this! !! ** **

settings.py


AWS_ACCESS_KEY_ID = 'AKI***********'       #Access key ID
AWS_SECRET_ACCESS_KEY = '**************************'        #Secret access key
AWS_SES_REGION_NAME = 'ap-south-1'          #Added
AWS_SES_REGION_ENDPOINT = 'email.ap-south-1.amazonaws.com'   #Added

So what was wrong after all? ??

My conclusion is that AWS has some services that are not implemented in each region, so ** Asia Pacific (Oregon) has not yet implemented that service **. I'm guessing it isn't.

In fact, it seems that Oregon was added to the SES service recently, and I think "I think it will probably be available in future updates" (/ ・ ω ・) /

at the end

Thank you for reading until the end. If you add the allauth package etc. to the program created this time, you will be able to implement a solid mail function, so please take advantage of the fastest procedure. If you have any mistakes or impressions, please feel free to comment! !!

I would be grateful if you could follow me on Twitter, who is studying backends such as Django, AWS, and Docker, and is also making some efforts in machine learning! !@ heacet43

References

Recommended Posts

Django-A story that got stuck when trying to operate mail with SES and Amazon SES (also introduces the fastest operation procedure)
A story that got stuck when trying to upgrade the Python version on GCE
A story that failed when trying to remove the suffix from the string with rstrip
Problems and solutions when trying to put rbenv with git submodule (also pyenv)
A story that required preparation when trying to do a Django tutorial with plain centos7
I got stuck when trying to specify a relative path with relative_to () in python
The story of trying to contribute to COVID-19 analysis with AWS free tier and failing
When writing to a csv file with python, a story that I made a mistake and did not meet the delivery date