Emails Setup in Django Using AWS

yokwejuste

Steve Yonkeu

Posted on July 28, 2024

Emails Setup in Django Using AWS

In the early days, communication relied on letters that took days or weeks to deliver. The internet revolutionized this with the advent of emails, providing instantaneous and reliable messaging. From there businesses quickly adopted this tool for customer communication, transactional updates, and marketing, valuing the speed and direct connection it offered. For developers, integrating email functionality into applications has become essential. AWS (Amazon Web Services) provides not only a robust but also a cheap solution for setting up email services, allowing developers to automate and streamline communication within their Django applications.

Let's dive into a quick implementation of this using AWS and Django. We will be using a couple of ideas from the AWS Official Blog.

  • What is Django?
    Django is a free, open-source Python web framework designed to simplify the creation of complex, database-driven websites. It emphasizes reusability, rapid development, and clean design. Django handles many common web development tasks, allowing developers to focus on unique features for their applications. Personally, I consider it quickest way to kickstart a web application.

  • What is AWS?
    Amazon Web Services (AWS) is a comprehensive cloud computing platform offering over 200 services. It provides on-demand resources like computing power, storage, databases, and machine learning tools for individuals, businesses, and governments. AWS operates on a pay-as-you-go model, allowing users to scale resources based on their needs.

Why AWS?

  1. Price:
    After a few comparison I came to the conclusion that this will be our most cost effective option.

    Email Service Free Tier Price per 10,000 Emails Additional Features
    AWS SES 62,000 emails per month (when sent from Amazon EC2) $1 (after 62,000 free tier) Flexible, scalable, and cost-effective
    SendGrid 100 emails/day (3,000 emails/month) $9.95 for 10,000 emails Advanced analytics, templates, API
    Mailgun 5,000 emails/month for 3 months $35 for 10,000 emails Email validation, detailed logs, analytics
    Mailchimp 10,000 emails/month for 3 months $30 for 10,000 emails Marketing automation, templates, analytics
    Postmark No free tier $10 for 10,000 emails Fast delivery, detailed stats, responsive support
    Sendinblue 300 emails/day (9,000 emails/month) $25 for 10,000 emails Marketing automation, SMS, chat, CRM
    SparkPost 15,000 emails/month $20 for 10,000 emails Advanced analytics, templates, API
    Mandrill (Mailchimp) No free tier $20 for 10,000 emails Transactional email service, API
  2. Scalability:
    AWS SES is highly scalable, allowing you to send millions of emails per day. Its robust infrastructure ensures that you can handle increased email volumes seamlessly as your business grows. Base on your needs you can easily step up.

  3. Reliability:
    AWS SES boasts high deliverability rates and strong security measures, ensuring that your emails reach their intended recipients reliably and safely. This reliability is critical for maintaining effective communication with your customers.

Setting Amazon SES(Simple Email Service)

  1. Let's get started AWS SES Home
  2. Enter Email, domain/subdomain and proceed Click the button
  3. Verify your email and domain Verification 1 Verification 2 Verification 3
  4. By default the account is in Sandbox mode and needs to be in production to send emails to emails not under the verified domain. It usually takes a couple of hours, maximum 24 hours to verify but it's worth it. Sandbox Account

Setting the Django project

This project being one tagged as beginner-friendly we need a few prerequisites for this. Already we need to have a Python environment properly setup. Also, a valid domain and email ready for use on this project. I got a random domain name and an email for this tutorial. Let's have a walk now...

  1. Creating Folder and Activating the virtual environment
mkdir DjangoSES && cd DjangoSES

python -m venv venv

# For Unix and Linux
source venv/bin/activate
Enter fullscreen mode Exit fullscreen mode
  1. Installing the necessary packages or dependencies
pip install django boto3 python-dotenv
Enter fullscreen mode Exit fullscreen mode
  1. Creating the Django Project and the Django app
# Creating the Django project
django-admin startproject aws_ses .

# We create an application for the project
python manage.py startapp emailer
Enter fullscreen mode Exit fullscreen mode

At this moment, the current project structure is using the command below:

tree -I "venv|__pycache__" .
Enter fullscreen mode Exit fullscreen mode

The Output below:

    .
    ├── aws_ses
    │   ├── __init__.py
    │   ├── asgi.py
    │   ├── settings.py
    │   ├── urls.py
    │   └── wsgi.py
    ├── emailer
    │   ├── __init__.py
    │   ├── admin.py
    │   ├── apps.py
+   │   ├── forms.py
    │   ├── migrations
    │   │   └── __init__.py
    │   ├── models.py
    │   ├── tests.py
+   │   ├── urls.py
+   │   ├── utils.py
    │   └── views.py
    ├── manage.py
    └── requirements.txt
    ├── static
    └── templates
+   └── .env
Enter fullscreen mode Exit fullscreen mode

At this point you should have this display on your browser when you run the command:

python manage.py runserver
Enter fullscreen mode Exit fullscreen mode

Django Init Display

Writing some utils functions for the project

  1. A function to send emails
# .env
AWS_ACCESS_KEY_ID=your_access_key_id
AWS_SECRET_ACCESS_KEY=your_secret_access_key
AWS_REGION_NAME=your_aws_region
Enter fullscreen mode Exit fullscreen mode
# aws_ses/settings.py
import os
from dotenv import load_dotenv

load_dotenv()

AWS_ACCESS_KEY_ID = os.getenv('AWS_ACCESS_KEY_ID')
AWS_SECRET_ACCESS_KEY = os.getenv('AWS_SECRET_ACCESS_KEY')
AWS_REGION_NAME = os.getenv('AWS_REGION_NAME')
DEFAULT_FROM_EMAIL = os.getenv('DEFAULT_FROM_EMAIL')
Enter fullscreen mode Exit fullscreen mode
# emailer/utils.py
import boto3
from botocore.exceptions import ClientError
from django.conf import settings

def send_ses_email(recipient, subject, body_text, body_html=None):
    client = boto3.client('ses', region_name=settings.AWS_REGION_NAME)

    try:
        response = client.send_email(
            Destination={
                'ToAddresses': [recipient],
            },
            Message={
                'Body': {
                    'Text': {
                        'Charset': 'UTF-8',
                        'Data': body_text,
                    },
                    'Html': {
                        'Charset': 'UTF-8',
                        'Data': body_html,
                    } if body_html else {},
                },
                'Subject': {
                    'Charset': 'UTF-8',
                    'Data': subject,
                },
            },
            Source=settings.DEFAULT_FROM_EMAIL,
        )
    except ClientError as e:
        print(f"An error occurred: {e.response['Error']['Message']}")
        return False
    else:
        print(f"Email sent! Message ID: {response['MessageId']}")
        return True
Enter fullscreen mode Exit fullscreen mode

This project will be fully available on GitHub here

Conclusion

I thoroughly enjoyed working with AWS services to enhance the capabilities of Django applications. The versatility and robustness of AWS tools have made this project not only successful but also a great learning experience. As we continue to explore and integrate AWS services into our future projects, I am excited about the potential to innovate and optimize our applications further. For more insights and updates on upcoming projects utilizing AWS, please visit my website and follow my social media channels. Let's stay connected and push the boundaries of what we can achieve with AWS and Django. Stay tuned for more!

💖 💪 🙅 🚩
yokwejuste
Steve Yonkeu

Posted on July 28, 2024

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related