aemetxfb.pred
Prediction (hourly forecast) module.
Prediction module for AEMet data.
This module provides access to weather forecast data and station lookup utilities for the Spanish national weather service (AEMet).
- class aemetxfb.pred.Forecast(xml_text)[source]
Bases:
objectParsed hourly forecast for a single municipality.
Holds metadata, sunrise/sunset times, hourly observations, and 6-hourly probability blocks. All data is exposed via typed getter methods that return either scalars, dicts, or
pd.DataFrameinstances.- Parameters:
xml_text (str) – Raw XML content from the AEMet hourly forecast endpoint.
- Raises:
ValueError – If the XML cannot be parsed or is missing required elements.
- get_metadata(key=None)[source]
Return forecast metadata.
- Parameters:
key (str or None) – If
None, return the full metadata dictionary. If a string, return the value for that specific key (e.g."name","link","province").- Returns:
Full metadata dict when
keyisNone; otherwise the value associated withkey.- Return type:
dict or scalar
- Raises:
KeyError – If
keyis not found in the metadata.
Examples
>>> forecast.get_metadata() {'id': '50130', 'name': 'Jarque', ...} >>> forecast.get_metadata("link") 'https://www.aemet.es/...'
- get_sunrise_sunset()[source]
Return sunrise and sunset times for each forecast day.
- Returns:
Columns:
date(date),sunrise(time),sunset(time).- Return type:
pd.DataFrame
Examples
>>> forecast.get_sunrise_sunset() date sunrise sunset 0 2026-06-24 06:33:00 21:45:00 1 2026-06-25 06:33:00 21:45:00 2 2026-06-26 06:33:00 21:45:00
- get_hourly(variable=None)[source]
Return hourly forecast data.
- Parameters:
variable (str or None) –
If
None, return all hourly columns. If a string, return onlydate,hour, and the requested variable column.Accepted values (case-insensitive):
"temperature","apparent_temperature""humidity","relative_humidity""precipitation","rain""snow""wind_direction","wind_speed","gust","gust_speed""sky","sky_code","sky_description","weather"
- Returns:
Full hourly data or filtered subset.
- Return type:
pd.DataFrame
- Raises:
ValueError – If
variableis not recognised.
Examples
>>> forecast.get_hourly("temperature") date hour temperature 0 2026-06-24 9 26.0 1 2026-06-24 10 29.0 ...
- get_probability(variable=None)[source]
Return 6-hourly probability data.
- Parameters:
variable (str or None) –
If
None, return all probability types (wide format with one column per type). If a string, return only that type.Accepted values (case-insensitive):
"precipitation","rain""storm","thunderstorm""snow"
- Returns:
When
variableisNone: columnsdate,period,precipitation,storm,snow(pivoted wide format).When
variableis given: columnsdate,period,probability.- Return type:
pd.DataFrame
- Raises:
ValueError – If
variableis not recognised.
Examples
>>> forecast.get_probability() date period precipitation storm snow 0 2026-06-24 0814 0 0 0 ... >>> forecast.get_probability("storm") date period probability 0 2026-06-24 0814 0 ...
- aemetxfb.pred.find_nearest_location(lat, lon)[source]
Find the prediction station closest to the given coordinates.
Uses vectorised
numpyoperations to compute Euclidean distance on the lat/lon grid and return the ID of the nearest station.- Parameters:
- Returns:
The
IDof the nearest station (e.g."id01001").- Return type:
- Raises:
ValueError – If the station registry is empty.
Examples
>>> find_nearest_location(40.4168, -3.7038) # Madrid city centre 'id28079'
- aemetxfb.pred.get_forecast(lat_or_name, lon=None)[source]
Fetch the hourly forecast for a Spanish municipality.
Accepts either a municipality name (string) or coordinates (lat/lon as floats).
Resolution strategy:
If
lat_or_nameis a string, look up the station by name (exact or substring match, case-insensitive).If
lat_or_nameis a number, resolve the nearest station viafind_nearest_location()usinglat_or_nameandlon.
- Parameters:
- Returns:
Parsed forecast object with query methods.
- Return type:
- Raises:
ValueError – If no municipality matches the given name, if the name is ambiguous, or if coordinates are incomplete.
RuntimeError – If the XML cannot be fetched or parsed.
Examples
>>> forecast = get_forecast("Madrid") >>> forecast.get_metadata("name") 'Madrid' >>> forecast = get_forecast(40.4168, -3.7038) >>> forecast.get_hourly("temperature").head(3)
- aemetxfb.pred.get_predicted_stations()[source]
Return all prediction stations.
Data is loaded lazily from
stations.jsonand cached after the first call so that subsequent accesses are instant.- Returns:
Mapping of station ID to
{"name": ..., "lat": ..., "lon": ...}.- Return type:
Examples
>>> stations = get_predicted_stations() >>> "id01001" in stations True >>> stations["id01001"]["name"] 'Alegría-Dulantzi'
aemetxfb.pred.pred
Core forecast parsing and factory function.
Hourly weather forecasts for Spanish municipalities from AEMet XML API.
This module fetches the hourly forecast XML for a given municipality ID and
exposes it through a Forecast object with convenient query methods.
Examples
>>> forecast = get_forecast("Madrid")
>>> forecast.get_metadata("name")
'Madrid'
>>> forecast = get_forecast(40.4168, -3.7038)
>>> forecast.get_hourly("temperature").head()
>>> forecast.get_probability("precipitation")
- class aemetxfb.pred.pred.Forecast(xml_text)[source]
Bases:
objectParsed hourly forecast for a single municipality.
Holds metadata, sunrise/sunset times, hourly observations, and 6-hourly probability blocks. All data is exposed via typed getter methods that return either scalars, dicts, or
pd.DataFrameinstances.- Parameters:
xml_text (str) – Raw XML content from the AEMet hourly forecast endpoint.
- Raises:
ValueError – If the XML cannot be parsed or is missing required elements.
- get_metadata(key=None)[source]
Return forecast metadata.
- Parameters:
key (str or None) – If
None, return the full metadata dictionary. If a string, return the value for that specific key (e.g."name","link","province").- Returns:
Full metadata dict when
keyisNone; otherwise the value associated withkey.- Return type:
dict or scalar
- Raises:
KeyError – If
keyis not found in the metadata.
Examples
>>> forecast.get_metadata() {'id': '50130', 'name': 'Jarque', ...} >>> forecast.get_metadata("link") 'https://www.aemet.es/...'
- get_sunrise_sunset()[source]
Return sunrise and sunset times for each forecast day.
- Returns:
Columns:
date(date),sunrise(time),sunset(time).- Return type:
pd.DataFrame
Examples
>>> forecast.get_sunrise_sunset() date sunrise sunset 0 2026-06-24 06:33:00 21:45:00 1 2026-06-25 06:33:00 21:45:00 2 2026-06-26 06:33:00 21:45:00
- get_hourly(variable=None)[source]
Return hourly forecast data.
- Parameters:
variable (str or None) –
If
None, return all hourly columns. If a string, return onlydate,hour, and the requested variable column.Accepted values (case-insensitive):
"temperature","apparent_temperature""humidity","relative_humidity""precipitation","rain""snow""wind_direction","wind_speed","gust","gust_speed""sky","sky_code","sky_description","weather"
- Returns:
Full hourly data or filtered subset.
- Return type:
pd.DataFrame
- Raises:
ValueError – If
variableis not recognised.
Examples
>>> forecast.get_hourly("temperature") date hour temperature 0 2026-06-24 9 26.0 1 2026-06-24 10 29.0 ...
- get_probability(variable=None)[source]
Return 6-hourly probability data.
- Parameters:
variable (str or None) –
If
None, return all probability types (wide format with one column per type). If a string, return only that type.Accepted values (case-insensitive):
"precipitation","rain""storm","thunderstorm""snow"
- Returns:
When
variableisNone: columnsdate,period,precipitation,storm,snow(pivoted wide format).When
variableis given: columnsdate,period,probability.- Return type:
pd.DataFrame
- Raises:
ValueError – If
variableis not recognised.
Examples
>>> forecast.get_probability() date period precipitation storm snow 0 2026-06-24 0814 0 0 0 ... >>> forecast.get_probability("storm") date period probability 0 2026-06-24 0814 0 ...
- aemetxfb.pred.pred.get_forecast(lat_or_name, lon=None)[source]
Fetch the hourly forecast for a Spanish municipality.
Accepts either a municipality name (string) or coordinates (lat/lon as floats).
Resolution strategy:
If
lat_or_nameis a string, look up the station by name (exact or substring match, case-insensitive).If
lat_or_nameis a number, resolve the nearest station viafind_nearest_location()usinglat_or_nameandlon.
- Parameters:
- Returns:
Parsed forecast object with query methods.
- Return type:
- Raises:
ValueError – If no municipality matches the given name, if the name is ambiguous, or if coordinates are incomplete.
RuntimeError – If the XML cannot be fetched or parsed.
Examples
>>> forecast = get_forecast("Madrid") >>> forecast.get_metadata("name") 'Madrid' >>> forecast = get_forecast(40.4168, -3.7038) >>> forecast.get_hourly("temperature").head(3)
aemetxfb.pred._stations
Station registry with lazy loading and vectorised nearest-neighbour search.
Prediction station registry with lazy loading and vectorised search.
Stations are stored in stations.json (shipped with the package) and
loaded on first access. Latitude and longitude columns are cached as
numpy arrays so that nearest-neighbour searches use vectorised
operations instead of a Python loop.
- aemetxfb.pred._stations._load_stations()[source]
Load station data from JSON and build numpy arrays (lazy, cached).
- Returns:
(stations_dict, lat_array, lon_array, ids_list). The dict is the full registry; the arrays and list are aligned by position so thatlat_array[i],lon_array[i]andids_list[i]refer to the same station.- Return type:
- aemetxfb.pred._stations.get_predicted_stations()[source]
Return all prediction stations.
Data is loaded lazily from
stations.jsonand cached after the first call so that subsequent accesses are instant.- Returns:
Mapping of station ID to
{"name": ..., "lat": ..., "lon": ...}.- Return type:
Examples
>>> stations = get_predicted_stations() >>> "id01001" in stations True >>> stations["id01001"]["name"] 'Alegría-Dulantzi'
- aemetxfb.pred._stations.find_nearest_location(lat, lon)[source]
Find the prediction station closest to the given coordinates.
Uses vectorised
numpyoperations to compute Euclidean distance on the lat/lon grid and return the ID of the nearest station.- Parameters:
- Returns:
The
IDof the nearest station (e.g."id01001").- Return type:
- Raises:
ValueError – If the station registry is empty.
Examples
>>> find_nearest_location(40.4168, -3.7038) # Madrid city centre 'id28079'
- aemetxfb.pred._stations._find_station_by_name(name)[source]
Find a prediction station by its municipality name (internal).
Search strategy (case-insensitive):
Exact match — if a single station name matches exactly, return it.
Substring match — if no exact match, return the first station whose name contains the query string.
- Parameters:
name (str) – Municipality name (e.g.
"Madrid","zaragoza","jarque"). Matching is case-insensitive.- Returns:
The
IDof the matched station (e.g."id28079").- Return type:
- Raises:
ValueError – If no station matches or if the name is ambiguous (multiple exact matches).