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?
Price:
1-- 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)
Let's get started
Enter Email, domain/subdomain and proceed
Verify your email and domain
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.
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...
- Creating Folder and Activating the virtual environment
mkdir DjangoSES && cd DjangoSES
python -m venv venv
# For Unix and Linux
source venv/bin/activate
- Installing the necessary packages or dependencies
pip install django boto3 python-dotenv
- 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
At this moment, the current project structure is using the command below:
tree -I "venv|__pycache__" .
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
At this point you should have this display on your browser when you run the command:
python manage.py runserver
Writing some utils functions for the project
- 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
# 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')
# 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
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!