DEV Community

loading...
Cover image for Getting Photos from Mars with the NASA API

Getting Photos from Mars with the NASA API

Meredydd Luff
Building things to help people build things. Founded Anvil.
・5 min read

Get the Latest Mars Photos, on the Web and In Your Inbox

Perseverance rover

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:

App Screenshot Open the app: Pictures from Mars

See the latest photos from all the Mars rovers, and get an email as soon as new ones arrive.

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"
    }
}
Enter fullscreen mode Exit fullscreen mode

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 Labels to display information about the photo.

Building a simple UI with drag and drop

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'])
Enter fullscreen mode Exit fullscreen mode

Now I can call it from my Python code that's running in the web browser, and display the photo in our UI:

Writing code to display a photo

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:

The Data Table storing email subscribers

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
  }

  # ...
Enter fullscreen mode Exit fullscreen mode

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:

App Screenshot Open the app: Pictures from Mars

See the latest photos from all the Mars rovers, and get an email as soon as new ones arrive.

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.

Try Anvil >>

See tutorials >>

Discussion (0)