Getting Photos from Mars with the NASA API
Tags: python, showdev, webdev
Published: 2021-03-03 11:58:08

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

![Perseverance rover](https://anvil.works/blog/img/photos-from-mars/perseverance.jpg)

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](https://www.nasa.gov/directorates/heo/scan/services/networks/deep_space_network/about/) -- NASA provides a [public API](https://api.nasa.gov) 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](https://anvil.works?utm_source=crosspost:dev.to:/blog/photos-from-mars), 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](https://anvil.works/blog/img/photos-from-mars/app-screenshot.jpg) **Open the app: Pictures from Mars**](https://photos-from-mars.anvil.app)
<figcaption>
See the latest photos from all the Mars rovers, and get an email as soon as new ones arrive.</figcaption>

---

## Getting the Photos

According to the [API docs](https://github.com/chrisccerami/mars-photo-api), you can get all Perseverance's latest photos from this URL:
<br><small>[https://api.nasa.gov/mars-photos/api/v1/rovers/perseverance/latest_photos?api_key=DEMO_KEY](https://api.nasa.gov/mars-photos/api/v1/rovers/perseverance/latest_photos?api_key=DEMO_KEY)</small>

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:

```json
{
    "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](https://anvil.works/articles/drag-and-drop-builder?utm_source=crosspost:dev.to:/blog/photos-from-mars) to set up an `Image` component, and some `Label`s to display information about the photo.

![Building a simple UI with drag and drop](https://anvil-website-static.s3.eu-west-2.amazonaws.com/articles/photos-from-mars/build-ui.gif)

Then I wrote a [server function](https://anvil.works/docs/server?utm_source=crosspost:dev.to:/blog/photos-from-mars) to retrieve a photo. It started off really simple:

```python
@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:

![Writing code to display a photo](https://anvil-website-static.s3.eu-west-2.amazonaws.com/articles/photos-from-mars/display-image-shortened.gif?really)

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](#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](https://anvil.works/docs/background-tasks/scheduled-tasks?utm_source=crosspost:dev.to:/blog/photos-from-mars), to check for new photos, and the [Email Service](https://anvil.works/docs/email?utm_source=crosspost:dev.to:/blog/photos-from-mars), to send them out. Plus, of course, a [database table](https://anvil.works/docs/data-tables?utm_source=crosspost:dev.to:/blog/photos-from-mars) to store the email addresses:

![The Data Table storing email subscribers](https://anvil.works/blog/img/photos-from-mars/data-table.png?utm_source=crosspost:dev.to:/blog/photos-from-mars)

Every 10 minutes, the Scheduled Task collects the latest photos from every rover:

```python
@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()`](https://anvil.works/docs/email/attachments?utm_source=crosspost:dev.to:/blog/photos-from-mars). 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 >>](https://anvil.works/build#clone:T6VAXJF5RA2JEYIS=B4NKQJ45BLBBKI4DBNOGSMKM)

---

Or you can check out the app again, now that you know how it works:

[![App Screenshot](https://anvil.works/blog/img/photos-from-mars/app-screenshot.jpg) **Open the app: Pictures from Mars**](https://photos-from-mars.anvil.app)
<figcaption>
See the latest photos from all the Mars rovers, and get an email as soon as new ones arrive.</figcaption>


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](https://twitter.com/meredydd)!

## More about Anvil

If you're new here, welcome! [Anvil](https://anvil.works/?utm_source=crosspost:dev.to:/blog/photos-from-mars) 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 >>](https://anvil.works/build?utm_source=crosspost:dev.to:/blog/photos-from-mars)

## [See tutorials >>](https://anvil.works/learn?utm_source=crosspost:dev.to:/blog/photos-from-mars)