TEMPO — client.tempo¶
NASA TEMPO satellite air-quality data — hourly gridded column-density measurements for the San Joaquin Valley, covering nitrogen dioxide (no2), total ozone (o3tot), formaldehyde (hcho), and cloud fraction (cldo4, QA-only).
from sjvair import SJVAirClient
with SJVAirClient() as client:
latest = client.tempo.latest('no2')
print(latest)
{
"sqid": "gY8kw2",
"timestamp": "2026-07-12T18:00:00Z",
"is_final": False,
"version": "V03",
"bounds": {"type": "Polygon", "coordinates": [["..."]]},
"preview_url": "https://sjvair.com/media/tempo/2026/07/no2-2026071218.png",
}
Methods¶
Method |
Signature |
|---|---|
|
Product metadata: label, units, legend color stops. Excludes |
|
Iterate granules for one product. Defaults to today (America/Los_Angeles), falling back to yesterday if it’s before noon and today’s data isn’t ready. |
|
The single most recent granule for one product. |
|
Hourly point-value series at a coordinate. |
|
Hourly zonal-stats series over a region boundary. |
product is one of no2, o3tot, hcho, cldo4.
# NO2 point series over a day at a coordinate
series = client.tempo.point(
'no2', 36.7468, -119.7726,
start='2026-07-11T00:00:00', end='2026-07-12T00:00:00',
)
[
{"timestamp": "2026-07-11T00:00:00Z", "is_final": True, "version": "V03", "value": 1.4e15},
{"timestamp": "2026-07-11T01:00:00Z", "is_final": True, "version": "V03", "value": 1.6e15},
# ...one entry per hour; value is None where that pixel is masked/nodata
]
region() scopes to a region by its sqid (same ID used everywhere else in this client):
series = client.tempo.region('no2', region_id='r6phe')
Each region() row is {timestamp, is_final, version, count, sum, mean, stddev, min, max} — zonal stats over the pixels inside the region’s boundary for that hour.
granules() filters happen server-side: date, timestamp/timestamp__lt/__lte/__gt/__gte, is_final, version/version__iexact. Omitting date/timestamp defaults to today (America/Los_Angeles), falling back to yesterday if it’s before noon and today’s data isn’t ready yet.
point()/region() accept start/end as ISO 8601 timestamps (max 90-day range) — omit both to default to today’s available granules.