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.0
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.0.tar.gz | 33.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| accuweather_client-2.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 65.8 kB
Release files / accuweather_client-2.0.0.tar.gz
| Download URL | accuweather_client-2.0.0.tar.gz |
|---|---|
| Size | 33.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c44ceb1d1e7876ceffe8fd16740f23ac0bc6f8c97f1da4bbbf8d73b791f665ba
|
|
BLAKE2b-256 checksum How to use checksums |
c1ea906799a0508f1b92f4f1734b30f9c3c88e0ef095cf3374e010932b43f5e1
|
| 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.0-py3-none-any.whl
| Download URL | accuweather_client-2.0.0-py3-none-any.whl |
|---|---|
| Size | 32.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
dc5d1998e315c72deed7d5bc98d2c3a575eb81cfb1ebcbc9979d04f4efdd8f5a
|
|
BLAKE2b-256 checksum How to use checksums |
6bbf60ae007fd52f9533ef69ec7e31f7c8dd01469ed63b06d462a54a9bfb7292
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.3
|