API#
DWD#
DMO#
- class DwdDmoRequest
Bases:
wetterdienst.model.request.TimeseriesRequestImplementation of sites for dmo sites.
- metadata
None
- _values
None
- issue: str | datetime.datetime | wetterdienst.provider.dwd.dmo.api.DwdForecastDate
None
- station_group: Literal[single_stations, all_stations] | wetterdienst.provider.dwd.dmo.api.DwdDmoStationGroup | None
None
- lead_time: Literal[short, long] | wetterdienst.provider.dwd.dmo.api.DwdDmoLeadTime | None
None
- _coverage_cache: dict[str, set[str] | None]
‘field(…)’
- _placemark_cache: dict[str, polars.DataFrame | None]
‘field(…)’
- _url
‘https://www.dwd.de/DE/leistungen/opendata/help/schluessel_datenformate/kml/dmo_stationsliste_txt.asc…’
- _base_columns: ClassVar
[‘resolution’, ‘dataset’, ‘station_id’, ‘icao_id’, ‘start_timestamp’, ‘end_timestamp’, ‘latitude’, ‘…
- static adjust_datetime(datetime_: datetime.datetime) datetime.datetime
Adjust datetime to DMO’s release hours, which are 00 and 12 UTC.
Datetime is floored to closest release time e.g. if hour is 14, it will be rounded to 12
- classmethod discover(resolutions: str | wetterdienst.metadata.resolution.Resolution | wetterdienst.model.metadata.ResolutionModel | collections.abc.Sequence[str | wetterdienst.metadata.resolution.Resolution | wetterdienst.model.metadata.ResolutionModel] | None = None, datasets: str | wetterdienst.model.metadata.DatasetModel | collections.abc.Sequence[str | wetterdienst.model.metadata.DatasetModel] | None = None) dict
Discover metadata as
TimeseriesRequest.discoverdoes, with each parameter’s lead times.lead_timeslists the lead times whose run carries the parameter,shortbeforelong, so a caller can offer only what thelead_timeit sends will answer: values refuse a parameter asked for by name that the run does not carry (GH-1976). An added key, the others are as they were (GH-2256).
- classmethod available_issues(station_id: str, settings: wetterdienst.settings.Settings, *, dataset: wetterdienst.model.metadata.DatasetModel | str = 'icon', station_group: wetterdienst.provider.dwd.dmo.api.DwdDmoStationGroup | str | None = None, lead_time: wetterdienst.provider.dwd.dmo.api.DwdDmoLeadTime | str | None = DwdDmoLeadTime.SHORT) list[datetime.datetime]
Return the run start times DWD publishes for one product, in ascending UTC order.
Answers for a particular product, because the values path reads a particular product: this listed
icon/single_stations/<id>/kmz/whatever the request was for, and named issues that the request would then reject (GH-1956). Two ways, both measured against the live server:icon_eu’sall_stationspublishes only the078lead time, so an issue advertised from a168file metIndexError: Unable to find a 168 h forecast within ...; and a station the shared catalogue listed foricon_euwithouticon_eucovering it has no single-station directory, so every issue this advertised for it resolved to an empty frame – GH-1964, which narrowed the catalogue to the product. The directory comes from_dmo_kmz_pathnow, which is the one the values path reads.The defaults are
DwdDmoRequest’s own, so what this answers with no arguments is what a request built with no arguments accepts.lead_timedefaulted toNoneuntil GH-2009, and so pooled the runs of both lead times:wetterdienst issuesnamed runs of the168file that the defaultvaluesrequest then rejected. Passlead_time=Noneto list the runs of every lead time together, which is a question about the directory rather than about anything that can be asked for.Args: station_id: The station to answer for, where the product is published per station. settings: The settings to list with. dataset: The DMO product –
iconoricon_eu, or theDatasetModelitself. station_group:single_stations(the default) orall_stations. lead_time:short(078, the default) orlong(168);Nonelists every lead time.Returns: The run start times, tz-aware UTC, deduplicated and ascending.
- __post_init__() None
Post-initialize the DwdDmoRequest class.
- _with_stations_the_catalogue_omits(df_dataset: polars.DataFrame, covered: set[str], dataset_name_original: str) polars.DataFrame
Add the stations a product forecasts for that
dmo_stationsliste_txt.ascdoes not list.135 of them for
icon, 132 foricon_eu(measured 2026-09-24), and they could not be asked for at all: absent from the catalogue, they were filtered out of every request even though their forecasts are published and fetch with HTTP 200. The catalogue is the only source of an ICAO id, so it stays the source for the stations it does list, and these are described from the run instead – with no ICAO id, which is already a value the catalogue produces for the stations it writes as----(GH-1966).
- static _narrows_rather_than_empties(covered: set[str], df_raw: polars.DataFrame, dataset_name_original: str) bool
Say whether a coverage listing names stations this catalogue has, so filtering by it narrows.
_covered_station_idsreads directory names, and a directory tree that stops being one directory per station still yields names: weresingle_stations/reorganised into a subdirectory per lead time, the listing would come back as{"078", "168"}, pass the emptiness check, and filter every station in the catalogue out. The result is an empty stations frame with nothing raised and nothing logged – the same indistinguishable silence GH-1964 and GH-1947 are about, arriving through the very change that was meant to end it.One station in common is enough: the products genuinely cover different subsets, so anything stricter would fire on the real disagreement this exists to represent.
- _station_metadata_from_placemarks(dataset_name_original: str) polars.DataFrame | None
Describe the stations a product forecasts for, from its newest
all_stationsrun.Read only when the catalogue is missing a station the product covers, so that a catalogue DWD completes stops costing anything, and cached per request for the same reason
_covered_station_idsis.
- _read_station_metadata_from_placemarks(dataset_name_original: str) polars.DataFrame | None
Do the fetch
_station_metadata_from_placemarkscaches, or None if it could not be done.
- _covered_station_ids(dataset_name_original: str) set[str] | None
Read which stations one DMO product forecasts for, or None if that could not be read.
The catalogue at
_urlis one list for both products and matches neither. Of its 5811 stationsiconcovers 5622 andicon_eu3556 (measured 2026-09-24), so a request foricon_euadvertised 2255 stations that can only ever answer with an empty frame – which from the caller’s side is indistinguishable from a station whose forecast is merely missing right now, and from the swallowed listing GH-1947 was about (GH-1964).None rather than an empty set when the listing cannot be read, because the two mean opposite things: the caller keeps the whole catalogue for a listing it could not read, rather than answering that a product has no stations at all.
- _read_covered_station_ids(dataset_name_original: str) set[str] | None
Do the listing
_covered_station_idscaches.
- _all() polars.LazyFrame
Get all stations from DMO.
Mosmix#
- class DwdMosmixRequest
Bases:
wetterdienst.model.request.TimeseriesRequestRequest MOSMIX data from the DWD server.
- metadata
None
- _values
None
- issue: str | datetime.datetime | wetterdienst.provider.dwd.mosmix.api.DwdForecastDate
None
- station_group: wetterdienst.provider.dwd.mosmix.api.DwdMosmixStationGroup
None
- _url
None
- _base_columns: ClassVar
[‘resolution’, ‘dataset’, ‘station_id’, ‘icao_id’, ‘start_timestamp’, ‘end_timestamp’, ‘latitude’, ‘…
- classmethod available_issues(station_id: str, settings: wetterdienst.settings.Settings) list[datetime.datetime]
Return datetimes for which MOSMIX L single-station files exist on DWD’s server.
The list is sorted in ascending order and contains only unique UTC datetimes. Only MOSMIX_L single-station files are considered; the LATEST symlink is excluded.
- __post_init__() None
Post-initialization of the DwdMosmixRequest class.
- _all() polars.LazyFrame
Read the MOSMIX station catalog from the DWD server and return a DataFrame.
Observation#
- class DwdObservationRequest
Bases:
wetterdienst.model.request.TimeseriesRequestRequest class for DWD observation data.
- metadata
None
- _values
‘cast(…)’
- _history
‘cast(…)’
- _selects_by_period
True
- property interval: portion.Interval | None
Interval of the request.
- property _historical_interval: portion.Interval
Interval of historical data release schedule.
Historical data is typically release once in a year somewhere in the first few months with updated quality
- property _recent_interval: portion.Interval
Interval of recent data release schedule.
Recent data is released every day somewhere after midnight with data reaching back 500 days.
- property _now_interval: portion.Interval
Interval of now data release schedule.
Now data is released every hour (near real time) reaching back to beginning of the previous day.
- _get_periods() set[wetterdienst.metadata.period.Period] | None
Get periods based on the interval of the request.
- static _parse_station_id(series: polars.Series) polars.Series
- filter_by_station_id(station_id: str | int | tuple[str, ...] | tuple[int, ...] | list[str] | list[int]) wetterdienst.model.result.StationsResult
Filter by station id.
- classmethod describe_fields(dataset: str | collections.abc.Sequence[str] | wetterdienst.model.metadata.ParameterSearch | wetterdienst.model.metadata.DatasetModel, period: str | wetterdienst.metadata.period.Period, language: Literal[en, de] = 'en') dict
Describe fields of a dataset.
- _all() polars.LazyFrame
:return:
Radar#
- class DwdRadarValues(parameter: str | wetterdienst.provider.dwd.radar.metadata.parameter.DwdRadarParameter, site: wetterdienst.provider.dwd.radar.sites.DwdRadarSite | None = None, fmt: wetterdienst.provider.dwd.radar.metadata.DwdRadarDataFormat | None = None, subset: wetterdienst.provider.dwd.radar.metadata.DwdRadarDataSubset | None = None, elevation: int | None = None, start: str | datetime.datetime | wetterdienst.provider.dwd.radar.metadata.parameter.DwdRadarDate | None = None, end: str | datetime.datetime | datetime.timedelta | None = None, resolution: str | wetterdienst.metadata.resolution.Resolution | wetterdienst.provider.dwd.radar.metadata.DwdRadarResolution | None = None, period: str | wetterdienst.metadata.period.Period | wetterdienst.provider.dwd.radar.metadata.DwdRadarPeriod | None = None, settings: wetterdienst.settings.Settings | None = None)
API for DWD radar data requests.
Request radar data from different places on the DWD data repository.
https://opendata.dwd.de/weather/radar/composite/
https://opendata.dwd.de/weather/radar/sites/
https://opendata.dwd.de/climate_environment/CDC/grids_germany/daily/radolan/
https://opendata.dwd.de/climate_environment/CDC/grids_germany/hourly/radolan/
https://opendata.dwd.de/climate_environment/CDC/grids_germany/5_minutes/radolan/
Initialization
Initialize the request object.
Args: parameter: requested parameter (e.g. RADOLAN_CDC) site: requested site (e.g. DX_REFLECTIVITY) fmt: requested format (e.g. BINARY) subset: requested subset (e.g. RADOLAN) elevation: requested elevation (e.g. 10) start: start of the requested data end: end of the requested data resolution: requested resolution (e.g. MINUTE_5) period: requested period (e.g. RECENT) settings: settings for the request
- __new__(*args: object, **kwargs: object) Self
Refuse a renamed argument by naming the new one, as
TimeseriesRequestdoes.
- __str__() str
Return a string representation of the object.
- __eq__(other: object) bool
Compare two DwdRadarValues objects.
- adjust_datetimes() None
Adjust
startandendattributes to match minute marks for RadarParameter.RADOLAN_CDC is always published at HH:50. https://opendata.dwd.de/climate_environment/CDC/grids_germany/daily/radolan/recent/bin/
RW_REFLECTIVITY is published each 10 minutes. https://opendata.dwd.de/weather/radar/radolan/rw/
RQ_REFLECTIVITY is published each 15 minutes. https://opendata.dwd.de/weather/radar/radvor/rq/
All other radar formats are published in intervals of 5 minutes. https://opendata.dwd.de/weather/radar/composit/fx/ https://opendata.dwd.de/weather/radar/sites/dx/boo/
- _attach_bufr(result: wetterdienst.provider.dwd.radar.api.RadarResult) None
Attach the parsed BUFR contents to
result.dfwhenread_bufris enabled.No-op unless the request is for BUFR data and
Settings.read_bufris set. Requires the optional eccodes + pdbufr dependencies; a missing dependency or a parse error is logged and leavesresult.dfasNonerather than failing the whole query.
- query() collections.abc.Iterator[wetterdienst.provider.dwd.radar.api.RadarResult]
Query radar data from the DWD server.
- static _should_cache_download(url: str) bool
Determine whether this specific result should be cached.
Here, we don’t want to cache any files containing “-latest-” in their filenames.
Args: url: URL of the file to be downloaded
Returns: Whether the file should be cached or not
- _download_generic_data(url: str) collections.abc.Iterator[wetterdienst.provider.dwd.radar.api.RadarResult]
Download radar data.
- _download_radolan_data(url: str, start_date: datetime.datetime, end_date: datetime.datetime) collections.abc.Iterator[wetterdienst.provider.dwd.radar.api.RadarResult]
Download RADOLAN_CDC data for a given datetime.
- static _extract_radolan_data(archive_in_bytes: io.BytesIO) collections.abc.Iterator[wetterdienst.provider.dwd.radar.api.RadarResult]
Extract the RADOLAN_CDC data from the archive.
Road#
- class DwdRoadRequest
Bases:
wetterdienst.model.request.TimeseriesRequestRequest class for DWD road weather data.
- metadata
None
- _values
None
- _base_columns: ClassVar
(‘resolution’, ‘dataset’, ‘station_id’, ‘start_timestamp’, ‘end_timestamp’, ‘latitude’, ‘longitude’,…
- _endpoint
‘https://www.dwd.de/DE/leistungen/opendata/help/stationen/sws_stations_xls.xlsx?__blob=publicationFil…’
- _column_mapping: ClassVar
None
- _dtypes: ClassVar
None
- _all() polars.LazyFrame
EA#
Hydrology#
- class EAHydrologyRequest
Bases:
wetterdienst.model.request.TimeseriesRequestRequest class for Environment Agency hydrology data.
- metadata
None
- _values
None
- _url
‘https://environment.data.gov.uk/hydrology/id/stations.json’
- _all() polars.LazyFrame
Acquire all stations and filter for stations that have wanted resolution and parameter combinations.
Eaufrance#
Hubeau#
- class HubeauRequest
Bases:
wetterdienst.model.request.TimeseriesRequestRequest class for Eaufrance Hubeau data.
- metadata
None
- _values
None
- _endpoint
None
- _base_columns: ClassVar
()
- _observation_dates(url: str) polars.DataFrame
Read the timestamps one observations query carries.
Returns: Frame of
station_idandtimestamp, one row per observation.
- _station_steps(station_ids: list[str]) polars.DataFrame
Measure the interval each station transmits at.
Args: station_ids: The stations the referential lists, so that a station quiet during the first window can be asked about by name.
Returns: Frame of
station_idandstep, the station’s interval in minutes. A station that published nothing to measure is absent.
- static _observations_url(start: datetime.datetime, end: datetime.datetime, grandeur: str, station_ids: list[str] | None = None) str
Build one observations query, asking for the two fields an interval is measured from.
- _site_elevations() polars.DataFrame
Read the altitude of every hydrometric site.
Returns: Frame of
code_siteandelevation, null where the site publishes no altitude or one that cannot be the ground’s – see_ELEVATION_MIN. Empty when the referential cannot be read: the elevation is all it supplies, and a station list without one is better than none at all.
- _all() polars.LazyFrame
List each station under the resolution it transmits at.
ECCC#
Observation#
- class EcccObservationRequest
Bases:
wetterdienst.model.request.TimeseriesRequestDownload weather data from Environment and Climate Change Canada (ECCC).
https://www.canada.ca/en/environment-climate-change.html
https://www.canada.ca/en/services/environment/weather.html
Original code by Trevor James Smith. Thanks!
https://github.com/Zeitsperre/canada-climate-python
- _endpoint
‘https://api.weather.gc.ca’
- metadata
None
- _values
‘cast(…)’
- _timezone_mapping: ClassVar[dict]
None
- _all() polars.LazyFrame
Geosphere#
Observation#
- class GeosphereObservationRequest
Bases:
wetterdienst.model.request.TimeseriesRequestRequest class for geosphere observation data.
- metadata
None
- _values
None
- _endpoint
‘https://dataset.api.hub.geosphere.at/v1/station/historical/{dataset}/metadata/stations’
- _all() polars.LazyFrame
IMGW#
Hydrology#
- class ImgwHydrologyRequest
Bases:
wetterdienst.model.request.TimeseriesRequestRequest class for hydrological data from IMGW.
- metadata
None
- _values
None
- _endpoint
‘https://dane.imgw.pl/datastore/getfiledown/Arch/Telemetria/Hydro/kody_stacji.csv’
- _all() polars.LazyFrame
:return:
Meteorology#
- class ImgwMeteorologyRequest
Bases:
wetterdienst.model.request.TimeseriesRequestRequest for meteorological data from the Institute of Meteorology and Water Management.
- metadata
None
- _values
None
- _endpoint
‘https://dane.imgw.pl/datastore/getfiledown/Arch/Telemetria/Meteo/kody_stacji.csv’
- _all() polars.LazyFrame
Get all available stations.
Météo-France#
Synop#
- class MeteoFranceSynopRequest
Bases:
wetterdienst.model.request.TimeseriesRequestRequest class for Météo-France SYNOP data.
- metadata
None
- _values
None
- _all() polars.LazyFrame
Observation#
- class MeteoFranceObservationRequest
Bases:
wetterdienst.model.request.TimeseriesRequestRequest class for Météo-France observation data.
- metadata
None
- _values
None
- _all() polars.LazyFrame
- static _climate_stations(settings: wetterdienst.settings.Settings) polars.DataFrame
Build the station list from Météo-France’s canonical station metadata registry.
MeteoSwiss#
Observation#
- class MeteoswissObservationRequest
Bases:
wetterdienst.model.request.TimeseriesRequestRequest class for MeteoSwiss observation data.
- metadata
None
- _values
None
- _station_endpoint
‘https://data.geo.admin.ch/ch.meteoschweiz.ogd-smn/ogd-smn_meta_stations.csv’
- _all() polars.LazyFrame
MET Norway#
Frost#
- class MetnoFrostRequest
Bases:
wetterdienst.model.request.TimeseriesRequestRequest class for MET Norway Frost API.
- metadata
None
- _values
None
- _sources_url
‘https://frost.met.no/sources/v0.jsonld?types=SensorSystem&fields=id,name,validFrom,validTo,geometry,…’
- classmethod is_configured() bool
- classmethod is_valid(settings: wetterdienst.settings.Settings | None = None) bool
- __post_init__() None
- _all() polars.LazyFrame
NOAA#
GHCN#
- class NoaaGhcnRequest
Bases:
wetterdienst.model.request.TimeseriesRequestRequest class for NOAA GHCN data provider.
- metadata
None
- _values
None
- _all() polars.LazyFrame
- static _take_daily_elevation(df: polars.LazyFrame) polars.LazyFrame
Give a station’s hourly row the daily list’s elevation, where both lists mean one place.
Then every reader of the station gets one elevation, whichever row it takes (GH-2336). Only where the two lists put the station within 5 km of each other: for some ids they name different stations (MXM00076840 is ARRIAGA on the Chiapas coast in the hourly list and its data, TEMOSACHI 2000 km away and 1900 m higher in the daily one), and there each row keeps its own list’s height. Nor does a daily 0.0 replace a height the hourly list gives (GH-2362); both rows then keep their own as well. A daily list giving none leaves the hourly one.
- _create_metaindex_for_ghcn_hourly() polars.LazyFrame
- _create_metaindex_for_ghcn_daily() polars.LazyFrame
Acquire station listing for ghcn daily.
station listing
Variable
Columns
Type
Example
ID
1-11
Character
EI000003980
LATITUDE
13-20
Real
55.3717
LONGITUDE
22-30
Real
-7.3400
ELEVATION
32-37
Real
21.0
STATE
39-40
Character
NAME
42-71
Character
MALIN HEAD
GSN FLAG
73-75
Character
GSN
HCN/CRN FLAG
77-79
Character
WMO ID
81-85
Character
03980
inventory listing
Variable
Columns
Type
ID
1-11
CHARACTER
LATITUDE
13-20
REAL
LONGITUDE
22-30
REAL
ELEMENT
32-35
CHARACTER
FIRSTYEAR
37-40
INTEGER
LASTYEAR
42-45
INTEGER
National Weather Service#
Observation#
- class NwsObservationRequest
Bases:
wetterdienst.model.request.TimeseriesRequestRequest class for NWS observation.
- metadata
None
- _values
None
- _endpoint
‘https://madis-data.ncep.noaa.gov/madisPublic1/data/stations/METARTable.txt’
- _stations_filed_under_a_state_code
(‘PHBK’, ‘TIST’, ‘TISX’)
- _elevation_missing
9999.0
- _all() polars.LazyFrame
WSV#
Observation#
- class WsvPegelRequest
Bases:
wetterdienst.model.request.TimeseriesRequestRequest class for WSV Pegelonline.
Pegelonline is a German river management facility and provider of river-based measurements for last 30 days.
- metadata
None
- _values
None
- _endpoint
None
- characteristic_values: ClassVar
None
- _base_columns: ClassVar
()
- _all() polars.LazyFrame
Get stations for WSV Pegelonline.
It involves reading the REST API, doing some transformations and adding characteristic values in extra columns if given for each station.