Get the Latest Mars Photos, on the Web and In Your Inbox
Everyone's waiting on the next photos from Perseverance, NASA's latest Mars rover. I'll show you how to use NASA's API to get the latest images as soon as they arrive - and send them straight to your inbox!
We don't need our own Deep Space Network -- NASA provides a public API for all of its Mars rovers. So I wrote an app to fetch the latest photos from Perseverance, and its older sibling Curiosity.
I built the web app with Anvil, which means I could build everything in Python -- that includes the "front-end" parts (displaying images, choosing your rovers, entering your email address, and so on), as well as the "back-end" (accessing NASA's APIs and sending out emails).
Take a look:
Getting the Photos
According to the API docs, you can get all Perseverance's latest photos from this URL:
https://api.nasa.gov/mars-photos/api/v1/rovers/perseverance/latest_photos?api_key=DEMO_KEY
The photos arrive as an array of JSON objects, describing everything about a photo. That includes which of the rover's cameras took it, the sol (and Earth date) of the photo, as well as a URL to download the image itself. Here's one:
{
"id": 804712,
"sol": 2,
"earth_date": "2021-02-20",
"camera": {
"id": 40,
"name": "MCZ_RIGHT",
"full_name": "Mast Camera Zoom - Right",
"rover_id": 8
},
"img_src": "https://mars.nasa.gov/mars2020-raw-images/pub/ods/surface/sol/00002/ids/fdr/browse/zcam/ZRF_0002_0667131195_000FDR_N0010052AUT_04096_0260LUJ01_1200.jpg",
"rover": {
"id": 8,
"name": "Perseverance",
"landing_date": "2021-02-18",
"launch_date": "2020-07-30",
"status": "active"
}
}
Displaying the Photos
The first thing to build is a web app that displays a random photo. I used Anvil's drag and drop designer to set up an Image
component, and some Label
s to display information about the photo.
Then I wrote a server function to retrieve a photo. It started off really simple:
@anvil.server.callable
def get_photo():
resp = requests.get(f"https://api.nasa.gov/mars-photos/api/v1/rovers/perseverance/latest_photos?api_key={API_KEY}").json()
return random.choice(resp['latest_photos'])
Now I can call it from my Python code that's running in the web browser, and display the photo in our UI:
Of course, the most recent image might not be the most interesting. What's more, there is more than one rover on Mars, and they send back images on their own schedules. So I expanded the app to look backwards through time until it can find at least 50 photos from each rover, then send them all to the front end, which shuffles them when the user clicks a button. (You can see how this works in the source code.)
Sending Automatic Emails
Of course, I could see all these photos on NASA's website if I wanted. I want to know when we get new photos! Specifically, I want to get them by email. We'll need two new features for this: Scheduled Tasks, to check for new photos, and the Email Service, to send them out. Plus, of course, a database table to store the email addresses:
Every 10 minutes, the Scheduled Task collects the latest photos from every rover:
@anvil.server.background_task
def send_photos():
latest_photos = {
rover: anvil.http.request(f"https://api.nasa.gov/mars-photos/api/v1/rovers/{rover}/latest_photos?api_key={API_KEY}", json=True)["latest_photos"]
for rover in ROVERS
}
# ...
Then we look through every subscriber, and compare the date of our last email to them with the earth_date
of the most recent photos. If the photos are more recent, we pick one and send it as an email attachment, using anvil.email.send()
. The emails are grouped by day, so we will never send more than one email a day to any subscriber.
The actual logic for this is a little cumbersome, but if you want to see it in more detail then you can check out the full source code:
Source Code
You can open the app in the Anvil editor and see its source code here (requires a free Anvil account):
Open Source Code >>
Or you can check out the app again, now that you know how it works:
If you can think of something else cool to do with the Mars rover images, or NASA's APIs, please put it in the comments, or tweet it to me @meredydd!
More about Anvil
If you're new here, welcome! Anvil is a platform for building full-stack web apps with nothing but Python. No need to wrestle with JS, HTML, CSS, Python, SQL and all their frameworks β just build it all in Python.
Top comments (0)