This content originally appeared on Twilio Blog and was authored by Sam Agnew
With cool APIs like Open Notify we can programmatically access the location of the International Space Station to determine when it is flying by a specific location, and with Twilio SendGrid we can send an email notification when this occurs.
Let's walk through how to do this in Python using Redis Queue to schedule the email.
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
- Requests - for making HTTP requests
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 requests==2.26.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.
Accessing the International Space Station's location
Let’s begin by writing code that will call the Open Notify API for a given set of coordinates and print the next time that the ISS will fly by that latitude and longitude.
Create a file called iss.py
(an “International Space Station” module) in the directory where you want your code to live, and add the following function:
from datetime import datetime
import pytz
import requests
ISS_URL = 'http://api.open-notify.org/iss-pass.json'
def get_next_pass(lat, lon):
location = { 'lat': lat, 'lon': lon }
response = requests.get(ISS_URL, params=location).json()
if 'response' in response:
next_pass = response['response'][0]['risetime']
next_pass_datetime = datetime.fromtimestamp(next_pass, tz=pytz.utc)
print('Next pass for {}, {} is: {}'
.format(lat, lon, next_pass_datetime))
return next_pass_datetime
else:
print('No ISS flyby can be determined for {}, {}'.format(lat, lon))
The get_next_pass
function in this code will make a request to the Open Notify API with a given latitude and longitude, check to see if there is a valid response, and then convert the timestamp received from the API into a Python datetime object and print the corresponding time that the ISS will fly overhead next.
To test this code, open a Python shell and run the following two lines. For this example we will use the Twilio Headquarters in San Francisco as our test location (latitude: 37.788052, longitude: -122.391472):
from iss import get_next_pass
get_next_pass(37.788052, -122.391472)
You should see something along the lines of: Next pass for 37.788052, -122.391472 is: 2021-12-09 23:58:11+00:00
with an appropriate timestamp.
Now we can move on to writing code to send an email.
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 can update iss.py
to include code to send an email:
from datetime import datetime
import os
import pytz
import requests
from sendgrid import SendGridAPIClient
from sendgrid.helpers.mail import Mail
ISS_URL = 'http://api.open-notify.org/iss-pass.json'
def send_email(from_email, to_email, body):
message = Mail(
from_email=from_email,
to_emails=to_email,
subject='International Space Station passing by!',
html_content=body)
sg = SendGridAPIClient(os.environ.get('SENDGRID_API_KEY'))
response = sg.send(message)
print(response.status_code, response.body, response.headers)
def get_next_pass(lat, lon):
location = { 'lat': lat, 'lon': lon }
response = requests.get(ISS_URL, params=location).json()
if 'response' in response:
next_pass = response['response'][0]['risetime']
next_pass_datetime = datetime.fromtimestamp(next_pass, tz=pytz.utc)
print('Next pass for {}, {} is: {}'
.format(lat, lon, next_pass_datetime))
return next_pass_datetime
else:
print('No ISS flyby can be determined for {}, {}'.format(lat, lon))
Remember to make sure the SendGrid API key environment variable is set before trying to run this code.
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.
If you want to test this code, open up a Python shell and run the following, replacing the to_email
argument with your own email address:
from iss import send_email
send_email('from_email@example.com', 'your_email@example.com', 'Look up!')
You should receive an email telling you to look up after running this code.
Scheduling a task with RQ Scheduler
Now that we have a function that provides us with a datetime, and a function that sends an email, we can use RQ Scheduler. Create another file called schedule_notification.py
, and add the following code to it:
from datetime import datetime
from redis import Redis
from rq_scheduler import Scheduler
import iss
scheduler = Scheduler(connection=Redis()) # Get a scheduler for the "default" queue
# Change these latitude and longitude values for any location you want.
next_pass = iss.get_next_pass(37.788052, -122.391472)
if next_pass:
scheduler.enqueue_at(next_pass, iss.send_email,
'from_email@example.com', 'your_email@example.com',
'Look up! The ISS is flying above you!')
This is just a quick script that calls the other functions you wrote, one to find out when the ISS is passing by your location next, and another that will send you an email. In this example, I'm using the coordinates for the Twilio office in San Francisco, but you can change the latitude and longitude to be wherever you are.
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 or as background processes. 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 a notification:
python schedule_notification.py
Now all you have to do is wait...
Traveling through time
This is great, but it's understandable if you don't feel like waiting around just to see if your code works. If you want instant gratification, we can use the time traveling method. On Unix based systems, you can change your system time using the date command.
If the space station is supposed to fly by on December 5th, 2019 at 4:02, then on Linux you can run date -s "12/05/2019 03:02:00"
. On OSX you would run date 1205160219
(you can even use the -u
argument if you want to use a UTC time zone, which corresponds to the datetime your Python code is printing). If all else fails, there are also GUI options to change your computer's time on most operating systems.
On OSX you can set (and reset) this by opening "Date & Time" in your System Preferences
If you want to receive notifications every time the ISS passes by instead of just once, you can schedule another notification after each message by modifying your send_email
function in iss.py
and adding the appropriate import statements:
from redis import Redis
from rq_scheduler import Scheduler
scheduler = Scheduler(connection=Redis()) # Get a scheduler for the "default" queue
def send_email(from_email, to_email, body):
message = Mail(
from_email=from_email,
to_emails=to_email,
subject='International Space Station passing by!',
html_content=body)
sg = SendGridAPIClient(os.environ.get('SENDGRID_API_KEY'))
response = sg.send(message)
print(response.status_code, response.body, response.headers)
scheduler.enqueue_at(next_pass, iss.send_email,
'from_email@example.com', 'your_email@example.com',
'Look up! The ISS is flying above you!')
To Infinity and Beyond
Now that you can receive emails whenever the International Space Station flies by, you can use RQ Scheduler for all of your Python scheduling needs. The possibilities are endless.
For another example of a project that uses RQ, check out this post on how to create a phone number that plays computer generated music that sounds like the soundtracks of old Nintendo games.
- Email: Sagnew@twilio.com
- Twitter: @Sagnewshreds
- GitHub: Sagnew
- Twitch (streaming live code): Sagnewshreds
This content originally appeared on Twilio Blog and was authored by Sam Agnew
Sam Agnew | Sciencx (2021-12-10T01:32:12+00:00) Scheduling International Space Station emails in Python with SendGrid and Redis Queue. Retrieved from https://www.scien.cx/2021/12/10/scheduling-international-space-station-emails-in-python-with-sendgrid-and-redis-queue/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.