Many applications have the need to send emails programmatically at specific times or regular intervals. In Python this is possible with the use of the Twilio SendGrid API for sending emails as well as Redis Queue and RQ Scheduler. Let's walk through how to schedule an email step by step.
Prerequisites and dependencies
Make sure you have the following before moving on:
- Python 3 installed on your machine
- A free SendGrid account
- An email address to test out this project
Here is a guide you can follow for setting up your development environment if you are going to be doing more web development with Python in general and are unfamiliar with things like virtual environments.
Before writing code, you'll need to install some dependencies:
- The SendGrid Python library for sending emails
- RQ Scheduler - a lightweight, elegant solution built on top of another tool with a low barrier to entry called Redis Queue
Make sure you create and activate a virtual environment, and then install these with the following command:
pip install sendgrid rq-scheduler==0.11.0
The RQ and Redis Python modules will install as dependencies with RQ Scheduler. In order for RQ to work, you'll also need to install Redis on your machine. That can be done with the following commands using wget
:
wget https://download.redis.io/releases/redis-6.2.6.tar.gz
tar xzf redis-6.2.6.tar.gz
cd redis-6.2.6
make
Run Redis in a separate terminal window on the default port with the command src/redis-server
from the directory where it's installed.
Sign up for SendGrid and create an API key
When creating a SendGrid account, you can choose the free tier for the purpose of this tutorial. Once you have an account, you need to create an API key as seen in this screenshot. You can name it whatever you want, but once it is created make sure you save it before moving on!
A good way to save this API key is to set it as an environment variable that you can access from your Python code in order to avoid writing it directly in your code. Set the value of the SENDGRID_API_KEY
environment variable to be the API key from your SendGrid account. It still doesn't hurt to make note of it elsewhere though, because you cannot view it again. Here's a useful tutorial if you need help setting environment variables. We will use this API key later on.
Sending an Email with Python
Now that you have a SendGrid account and API key, you're ready to dive into some code and send emails! Start by opening your terminal and navigating to the directory where you want your project to live.
Now create a file called send_email.py
in this directory and add the following code to it:
import os
from sendgrid import SendGridAPIClient
from sendgrid.helpers.mail import Mail
message = Mail(
from_email='from_email@example.com',
to_emails='to@example.com',
subject='Sending with Twilio SendGrid is Fun',
html_content='<strong>and easy to do anywhere, even with Python</strong>')
sg = SendGridAPIClient(os.environ.get('SENDGRID_API_KEY'))
response = sg.send(message)
print(response.status_code, response.body, response.headers)
Before running this code, remember to replace the to_emails
value with your own email address to verify that your code worked correctly. If the SendGrid API key environment variable is set, then this code should work correctly.
Note that in production applications, it's recommended to verify your Sender Identity by completing Domain Authentication. A Sender Identity represents your 'From' email address—the address your recipients see as the sender of your emails. For a step-by-step tutorial on this check out: How to set up domain authentication for Twilio SendGrid.
Finally, in your terminal use the following command to run this code to send yourself a picture of an email:
python send_email.py
Check your inbox and you should see something like this!
Scheduling a task with RQ Scheduler
You can use RQ Scheduler to execute specific code at a specific time by creating a Scheduler
object and passing it a function to execute, a Python datetime
, and any arguments you want to pass to the function.
For example:
from datetime import datetime
from redis import Redis
from rq_scheduler import Scheduler
from some_module import arbitrary_function
scheduler = Scheduler(connection=Redis()) # Get a scheduler for the "default" queue
scheduler.enqueue_at(datetime(2020, 1, 1), arbitrary_function) # Date time should be in UTC
So first, we need a function to pass to our Scheduler
object. Let's take the code from before in send_email.py
and put it in a function:
import os
from sendgrid import SendGridAPIClient
from sendgrid.helpers.mail import Mail
def send_email(from_email, to_email):
message = Mail(
from_email=from_email,
to_emails=to_email,
subject='Sending with Twilio SendGrid is Fun',
html_content='<strong>and easy to do anywhere, even with Python</strong>')
sg = SendGridAPIClient(os.environ.get('SENDGRID_API_KEY'))
response = sg.send(message)
print(response.status_code, response.body, response.headers)
Now create another file for scheduling this function, called schedule_email.py
, with the following code:
import datetime
from redis import Redis
from rq_scheduler import Scheduler
import send_email
scheduler = Scheduler(connection=Redis()) # Get a scheduler for the "default" queue
if __name__ == '__main__':
scheduler.enqueue_at(datetime.datetime.now(), send_email.send_email,
'from_email@example.com', 'to_email@example.com')
Make sure to replace to_email@example.com
with your own email address. In this example we're just using a datetime.now()
object so it will immediately schedule the email for testing purposes, but you can use whatever time you want. And if you want them to recur, you can put them in a loop and continue generating datetimes to execute this function.
Before being able to run this code, you have to make sure you're running a Redis server, an RQ worker, and the RQ Scheduler process all in other terminal windows. You should already have run the Redis server by using the command src/redis-server
from the directory where you installed Redis. Open two more terminal windows, and in both of them navigate to the directory where your code exists and activate your virtual environment for this project. In one window run the command rqworker
and in another run the command rqscheduler
.
With this done, you should be ready to run your code to schedule an email:
python schedule_email.py
What's Next?
In this tutorial, we went through how to send an email with SendGrid and how to schedule them in Python using RQ Scheduler. Now you can use RQ Scheduler for all of your Python scheduling needs, such as sending a notification when the International Space Station flies by a location. The possibilities are endless.
- Email: Sagnew@twilio.com
- Twitter: @Sagnewshreds
- GitHub: Sagnew
- Twitch (streaming live code): Sagnewshreds