Weather Daily
Daily weather by city worldwide from Open-Meteo: temperature, precipitation, wind and more.
weather_daily — the dataset name to pass to the Obscura API.
What one row means
One row is one UTC calendar day's aggregated weather (daily max/min temperature and total precipitation) for one GeoNames city. DERIVED, not fetched: the `weather_rollup` task aggregates `weather_hourly` (Open-Meteo ERA5 hourly archive) day-by-day in-database, so every value here is a function of the hours stored in `weather_hourly` and can be reproduced from them exactly. (Rows written before that rollup came from a since-removed collector that called Open-Meteo's keyless `daily=` endpoints directly.)
One row per (location, weather_date).
Derived in-database from weather_hourly.
Point-in-time availability
Every Obscura dataset carries available_date: the calendar day the publisher made the row
available, day-of, with no session rounding. It is the one column a backtest filters on, and it means the
same thing on every dataset in the catalog.
For weather_daily: published: available_date = weather_date, the observation/target day itself (real-time daily weather).
Refresh cadence
Obscura refreshes weather_daily every 6 hours — the most frequent scheduled job that re-collects or re-exports it. This is Obscura's own pipeline cadence, not the upstream publisher's release schedule; when a row became public is recorded per row in available_date.
Schema — 8 columns
The full public column list for weather_daily, with the meaning of every field. The same
schema is served unauthenticated at https://api.obscura.trade/v1/catalog/weather_daily.
| Column | Type | Description |
|---|---|---|
| location | text · not null | City label for the row, part of the composite primary key. Rolled-up rows carry `weather_hourly.location` verbatim — the GeoNames key "{asciiname}, {ISO country_code}" (e.g. "London, GB") — so the two tables join 1:1 on it. Rows predating the rollup may still hold the legacy collector's bare city name ("London"), which does NOT join. |
| weather_date | date · not null | The UTC calendar day the temp/precip values describe — the day the underlying hours were grouped by (`(event_time AT TIME ZONE 'UTC')::date`), not a local-time day. Rehomed from the old, misused `available_date` column; this is the period/event date, part of the composite primary key with `location`. Also drives `available_date` (published same-day). |
| latitude | double precision · not null | City-centroid latitude carried through from `weather_hourly` (GeoNames cities15000, NOT the ERA5 grid point it snapped to); static per location and repeated on every row. |
| longitude | double precision · not null | City-centroid longitude, paired with latitude; same static-per-location, repeated-per-row characteristic as latitude. |
| temp_max_c | double precision | Daily maximum 2m air temperature in Celsius for `weather_date`: `max(weather_hourly.temp_c)` over the day's hours. Nullable: null when every hour of that day/location is missing a temperature. |
| temp_min_c | double precision | Daily minimum 2m air temperature in Celsius for `weather_date`: `min(weather_hourly.temp_c)` over the day's hours. |
| precipitation_mm | double precision | Total daily precipitation in millimeters for `weather_date`: `sum(weather_hourly.precip_mm)` over the day's hours. A legitimate 0 (no precipitation that day) is not the same as null (no hour carried a value at all); both occur in the live data. A day whose hours are still being filled sums only the hours present, and is rewritten when the rest land. |
| available_date | date | PUBLIC-availability date, DB-generated (STORED) as `weather_date` itself — this dataset is treated as published same-day (real-time daily weather), so availability and the observation day coincide. Read-only; the point-in-time column to filter/join on. |
Access weather_daily
Two delivery paths, one identifier. Both require an Obscura account and an active subscription; the catalog entry and the schema above are public.
import obscura
client = obscura.Client("obs_live_…")
df = client.query(
dataset="weather_daily",
start="2024-01-01",
)
Create a free account Browse all 95 datasets
Frequently asked questions
What is in the weather_daily dataset?
Daily weather by city worldwide from Open-Meteo: temperature, precipitation, wind and more. One row is one UTC calendar day's aggregated weather (daily max/min temperature and total precipitation) for one GeoNames city. DERIVED, not fetched: the `weather_rollup` task aggregates `weather_hourly` (Open-Meteo ERA5 hourly archive) day-by-day in-database, so every value here is a function of the hours stored in `weather_hourly` and can be reproduced from them exactly. (Rows written before that rollup came from a since-removed collector that called Open-Meteo's keyless `daily=` endpoints directly.)
How do I avoid look-ahead bias with weather_daily?
Filter on weather_daily.available_date, the day the publisher made the row public. For this dataset that date is derived as follows — published: available_date = weather_date, the observation/target day itself (real-time daily weather). A query of the form WHERE available_date <= '<as-of date>' never sees a row before it existed.
In what formats can I get weather_daily?
As a Parquet bulk export (POST https://api.obscura.trade/v1/download) or as JSON from the typed query API (POST https://api.obscura.trade/v1/query), both with dataset="weather_daily". The column schema is public at https://api.obscura.trade/v1/catalog/weather_daily.
How often is weather_daily updated?
Obscura refreshes weather_daily on a every 6 hours schedule — that is the most frequent scheduled job that re-collects or re-exports the table. It is Obscura's own pipeline cadence, not the upstream publisher's release schedule; when the publisher makes a row available is described by the availability rule above, and is recorded per row in available_date.