Predictions Module
The pred module provides access to hourly weather forecasts
from AEMet, covering a 3-day horizon. It includes a station registry of
~8,000 Spanish municipalities with nearest-neighbour lookup by coordinates
and case-insensitive name search.
Station registry
The module ships with a JSON registry of prediction stations. Data is loaded lazily on first access and cached in memory.
get_predicted_stations returns the full registry:
from aemetxfb.pred import get_predicted_stations
stations = get_predicted_stations()
print(len(stations)) # ~8000
print(stations["id28079"]["name"]) # "Madrid"
Each entry maps a station ID to {"name": ..., "lat": ..., "lon": ...}.
Nearest-station lookup
find_nearest_location() finds the closest station to
a pair of coordinates using vectorised numpy operations:
from aemetxfb.pred import find_nearest_location
station_id = find_nearest_location(40.4168, -3.7038)
print(station_id) # "id28079"
Hourly forecasts
get_forecast() fetches and parses the AEMet hourly
forecast XML for a municipality. It accepts either a name (string) or
coordinates (lat/lon as floats):
from aemetxfb.pred import get_forecast
# By name
forecast = get_forecast("Madrid")
# By coordinates
forecast = get_forecast(40.4168, -3.7038)
The function returns a Forecast object.
Forecast object
The Forecast class exposes typed getter methods
for metadata, sunrise/sunset, hourly variables, and probability blocks.
Metadata
forecast.get_metadata() # full dict
forecast.get_metadata("name") # "Madrid"
forecast.get_metadata("province") # "Madrid"
forecast.get_metadata("id") # "50130"
forecast.get_metadata("link") # AEMet web URL
Sunrise and sunset
df = 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
Hourly data
# All variables
df = forecast.get_hourly()
# Single variable (aliases accepted)
df = forecast.get_hourly("temperature")
df = forecast.get_hourly("rain") # alias for precipitation
df = forecast.get_hourly("gust") # alias for gust_speed
df = forecast.get_hourly("sky") # alias for sky_description
Available variables:
Column |
Aliases |
Description |
|---|---|---|
|
— |
Air temperature (°C, integer) |
|
|
Apparent / perceived temperature (°C, integer) |
|
|
Relative humidity (%) |
|
|
Accumulated precipitation (mm) |
|
— |
Snow depth (cm) |
|
— |
Wind direction (cardinal, e.g. “N”, “SE”) |
|
— |
Wind speed (km/h, integer) |
|
|
Maximum gust speed (km/h, integer) |
|
— |
Sky condition code (e.g. “11”, “12n”) |
|
|
Human-readable sky description |
Probability blocks
# All types (wide format)
df = forecast.get_probability()
# date period precipitation storm snow
# 0 2026-06-24 0814 0 0 0
# Single type
df = forecast.get_probability("precipitation")
df = forecast.get_probability("storm") # alias: thunderstorm
df = forecast.get_probability("snow")
Probabilities are given for 6-hour blocks:
Period |
Hours |
Description |
|---|---|---|
|
02:00–08:00 |
Early morning |
|
08:00–14:00 |
Late morning / early afternoon |
|
14:00–20:00 |
Afternoon / evening |
|
20:00–02:00 |
Night |
Error handling
Name not found —
ValueErrorwith a clear message.Ambiguous name —
ValueErrorlisting all matching stations with coordinates (e.g."Mieres"matches 2 entries).Incomplete coordinates —
ValueErrorwhen only latitude or longitude is provided.Network / parse errors —
RuntimeErrorwrapping the underlying exception.
API reference
See aemetxfb.pred for the full API reference.