accuweather-client
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 withcountry="canada", use apoi="Eiffel tower", or alat/lonpair. The location key is resolved and cached for you. - Typed everywhere. Every response is a documented pydantic model, the package ships a
py.typedmarker, and every public method has a complete docstring — your IDE (and your AI assistant) autocompletes the whole API. - Sync and async.
WeatherClientandAsyncWeatherClientmirror 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 dedicatedRateLimitExceededErrorcarrying theRateLimit-*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)
| File | Size | Uploaded | |
|---|---|---|---|
| accuweather_client-2.0.1.tar.gz | 33.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| 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
|