Skip to main content

accuweather-client

PyPI version Python versions License: MIT CI Downloads Typed Code style: ruff

A human-friendly, fully typed Python client for the AccuWeather API — address locations the way people do (city name, point of interest, or coordinates) and get documented pydantic models back. Sync and async clients, a pretty CLI, pandas export, automatic retries, quota-aware caching, and typed exceptions.

from accuweather_client import WeatherClient

client = WeatherClient(token="your-api-key", city="sydney")

client.get_current_conditions().current_conditions
# 'At the moment: sunny, with a temperature of 17.2C. The wind is coming from the WSW at 15.4km/h.'

client.get_5day_forecast().forecast_tomorrow
# 'Partly sunny, max temp is 18.9C and 25% chance of rain.'

Why this package?

  • Locations the human way. No manual location-key lookups: pass city="sydney" — or disambiguate with country="canada", use a poi="Eiffel tower", or a lat/lon pair. The location key is resolved and cached for you.
  • Typed everywhere. Every response is a documented pydantic model, the package ships a py.typed marker, and every public method has a complete docstring — your IDE (and your AI assistant) autocompletes the whole API.
  • Sync and async. WeatherClient and AsyncWeatherClient mirror each other method-for-method.
  • Quota-friendly. The free tier allows 50 calls/day; the client caches location lookups, optionally caches weather responses (cache_ttl=600), retries transient errors with backoff, and raises a dedicated RateLimitExceededError carrying the RateLimit-* headers.
  • Batteries included. A rich-powered CLI, emoji weather icons, and one-line pandas DataFrame export.

Installation

pip install accuweather-client            # core (requests + pydantic only)
pip install 'accuweather-client[all]'     # + pandas, async (httpx), cli (typer/rich)

Extras: [pandas] for DataFrame export, [async] for AsyncWeatherClient, [cli] for the accuweather command.

Getting an API key

Create a free account at developer.accuweather.com, register an app, and copy its API key. The free tier includes 50 requests/day and covers location search, current conditions, 1/5-day daily and 1/12-hour hourly forecasts; other endpoints (alerts, indices, historical conditions, longer forecasts) require a paid plan and answer with HTTP 403 otherwise.

Quick start

from accuweather_client import WeatherClient

client = WeatherClient(token=API_KEY, city="sydney")
client.location          # Sydney, Australia (key=22889) — resolved lazily, cached

# Same name, different country? Point of interest? Coordinates? All work:
WeatherClient(token=API_KEY, city="sydney", country="canada")
WeatherClient(token=API_KEY, poi="Eiffel tower")
WeatherClient(token=API_KEY, lat=51.988, lon=-4.88)

# Current conditions
conditions = client.get_current_conditions()
conditions.current_conditions   # friendly sentence
conditions.temperature          # 17.2

# Daily forecasts (1 & 5 days on the free tier, 10/15 on paid plans)
forecast = client.get_5day_forecast()
forecast.forecast_tomorrow      # one-line summary
print(forecast)                 # multi-line overview with emoji
forecast.to_pandas_df()         # flat DataFrame, one row per day

# Hourly forecasts (1 & 12 h free, 24/72/120 h paid)
client.get_hourly_forecast(hours=12)

# More endpoints
client.get_alerts()                       # severe-weather alerts
client.get_indices().get("running")       # lifestyle indices (pollen, UV, sports…)
client.get_historical_conditions(24)      # past 24 h observations

Units and language are configurable: WeatherClient(..., metric=False, language="nl-nl").

Async

import asyncio
from accuweather_client import AsyncWeatherClient

async def main():
    async with AsyncWeatherClient(token=API_KEY, city="sydney") as client:
        conditions, forecast = await asyncio.gather(
            client.get_current_conditions(),
            client.get_5day_forecast(),
        )
        print(conditions.current_conditions)

asyncio.run(main())

CLI

export ACCUWEATHER_API_KEY="your-api-key"   # or use --token / a .env file

accuweather now --city sydney
accuweather forecast --city sydney --days 5
accuweather hourly --lat 51.9 --lon -4.8 --hours 12
accuweather alerts --poi "Eiffel tower"

forecast and hourly print rich tables with emoji weather icons.

Location search on its own

from accuweather_client import LocationClient

locations = LocationClient(token=API_KEY)
locations.search_city("sydney").first        # best-ranked match
locations.autocomplete("syd")                # typeahead suggestions
locations.search_postal_code("1012", country="NL")
locations.search_ip()                        # geolocate the caller's IP

Supported endpoints

Method AccuWeather endpoint Free tier
get_current_conditions() currentconditions/v1/{key} ✅
get_historical_conditions(hours=6|24) currentconditions/v1/{key}/historical[/24] paid
get_daily_forecast(days=1|5|10|15) (+ get_5day_forecast() …) forecasts/v1/daily/{n}day/{key} 1, 5
get_hourly_forecast(hours=1|12|24|72|120) forecasts/v1/hourly/{n}hour/{key} 1, 12
get_alerts() alerts/v1/{key} paid
get_indices(index_id=None) indices/v1/daily/1day/{key} paid
LocationClient.search_city/poi/geoposition/postal_code/ip/autocomplete locations/v1/… ✅

Error handling

All errors derive from AccuWeatherError:

from accuweather_client.exceptions import (
    AccuWeatherError, InvalidTokenError, LocationNotFoundError,
    RateLimitExceededError, ApiRequestError, ApiServerError,
)

try:
    client.get_current_conditions()
except RateLimitExceededError as e:
    print("Daily quota used up.", e.rate_limit_headers)
except LocationNotFoundError:
    print("Try adding a country name.")

Using with AI coding assistants

This package is intentionally easy for LLM-based tools (Claude Code, Copilot, Cursor, …) to work with:

  • llms.txt — a compact, machine-readable API reference you can paste into any assistant's context.
  • Fully typed public API (py.typed) with Google-style docstrings and examples on every method, so assistants generate correct calls from signatures alone.
  • Predictable naming (get_<thing>()), typed exceptions, and models mirroring the official API field names.

Point your assistant at llms.txt or just at this README — both are written to be sufficient context for generating working integrations.

Development

git clone https://github.com/Thomas1942/AccuWeather && cd AccuWeather
uv venv && uv pip install -e '.[all]' --group dev   # or pip install -e '.[all]'
pytest          # 90%+ coverage, no network access needed
ruff check .    # lint + format
mypy            # type check

See CONTRIBUTING.md for guidelines, CHANGELOG.md for release history, ROADMAP.md for what's planned, and our Code of Conduct. Contributions are welcome — issues labeled good first issue are a great place to start.

License

MIT — this is an unofficial client; AccuWeather is a trademark of AccuWeather, Inc. Use of the API is subject to AccuWeather's terms.

Metadata

Release files for accuweather-client 2.0.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for accuweather-client 2.0.1
File Size Uploaded
accuweather_client-2.0.1.tar.gz 33.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for accuweather-client 2.0.1
File Interpreter ABI Platform
accuweather_client-2.0.1-py3-none-any.whl Python 3 none any Details

Total release size: 65.9 kB

Release files / accuweather_client-2.0.1.tar.gz

Download URL accuweather_client-2.0.1.tar.gz
Size 33.6 kB
Tags Source
SHA-256 checksum
How to use checksums
50fd9fc4206141f257c8c7c29b1e89ad92000deaf23b3975b1e4a45a7ea489d8
BLAKE2b-256 checksum
How to use checksums
f4464ecd4c27555b7647f3aaa2b8c488b135283428f39a86538cdbe64e3aba68
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.3

Release files / accuweather_client-2.0.1-py3-none-any.whl

Download URL accuweather_client-2.0.1-py3-none-any.whl
Size 32.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
2b9cde81bfac1439ce295d5073eda1eaa86e1c582c174f32a1cc4173bb324adb
BLAKE2b-256 checksum
How to use checksums
8cd99114cd29ab77d8bb78d4e26749978d19f8f0119419c611a6087a172d76bb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.3

Release history Release notifications | RSS feed

This release

2.0.1 This release

2 release files

2.0.0

2 release files

1.0.0

2 release files

0.0.4

2 release files

0.0.3

2 release files

0.0.2

2 release files

0.0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page