How clean is the air right now?
TEMPO is a NASA instrument in geostationary orbit that measures air pollution over North America every hour. The challenge was to turn data like that into something people could act on. In a weekend, our team of four built a Flask dashboard for ten US cities. It pulls the current air quality index from the EPA, fetches local weather, runs a random forest, and plots it all on a map.
The dashboard and the map.
Captured by running the original code again in November 2026. The EPA retired the AirNow API on 1 October 2026, so the app can no longer get live readings. Every number below comes from its fallbacks: the model's estimate with default weather.
From a city name to a coloured dot.
Looking back a year later.
Going through the code again for this page, I found that only some of what the dashboard shows is measured. Here's an honest breakdown.
| What the dashboard shows | Where it actually comes from | |
|---|---|---|
| Current AQI | EPA AirNow, live (until the API was retired in Oct 2026) | real |
| Weather | Open-Meteo, live, with fixed defaults whenever a request fails | real |
| Model's training labels | One live reading per city, scaled by weather, rush-hour and weekend factors I wrote by hand, plus random noise | synthetic |
| Model accuracy | Measures how well the forest learned those hand-written factors, not real air | misleading |
| Past week and five-day outlook | Today's reading multiplied by fixed weekday and trend factors | synthetic |
| NO₂ column | The AQI multiplied by a constant | not TEMPO |
A TEMPO NO₂ data file was downloaded for the project, but the code never reads it. The satellite the project is named after never reaches the dashboard.
What I'd build now.
The plumbing held up: live APIs with fallbacks, a model behind an endpoint, a map. The data science behind it doesn't hold up yet, and this is what I'd change.
Open the Level-2 NO₂ granules with xarray, keep only good-quality pixels, and sample the column over each city.
Train on months of archived AirNow readings, not on numbers derived from a single live one.
Test on days the model has never seen, and report how much it beats “same as yesterday”. If it doesn't, say so.
That's the habit I took into my research afterwards: weather meta-learning is evaluated against climatology on held-out regions.