Access and analyze historical weather and climate data with Python.
npx @tessl/cli install tessl/pypi-meteostat@1.7.0A comprehensive Python library for accessing and analyzing historical weather and climate data through a simple, intuitive API. Meteostat enables developers and researchers to fetch meteorological observations and statistics from various governmental sources including NOAA and DWD, offering access to weather station data, geographical point-based data, and time series information at hourly, daily, and monthly granularity.
pip install meteostatimport meteostatCommon imports for working with weather data:
from meteostat import Stations, Point, Hourly, Daily, Monthly, NormalsFor unit conversions:
from meteostat import unitsFor enumerations and type annotations:
from meteostat.enumerations.granularity import Granularity
from typing import Union, Optional
from datetime import datetimefrom datetime import datetime
from meteostat import Point, Daily
# Set time period
start = datetime(2018, 1, 1)
end = datetime(2018, 12, 31)
# Create Point for Vancouver, BC
location = Point(49.2497, -123.1193, 70)
# Get daily data
data = Daily(location, start, end)
data = data.fetch()
# Print daily average temperature
print(data['tavg'])Meteostat follows a modular design centered on location selection and time series data retrieval:
Stations) or geographic points (Point)Hourly, Daily, Monthly)Normals)This design enables seamless integration with pandas DataFrames for data manipulation and matplotlib for visualization, making it ideal for meteorological research, climate analysis, and weather applications.
Global configuration options that can be modified on the Base class to customize behavior across all meteostat operations.
class Base:
endpoint: str = "https://bulk.meteostat.net/v2/"
proxy: Optional[str] = None
cache_dir: str = "~/.meteostat/cache"
autoclean: bool = True
max_age: int = 86400 # 24 hours in seconds
processes: int = 1
threads: int = 1Example configuration:
from meteostat import Base
# Set up proxy for network requests
Base.proxy = "http://proxy.company.com:8080"
# Change cache location
Base.cache_dir = "/tmp/meteostat_cache"
# Increase cache retention to 1 week
Base.max_age = 7 * 24 * 60 * 60Select and filter weather stations from the global network based on location, country, geographical bounds, and data availability. Stations can be sorted by distance and filtered by data inventory.
class Stations:
def __init__(self) -> None: ...
def nearby(self, lat: float, lon: float, radius: int = None) -> "Stations": ...
def region(self, country: str, state: str = None) -> "Stations": ...
def bounds(self, top_left: tuple, bottom_right: tuple) -> "Stations": ...
def inventory(self, freq: str, required: Union[datetime, tuple, bool] = True) -> "Stations": ...Automatically select and interpolate data from nearby weather stations for any geographic location. Uses intelligent station selection and weighting algorithms for optimal data quality.
class Point:
def __init__(self, lat: float, lon: float, alt: int = None) -> None: ...
def get_stations(self, freq: str = None, start: datetime = None, end: datetime = None, model: bool = True) -> pd.DataFrame: ...Retrieve hourly meteorological observations including temperature, humidity, precipitation, wind, pressure, and weather conditions. Supports timezone localization and model data inclusion.
class Hourly:
def __init__(self, loc: Union[pd.DataFrame, Point, list, str], start=datetime(1890, 1, 1, 0, 0, 0), end=datetime.combine(datetime.today().date() + timedelta(days=10), datetime.max.time()), timezone: Optional[str] = None, model=True, flags=False) -> None: ...
def expected_rows(self) -> int: ...Access daily weather summaries with temperature extremes, precipitation totals, wind averages, and sunshine duration. Historical data available from 1781 for some locations.
class Daily:
def __init__(self, loc: Union[pd.DataFrame, Point, list, str], start=datetime(1781, 1, 1, 0, 0, 0), end=datetime.combine(datetime.today().date() + timedelta(days=10), datetime.max.time()), model=True, flags=False) -> None: ...
def expected_rows(self) -> int: ...Monthly aggregated weather statistics providing long-term climate patterns and trends. Ideal for climate analysis and seasonal comparisons.
class Monthly:
def __init__(self, loc: Union[pd.DataFrame, Point, list, str], start: datetime = None, end: datetime = None, model: bool = True, flags: bool = False) -> None: ...
def expected_rows(self) -> int: ...Climate normals providing 30-year averages for temperature, precipitation, and other parameters. Essential for climate research and establishing baseline conditions.
class Normals:
def __init__(self, loc: Union[pd.DataFrame, Point, list, str], start: int = None, end: int = None) -> None: ...
def normalize(self): ...Built-in methods for time series analysis including normalization, interpolation, aggregation, unit conversion, and data quality assessment.
# Available on all time series classes
def fetch(self) -> pd.DataFrame: ...
def normalize(self): ...
def interpolate(self, limit: int = 3): ...
def aggregate(self, freq: str, spatial: bool = False): ...
def convert(self, units: dict): ...
def coverage(self): ...
def count(self) -> int: ...Comprehensive unit conversion functions for temperature, precipitation, wind speed, pressure, and other meteorological parameters.
def fahrenheit(value): ...
def kelvin(value): ...
def inches(value): ...
def mph(value): ...
def direction(value): ...
def condition(value): ...
imperial: dict
scientific: dictfrom typing import Union, Optional
from datetime import datetime
import pandas as pd
# Location types
LocationType = Union[pd.DataFrame, Point, list, str]
# Granularity enumeration
class Granularity(Enum):
HOURLY = "hourly"
DAILY = "daily"
MONTHLY = "monthly"
NORMALS = "normals"