A comprehensive Python wrapper around OpenWeatherMap web APIs providing weather data, forecasts, air pollution, UV index, and agricultural information
npx @tessl/cli install tessl/pypi-pyowm@3.5.0A comprehensive Python wrapper around OpenWeatherMap web APIs providing weather data, forecasts, air pollution, UV index, and agricultural information. PyOWM offers a simple object model with human-friendly interfaces for accessing current weather conditions, weather forecasts, historical data, geocoding services, weather alerts, and satellite imagery across both free and paid OpenWeatherMap API subscription plans.
pip install pyowmfrom pyowm import OWMFor specific managers and data models:
from pyowm.owm import OWM
from pyowm.weatherapi30.weather import Weather
from pyowm.weatherapi30.location import Locationfrom pyowm import OWM
# Initialize with your API key
owm = OWM('your-api-key-here')
# Get current weather for a location
mgr = owm.weather_manager()
observation = mgr.weather_at_place('London,GB')
weather = observation.weather
print(f"Temperature: {weather.temperature('celsius')['temp']}°C")
print(f"Status: {weather.detailed_status}")
print(f"Wind: {weather.wind()}")
# Get weather forecast
forecaster = mgr.forecast_at_place('London,GB', '3h')
forecast = forecaster.forecast
print(f"Forecast items: {len(forecast)}")
for weather in forecast[:3]: # First 3 forecast items
print(f"{weather.reference_time('iso')}: {weather.status}")
# Get air quality data
air_mgr = owm.airpollution_manager()
air_status = air_mgr.air_quality_at_coords(51.5074, -0.1278)
print(f"Air Quality Index: {air_status.air_quality_data['main']['aqi']}")PyOWM follows a manager-based architecture where the main OWM class serves as a factory for specialized API managers:
This design enables clean separation of concerns while providing a unified interface to OpenWeatherMap's diverse API ecosystem.
Current weather conditions, forecasts, and historical data from OpenWeatherMap's Weather API and OneCall API. Supports location-based queries by name, coordinates, city ID, or zip code.
class WeatherManager:
def weather_api_version(self) -> tuple: ...
def weather_at_place(self, name: str) -> Observation: ...
def weather_at_coords(self, lat: float, lon: float) -> Observation: ...
def weather_at_zip_code(self, zipcode: str, country: str) -> Observation: ...
def weather_at_id(self, id: int) -> Observation: ...
def weather_at_ids(self, ids_list: List[int]) -> List[Observation]: ...
def weather_at_places(self, pattern: str, searchtype: str, limit: int = None) -> List[Observation]: ...
def weather_at_places_in_bbox(self, lon_left: float, lat_bottom: float, lon_right: float, lat_top: float, zoom: int = 10, cluster: bool = False) -> List[Observation]: ...
def weather_around_coords(self, lat: float, lon: float, limit: int = None) -> List[Observation]: ...
def forecast_at_place(self, name: str, interval: str, limit: int = None) -> Forecaster: ...
def forecast_at_coords(self, lat: float, lon: float, interval: str, limit: int = None) -> Forecaster: ...
def forecast_at_id(self, id: int, interval: str, limit: int = None) -> Forecaster: ...
def one_call(self, lat: Union[int, float], lon: Union[int, float], **kwargs) -> OneCall: ...
def one_call_history(self, lat: Union[int, float], lon: Union[int, float], dt: int = None) -> OneCall: ...
def station_tick_history(self, station_ID: int, limit: int = None) -> Historian: ...
def station_hour_history(self, station_ID: int, limit: int = None) -> Historian: ...
def station_day_history(self, station_ID: int, limit: int = None) -> Historian: ...Air quality information including AQI (Air Quality Index) and concentrations of pollutants like CO, NO₂, O₃, SO₂, PM2.5, PM10, and NH₃.
class AirPollutionManager:
def airpollution_api_version(self) -> tuple: ...
def air_quality_at_coords(self, lat: float, lon: float) -> AirStatus: ...
def air_quality_forecast_at_coords(self, lat: float, lon: float) -> List[AirStatus]: ...
def air_quality_history_at_coords(self, lat: float, lon: float, start, end=None) -> List[AirStatus]: ...Satellite imagery, soil data, and agricultural information for polygonal areas including NDVI, EVI indices and soil temperature/moisture data.
class AgroManager:
def agro_api_version(self) -> tuple: ...
def create_polygon(self, geopolygon: GeoPolygon, name: str = None) -> Polygon: ...
def get_polygons(self) -> List[Polygon]: ...
def get_polygon(self, polygon_id: str) -> Polygon: ...
def update_polygon(self, polygon: Polygon) -> Polygon: ...
def delete_polygon(self, polygon: Polygon) -> None: ...
def soil_data(self, polygon_id: str) -> Soil: ...
def search_satellite_imagery(self, polygon_id: str, acquired_from: int, acquired_to: int, img_w: int = None, img_h: int = None) -> SatelliteImagerySearchResultSet: ...
def download_satellite_image(self, satellite_image: SatelliteImage, preset: str, palette: str = None): ...Weather alert system allowing creation of triggers that monitor weather conditions and fire alerts when specified criteria are met.
class AlertManager:
def alert_api_version(self) -> tuple: ...
def create_trigger(self, start, end, conditions, area, alert_channels=None) -> Trigger: ...
def get_triggers(self) -> List[Trigger]: ...
def get_trigger(self, trigger_id: str) -> Trigger: ...
def update_trigger(self, trigger: Trigger) -> Trigger: ...
def delete_trigger(self, trigger: Trigger) -> None: ...
def get_alerts_for(self, trigger: Trigger, since: int = None) -> List[Alert]: ...
def delete_all_alerts_for(self, trigger: Trigger) -> None: ...Personal weather station management for creating, updating stations and sending/retrieving measurement data.
class StationsManager:
def stations_api_version(self) -> tuple: ...
def get_stations(self) -> List[Station]: ...
def get_station(self, id: str) -> Station: ...
def create_station(self, external_id: str, name: str, lat: float, lon: float, alt: float = None) -> Station: ...
def update_station(self, station: Station) -> None: ...
def delete_station(self, station: Station) -> None: ...
def send_measurement(self, measurement: Measurement) -> None: ...
def send_measurements(self, list_of_measurements: List[Measurement]) -> None: ...
def get_measurements(self, station_id: str, aggregated_on: str, from_timestamp: int, to_timestamp: int, limit: int = 100) -> List[AggregatedMeasurement]: ...
def send_buffer(self, buffer: Buffer) -> None: ...Ultraviolet radiation index information including current UV levels, forecasts, and historical UV index data.
class UVIndexManager:
def uvindex_api_version(self) -> tuple: ...
def uvindex_around_coords(self, lat: float, lon: float) -> UVIndex: ...
def uvindex_forecast_around_coords(self, lat: float, lon: float) -> List[UVIndex]: ...
def uvindex_history_around_coords(self, lat: float, lon: float, start, end=None) -> List[UVIndex]: ...Direct and reverse geocoding for converting between place names and geographic coordinates.
class GeocodingManager:
def geocoding_api_version(self) -> tuple: ...
def geocode(self, toponym: str, country: str = None, state_code: str = None, limit: int = None) -> List[Location]: ...
def reverse_geocode(self, lat: float, lon: float, limit: int = None) -> List[Location]: ...Weather map tiles for visualization including precipitation, wind, temperature, and pressure layers.
class TileManager:
def get_tile(self, x: int, y: int, zoom: int) -> Tile: ...class OWM:
def __init__(self, api_key: str, config: dict = None): ...
@property
def configuration(self) -> dict: ...
@property
def version(self) -> tuple: ...
@property
def supported_languages(self) -> List[str]: ...
def weather_manager(self) -> WeatherManager: ...
def airpollution_manager(self) -> AirPollutionManager: ...
def agro_manager(self) -> AgroManager: ...
def alert_manager(self) -> AlertManager: ...
def stations_manager(self) -> StationsManager: ...
def uvindex_manager(self) -> UVIndexManager: ...
def geocoding_manager(self) -> GeocodingManager: ...
def tile_manager(self, layer_name: str) -> TileManager: ...
def city_id_registry(self) -> CityIDRegistry: ...
class Location:
def __init__(self, name: str, lon: Union[int, float], lat: Union[int, float], _id: int, country: str = None): ...
@property
def name(self) -> str: ...
@property
def lon(self) -> Union[int, float]: ...
@property
def lat(self) -> Union[int, float]: ...
@property
def id(self) -> int: ...
@property
def country(self) -> str: ...
def to_geopoint(self) -> Point: ...
def to_dict(self) -> dict: ...
class Weather:
def reference_time(self, timeformat: str = 'unix') -> Union[int, str, datetime]: ...
def sunset_time(self, timeformat: str = 'unix') -> Union[int, str, datetime, None]: ...
def sunrise_time(self, timeformat: str = 'unix') -> Union[int, str, datetime, None]: ...
def wind(self, unit: str = 'meters_sec') -> dict: ...
def temperature(self, unit: str = 'kelvin') -> dict: ...
def barometric_pressure(self, unit: str = 'hPa') -> dict: ...
def visibility(self, unit: str = 'meters') -> float: ...
def weather_icon_url(self, size: str = "") -> str: ...
@property
def status(self) -> str: ...
@property
def detailed_status(self) -> str: ...
@property
def weather_code(self) -> int: ...
@property
def weather_icon_name(self) -> str: ...
@property
def clouds(self) -> int: ...
@property
def rain(self) -> dict: ...
@property
def snow(self) -> dict: ...
@property
def humidity(self) -> int: ...
@property
def dewpoint(self) -> float: ...
@property
def heat_index(self) -> float: ...
@property
def humidex(self) -> float: ...
@property
def visibility_distance(self) -> float: ...
@property
def uvi(self) -> Union[int, float, None]: ...
@property
def precipitation_probability(self) -> Union[float, None]: ...
class Observation:
def __init__(self, reception_time: int, location: Location, weather: Weather): ...
def reception_time(self, timeformat: str = 'unix') -> Union[int, str, datetime]: ...
@property
def location(self) -> Location: ...
@property
def weather(self) -> Weather: ...
class Forecast:
def __init__(self, interval: str, reception_time: int, location: Location, weathers: List[Weather]): ...
def get(self, index: int) -> Weather: ...
def reception_time(self, timeformat: str = 'unix') -> Union[int, str, datetime]: ...
def actualize(self) -> None: ...
@property
def interval(self) -> str: ...
@property
def location(self) -> Location: ...
@property
def weathers(self) -> List[Weather]: ...
def __len__(self) -> int: ...
def __iter__(self): ...
class Forecaster:
def __init__(self, forecast: Forecast): ...
def when_starts(self, timeformat: str = 'unix') -> Union[int, str, datetime]: ...
def when_ends(self, timeformat: str = 'unix') -> Union[int, str, datetime]: ...
def will_have_rain(self) -> bool: ...
def will_have_clear(self) -> bool: ...
def will_have_fog(self) -> bool: ...
def will_have_clouds(self) -> bool: ...
def will_have_snow(self) -> bool: ...
def will_have_storm(self) -> bool: ...
def will_have_tornado(self) -> bool: ...
def will_have_hurricane(self) -> bool: ...
def when_rain(self) -> List[Weather]: ...
def when_clear(self) -> List[Weather]: ...
def when_fog(self) -> List[Weather]: ...
def when_clouds(self) -> List[Weather]: ...
def when_snow(self) -> List[Weather]: ...
def when_storm(self) -> List[Weather]: ...
def when_tornado(self) -> List[Weather]: ...
def when_hurricane(self) -> List[Weather]: ...
def will_be_rainy_at(self, timeobject) -> bool: ...
def will_be_clear_at(self, timeobject) -> bool: ...
def will_be_snowy_at(self, timeobject) -> bool: ...
def will_be_cloudy_at(self, timeobject) -> bool: ...
def will_be_foggy_at(self, timeobject) -> bool: ...
def will_be_stormy_at(self, timeobject) -> bool: ...
def will_be_tornado_at(self, timeobject) -> bool: ...
def will_be_hurricane_at(self, timeobject) -> bool: ...
def get_weather_at(self, timeobject) -> Weather: ...
def most_hot(self) -> Union[Weather, None]: ...
def most_cold(self) -> Union[Weather, None]: ...
def most_humid(self) -> Union[Weather, None]: ...
def most_rainy(self) -> Union[Weather, None]: ...
def most_snowy(self) -> Union[Weather, None]: ...
def most_windy(self) -> Union[Weather, None]: ...
@property
def forecast(self) -> Forecast: ...
class OneCall:
def __init__(self, lat: Union[int, float], lon: Union[int, float], timezone: str,
current: Weather, forecast_minutely: Optional[List[Weather]] = None,
forecast_hourly: Optional[List[Weather]] = None,
forecast_daily: Optional[List[Weather]] = None,
national_weather_alerts: Optional[List] = None): ...
def to_geopoint(self) -> Point: ...
@property
def lat(self) -> Union[int, float]: ...
@property
def lon(self) -> Union[int, float]: ...
@property
def timezone(self) -> str: ...
@property
def current(self) -> Weather: ...
@property
def forecast_minutely(self) -> Optional[List[Weather]]: ...
@property
def forecast_hourly(self) -> Optional[List[Weather]]: ...
@property
def forecast_daily(self) -> Optional[List[Weather]]: ...
@property
def national_weather_alerts(self) -> Optional[List]: ...
class Historian:
def __init__(self, station_history): ...
def temperature_series(self, unit: str = 'kelvin') -> List[Tuple[int, float]]: ...
def humidity_series(self) -> List[Tuple[int, int]]: ...
def pressure_series(self) -> List[Tuple[int, float]]: ...
def rain_series(self) -> List[Tuple[int, float]]: ...
def wind_series(self) -> List[Tuple[int, dict]]: ...
def max_temperature(self, unit: str = 'kelvin') -> Tuple[int, float]: ...
def min_temperature(self, unit: str = 'kelvin') -> Tuple[int, float]: ...
def average_temperature(self, unit: str = 'kelvin') -> float: ...
def max_humidity(self) -> Tuple[int, int]: ...
def min_humidity(self) -> Tuple[int, int]: ...
def average_humidity(self) -> float: ...
def max_pressure(self) -> Tuple[int, float]: ...
def min_pressure(self) -> Tuple[int, float]: ...
def average_pressure(self) -> float: ...
def max_rain(self) -> Tuple[int, float]: ...
def min_rain(self) -> Tuple[int, float]: ...
def average_rain(self) -> float: ...
class AirStatus:
def __init__(self, reference_time: int, location: Location, air_quality_data: dict, reception_time: int): ...
def reference_time(self, timeformat: str = 'unix') -> Union[int, str, datetime]: ...
def reception_time(self, timeformat: str = 'unix') -> Union[int, str, datetime]: ...
@property
def location(self) -> Location: ...
@property
def air_quality_data(self) -> dict: ...
@property
def aqi(self): ...
@property
def co(self): ...
@property
def no(self): ...
@property
def no2(self): ...
@property
def o3(self): ...
@property
def so2(self): ...
@property
def pm2_5(self): ...
@property
def pm10(self): ...
@property
def nh3(self): ...
class UVIndex:
def __init__(self, reference_time: int, location: Location, value: float, reception_time: int): ...
def reference_time(self, timeformat: str = 'unix') -> Union[int, str, datetime]: ...
def reception_time(self, timeformat: str = 'unix') -> Union[int, str, datetime]: ...
def get_exposure_risk(self) -> str: ...
@property
def location(self) -> Location: ...
@property
def value(self) -> float: ...# Default configuration
from pyowm.utils.config import get_default_config, get_default_config_for_subscription_type, get_default_config_for_proxy
def get_default_config() -> dict: ...
def get_default_config_for_subscription_type(name: str) -> dict: ...
def get_default_config_for_proxy(http_url: str, https_url: str) -> dict: ...
# Subscription types
from pyowm.commons.enums import SubscriptionTypeEnum
class SubscriptionTypeEnum:
FREE: SubscriptionType
STARTUP: SubscriptionType
DEVELOPER: SubscriptionType
PROFESSIONAL: SubscriptionType
ENTERPRISE: SubscriptionTypePyOWM provides a comprehensive exception hierarchy for robust error handling:
from pyowm.commons.exceptions import (
PyOWMError, # Base exception
APIRequestError, # Network/infrastructure failures
APIResponseError, # HTTP error status codes
NotFoundError, # Entity not found
UnauthorizedError, # Insufficient subscription capabilities
ParseAPIResponseError, # JSON parsing failures
TimeoutError, # Response timeout
BadGatewayError, # Upstream backend issues
InvalidSSLCertificateError # SSL certificate verification failure
)# Geographic utilities
from pyowm.utils.geo import Point, Polygon, assert_is_lat, assert_is_lon
class Point:
def __init__(self, lon: Union[int, float], lat: Union[int, float]): ...
def bounding_square_polygon(self, inscribed_circle_radius_km: float = 10.0) -> Polygon: ...
# Unit conversions
from pyowm.utils.measurables import (
kelvin_to_celsius, celsius_to_fahrenheit,
meters_sec_to_miles_hour, meters_sec_to_knots,
hPa_to_inHg, hPa_to_mmHg
)
# Time utilities
from pyowm.utils.timestamps import to_UNIXtime, to_ISO
# City ID registry
class CityIDRegistry:
def ids_for(self, city_name: str, country: str = None, state: str = None, matching: str = 'like') -> List[tuple]: ...
def locations_for(self, city_name: str, country: str = None, state: str = None, matching: str = 'like') -> List[Location]: ...