Ensemble forecasts

action0.open_meteo.ensemble · Open-Meteo docs · EnsembleClient, preset to https://ensemble-api.open-meteo.com

GetV1Ensemble returns every member of an ensemble model run — dozens of slightly perturbed forecasts whose spread quantifies the uncertainty. The members arrive as dynamic JSON keys (temperature_2m_member01, …), which land in the response models’ typed catch-all field additional_properties:

from action0.client.backends.requests import RequestsBackend
from action0.open_meteo.ensemble import (
    EnsembleClient,
    GetV1Ensemble,
    GetV1EnsembleHourlyItem,
    GetV1EnsembleModelsItem,
)

with RequestsBackend() as backend:
    client = EnsembleClient(backend)
    runs = client.send(
        GetV1Ensemble(
            latitude="48.21",
            longitude="16.37",
            hourly=[GetV1EnsembleHourlyItem.TEMPERATURE_2M],
            models=[GetV1EnsembleModelsItem.DWD_ICON_SEAMLESS_EPS],
            forecast_days=1,
        )
    )

hourly = runs.hourly
assert hourly is not None and hourly.additional_properties is not None
members = {
    key: series
    for key, series in hourly.additional_properties.items()
    if key.startswith("temperature_2m_member")
}
print(len(members))  # 39 (ICON EPS)
noon = [series[12] for series in members.values()]
print(min(noon), max(noon))  # the uncertainty band at noon

Notes

  • hourly.time is a regular declared field; everything else — the control run (temperature_2m) and each ..._memberNN — sits in additional_properties: dict[str, list[float]], with the units in hourly_units.additional_properties.

  • models= is required practically: each entry is a specific ensemble system (DWD_ICON_SEAMLESS_EPS, ECMWF_IFS025_ENSEMBLE, …), and the member count depends on it.

  • Ensemble payloads are large — request only the variables and days you need.