Deciding how to add email sending capabilities to a web application is always difficult. Do you go through the trouble of setting up and maintaining your own email server, or do you opt for a third-party email service? While the answer is dependent on a number of variables such as volume of emails, your hosting platform and your budget, the tendency is often to favor the simplicity offered by a dedicated email service.
To follow this tutorial you need the following items:
- Python 3 — If your operating system does not provide a Python 3 interpreter, you can go to python.org to download an installer.
- A Twilio SendGrid account — If you are new to Twilio Sendgrid you can create a free account, which allows you to send 100 emails per day forever.
Before you can send email through SendGrid, you have to create an API key that you will use to authenticate with the service. Log in to your SendGrid account, then click on the left sidebar, select Settings and then API Keys. Finally click the “Create API Key”.
You need to give your API key a friendly name. For this tutorial I chose the name Django. I selected “Full Access” for permissions, which gives the key the ability to perform all the necessary email sending functions. If you prefer to create a key that has very specific permissions, then select “Restricted Access” and configure your access as needed.
When you click the “Create & View” button you will be presented with your key. This key will never be shown again, so you need to click on it to copy it to the clipboard, and then paste it in a secure document so that you can use it later. If you lose your key, you will need to generate a brand new one. Once you have saved your key, you can click the “Done” button.
Creating a Python Environment
Now we are ready to see how to send an email in the context of a Django application. We’ll begin by making a new directory on your computer called twilio-sendgrid-tests or similar, then creating a new Python virtual environment in it.
For Mac and Unix users, the commands are:
mkdir twilio-sendgrid-tests cd twilio-sendgrid-tests python3 -m venv venv source venv/bin/activate
For Windows users, open a Command Prompt or PowerShell window and use the following commands:
md twilio-sendgrid-tests cd twilio-sendgrid-tests python -m venv venv venv\Scripts\activate
If the Python virtual environment was created and activated successfully your prompt should have been modified with a
Now you can install
python-dotenv in your virtual environment:
(venv) $ pip install django python-dotenv
Creating a Django Application
Let’s create a starter Django application and then set our current directory to it. I’m going to call it emails, but you can use any name you like for it:
(venv) $ django-admin startproject emails (venv) $ cd emails
The good news is that Twilio SendGrid offers an SMTP interface for sending emails, which Django fully supports. To configure Django to send emails through SendGrid, add the following variables at the bottom of your settings.py file. In my case, this file is located in emails/settings.py, but your location will be different if you used a different name for your Django application.
# Twilio SendGrid EMAIL_HOST = 'smtp.sendgrid.net' EMAIL_PORT = 587 EMAIL_USE_TLS = True EMAIL_HOST_USER = 'apikey' EMAIL_HOST_PASSWORD = os.environ.get('SENDGRID_API_KEY')
You can see above that to use SendGrid’s SMTP interface you must have the following settings:
- The mail server should be
- The mail port should be 587 (port 25 is also supported, if you prefer)
- TLS must be enabled
- Authentication is required. For the username you must use
apikey(this is the same for all SendGrid accounts). The password is the SendGrid API key that you created in the previous section.
Since it is a bad practice to include secrets in your source code, we import the SendGrid API key from an environment variable called
SENDGRID_API_KEY. To avoid having to set this environment variable, we can store it in a .env file. Create a file named .env (note the leading dot) in the top-level of your Django application and define the variable in it:
Django knows nothing of this .env file, so it needs to be told to import environment variables from it when the application starts. This can be done at the top of that same settings.py file:
from dotenv import load_dotenv load_dotenv()
Sending an Email
Now you are going to send yourself a test email. Start a Python shell as follows:
(venv) $ python manage.py shell
Note that we started the Python shell with the
manage.py shell command, as this will ensure that the Django application is created and the settings we added above are imported.
Once in the shell, we can use the
send_mail() function from Django to send a test email:
from django.core.mail import send_mail send_mail('Example Subject', 'Example message', 'firstname.lastname@example.org', ['email@example.com'])
The arguments in the
send_mail() function call above are the email subject, the body, the sender, and finally a list of recipients. Try it in your own shell session by replacing the sender and recipient with some of your own email addresses.
If everything goes well, an email should arrive at your inbox a few seconds later.
Now that you have confirmed that the application sends simple emails, you are ready to code your Django application using the
send_mail() function as above or even with the lower-level
EmailMessage class. All the email features provided by the Django framework are now enabled to work through Twilio SendGrid!
If Your Emails Aren’t Delivered
My hope is that using the
send_email() function above you are successful in sending emails. There is a chance, however, that your emails will fail to be delivered. Since SendGrid sends emails asynchronously, most delivery errors occur after the sender completes their side of the transaction, so your application will not have any indication that there has been an error. If this happens, then it is likely that the email was rejected by the recipient’s email server.
If you experience this when you try to send an email as shown in the previous section, you can use the Twilio SendGrid console to help you debug what happened. From the SendGrid dashboard, click on Activity, and then on the “Show All Activity” button in the middle of the page. This will show you a list of all the emails that you attempted to send, indicating if they were successfully delivered or not.
You can see in the picture above that an email that I accidentally sent to an example.com address failed to be delivered. For any emails that were not delivered, you can click on the email to see detailed information, including any error responses sent by the recipient’s email server.
Twilio SendGrid is an extremely simple service that integrates nicely into the standard Django email sending workflow. I hope you decide to give Twilio SendGrid a try!
The following links will help you expand your knowledge of Django's email support and Twilio SendGrid:
- Sending Email (Django official documentation): This is the best resource if you want to learn about all the email features provided by Django, such as sending HTML formatted emails or including file attachments.
- TwilioQuest: This fun and educational game includes several missions designed around the different services and APIs. Play the SendGrid mission to familiarize yourself with the capabilities of this service.