Async OpenMeteo API client with historical data caching and DataFrame support
Project description
OpenMeteo Python Client
Async Python client for OpenMeteo API with historical data caching and DataFrame support.
Features
- Historical weather data from 1940 to present
- 16-day weather forecast
- Current weather conditions
- Same variables for historical and forecast (ideal for ML)
- Smart caching:
- Historical: JSON files per location per month, accumulates indefinitely
- Forecast: in-memory with TTL and data freshness validation
- DataFrame conversion (optional, via pandas)
- Global coverage, no API key required
- Full type hints with Pydantic models
Installation
pip install openmeteo-py-df
# With DataFrame support
pip install "openmeteo-py-df[dataframe]"
Quick Start
Historical Data
import asyncio
from datetime import date
from openmeteo import OpenMeteoClient, TimeStep
async def main():
async with OpenMeteoClient() as client:
# Get hourly historical data
data = await client.get_historical(
latitude=55.75,
longitude=37.62,
start_date=date(2024, 1, 1),
end_date=date(2024, 1, 31),
step=TimeStep.HOURLY,
timezone="Europe/Moscow",
)
for i, time in enumerate(data.hourly.time):
temp = data.hourly.temperature_2m[i]
print(f"{time}: {temp}°C")
asyncio.run(main())
Forecast
async with OpenMeteoClient() as client:
forecast = await client.get_forecast(
latitude=55.75,
longitude=37.62,
days=7,
step=TimeStep.DAILY,
)
for i, day in enumerate(forecast.daily.time):
high = forecast.daily.temperature_2m_max[i]
low = forecast.daily.temperature_2m_min[i]
print(f"{day}: {low}°C - {high}°C")
Current Weather
async with OpenMeteoClient() as client:
current = await client.get_current(55.75, 37.62)
print(f"Temperature: {current.current.temperature_2m}°C")
print(f"Humidity: {current.current.relative_humidity_2m}%")
print(f"Wind: {current.current.wind_speed_10m} km/h")
DataFrame Conversion
from openmeteo import OpenMeteoClient, TimeStep
from openmeteo.dataframe import to_dataframe
async with OpenMeteoClient() as client:
response = await client.get_historical(
latitude=55.75,
longitude=37.62,
start_date=date(2024, 1, 1),
end_date=date(2024, 1, 31),
step=TimeStep.HOURLY,
)
df = to_dataframe(response)
print(df.head())
print(df.describe())
Available Variables
Hourly (26 variables)
| Variable | Description | Unit |
|---|---|---|
temperature_2m |
Air temperature | °C |
relative_humidity_2m |
Relative humidity | % |
dew_point_2m |
Dew point | °C |
apparent_temperature |
Feels like temperature | °C |
precipitation |
Total precipitation | mm |
rain |
Rain amount | mm |
snowfall |
Snowfall | cm |
snow_depth |
Snow depth | m |
weather_code |
WMO weather code | code |
pressure_msl |
Pressure (sea level) | hPa |
surface_pressure |
Surface pressure | hPa |
cloud_cover |
Total cloud cover | % |
cloud_cover_low/mid/high |
Cloud layers | % |
wind_speed_10m |
Wind speed | km/h |
wind_direction_10m |
Wind direction | ° |
wind_gusts_10m |
Wind gusts | km/h |
shortwave_radiation |
Shortwave radiation | W/m² |
direct_radiation |
Direct solar radiation | W/m² |
diffuse_radiation |
Diffuse radiation | W/m² |
et0_fao_evapotranspiration |
ET0 evapotranspiration | mm |
vapour_pressure_deficit |
VPD | kPa |
visibility |
Visibility* | m |
is_day |
Day/night | 0/1 |
*Note: visibility only available in Forecast API, not Archive API.
Daily (21 variables)
| Variable | Description |
|---|---|
temperature_2m_max/min/mean |
Daily temperature |
apparent_temperature_max/min/mean |
Feels like temperature |
precipitation_sum |
Total precipitation |
rain_sum, snowfall_sum |
Rain and snow totals |
weather_code |
WMO weather code |
sunrise, sunset |
Sun times |
daylight_duration, sunshine_duration |
Duration in seconds |
wind_speed_10m_max |
Max wind speed |
wind_gusts_10m_max |
Max gusts |
wind_direction_10m_dominant |
Dominant direction |
shortwave_radiation_sum |
Solar radiation |
et0_fao_evapotranspiration |
Evapotranspiration |
uv_index_max |
Maximum UV index |
Caching
Historical Data
- Cached in JSON files per location per month
- Only missing months are fetched
- Data accumulates indefinitely
- Cache directory:
~/.cache/openmeteo/historical/
Forecast Data
- In-memory cache with TTL (default 60 minutes)
- Invalidated when approaching forecast end
- Ensures data freshness
Cache Management
client = OpenMeteoClient()
# Clear forecast cache
client.clear_forecast_cache()
# Clear historical cache
client.clear_historical_cache()
# Clear all
client.clear_all_cache()
Error Handling
from openmeteo import (
OpenMeteoError,
OpenMeteoAPIError,
OpenMeteoConnectionError,
OpenMeteoValidationError,
)
try:
data = await client.get_historical(91.0, 0.0, start, end)
except OpenMeteoValidationError as e:
print(f"Invalid parameters: {e}")
except OpenMeteoAPIError as e:
print(f"API error: {e.reason}")
except OpenMeteoConnectionError as e:
print(f"Connection error: {e}")
Development
Setup
git clone https://github.com/Evgeny105/openmeteo-py-df.git
cd openmeteo-py-df
pip install -e ".[dev,dataframe]"
Run Tests
# Run tests
pytest tests/
# Run with coverage
pytest tests/ --cov=openmeteo --cov-report=term-missing
# HTML coverage report
pytest tests/ --cov=openmeteo --cov-report=html
Minimum Coverage
This project requires minimum 90% test coverage. Current coverage: 96%.
Requirements
- Python >= 3.10
- httpx >= 0.24
- pydantic >= 2.0
Optional:
- pandas >= 2.0 (for DataFrame conversion)
License
MIT License - see LICENSE
Links
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file openmeteo_py_df-1.0.1.tar.gz.
File metadata
- Download URL: openmeteo_py_df-1.0.1.tar.gz
- Upload date:
- Size: 25.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.10.4 {"installer":{"name":"uv","version":"0.10.4","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"22.04","id":"jammy","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
18f196d0d47576e2bc11fb19a0f6596b6eb0cb9333d57461e01f5e406db452dc
|
|
| MD5 |
949a94fb9538c6d6c1c5074976ae4a58
|
|
| BLAKE2b-256 |
1c8cc2c4fcb7d1c3969de389f60caacb1564df61e8ce7a7d3ddedaf0d52626d1
|
File details
Details for the file openmeteo_py_df-1.0.1-py3-none-any.whl.
File metadata
- Download URL: openmeteo_py_df-1.0.1-py3-none-any.whl
- Upload date:
- Size: 24.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.10.4 {"installer":{"name":"uv","version":"0.10.4","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"22.04","id":"jammy","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
61738dc0c894712db1e5a0daabc184e81ea3cf0b26a82fc26e241e3aff34308d
|
|
| MD5 |
342c22bc7d4e2051816fde9805e5f9c7
|
|
| BLAKE2b-256 |
efcc9227fb4f709942505c1c8dbe10149b8154d0718e9441c494f16285fc6c4d
|