Skip to main content

weathercloud

PyPI Python CI License: MIT

Unofficial, fully-typed Python client for Weathercloud. Read live conditions, station metadata, history, and forecasts from any public station — no account, no API key (recommended). Authentication is optional and only required if you want to access private indoor sensors (like inside temperature, humidity, and heat index) of a station you own.

⚠️ Reverse-engineered from the public web app. Not affiliated with or endorsed by Weathercloud, and the upstream endpoints may change without notice.

✨ Highlights

  • 🌡️ Typed resultsget_current_conditions() returns a CurrentConditions dataclass, not a bag of stringly-typed JSON.
  • 🧱 Raw access too — every endpoint also has a dict-returning method when you need the full payload.
  • 🧯 One exception to catch — every failure (network, HTTP, bad JSON) raises WeathercloudError.
  • 🧪 Tested & type-checked — ships py.typed, runs on Python 3.10–3.13.

📦 Installation

pip install weathercloud

🚀 Quick start

from weathercloud import WeathercloudClient

# Public data requires no login:
with WeathercloudClient() as client:
    cond = client.get_current_conditions("5726468552")

print(cond.temperature)   # 22.8
print(cond.humidity)      # 62

# Pass your credentials to fetch private indoor sensors:
with WeathercloudClient(username="my_user", password="my_password") as client:
    cond = client.get_current_conditions("5726468552")

print(cond.inside_temperature)  # 21.5 (None if not logged in)
print(cond.inside_humidity)     # 55

The client owns a requests.Session, so use it as a context manager (or call client.close()) to release connections. You can also tune the request timeout:

client = WeathercloudClient(timeout=30)   # seconds; default is 10
# or with both credentials and timeout:
client = WeathercloudClient(username="user", password="pass", timeout=15)

📖 API

get_current_conditions(device_id)CurrentConditions

Live sensor readings as a typed dataclass — the one you'll call most. Stations only report the sensors they actually have, so every field is optional: a reading the station doesn't provide comes back as None rather than raising.

Field Type Unit Field Type Unit
temperature float | None °C pressure float | None hPa
dew_point float | None °C wind_speed float | None m/s
wind_chill float | None °C wind_speed_avg float | None m/s
heat_index float | None °C wind_gust float | None m/s
humidity int | None % wind_direction int | None °
rain float | None mm rain_rate float | None mm/h
solar_radiation float | None W/m² uv_index int | None
inside_temperature float | None °C inside_humidity int | None %
inside_heat_index float | None °C epoch int | None unix ts

get_station_info(device_id, scrape_name=True)StationInfo

Station metadata. The name isn't exposed by any JSON endpoint, so it's scraped from the page <title> (one extra request). Pass scrape_name=False to skip it and use the device_id as the name instead.

info = client.get_station_info("5726468552")
info.name                   # "Ginometeo"
info.city                   # "Ingelmunster"
info.altitude               # "18.0"  (metres, as string)
info.status                 # "online" | "recently_online" | "offline" | "unknown"
info.seconds_since_update   # int
info.account_type           # 0 = free, >0 = premium

get_device_stats(device_id)dict

Current readings plus day / month / year min–max. Each value is a [unix_timestamp, value] pair, keyed as {sensor}_{period}_{type}.

stats = client.get_device_stats("5726468552")
stats["temp_day_max"]       # [1748358122, 30.9]
stats["rain_month_total"]   # [1748358122, 12.4]

get_evolution(device_id, variable, period="day")dict

Hourly history for a single sensor. period is "day", "week", "month", or "year".

from weathercloud import VariableCode

evo = client.get_evolution("5726468552", VariableCode.TEMPERATURE, "week")

Available codes: TEMPERATURE, HUMIDITY, DEW_POINT, PRESSURE, WIND_SPEED, WIND_DIRECTION, WIND_GUST, RAIN, RAIN_RATE, SOLAR_RADIATION, UV_INDEX.

get_forecast(device_id)dict

6-day WMO daily forecast for the station's location.

get_nearby_stations(lat, lon, distance_km=5)dict

Stations within a radius of a coordinate. ⚠️ Sensor values inside each result are ×10 integers — divide by 10 (e.g. temp: 281 → 28.1 °C).

Other raw methods

client.get_device_values(device_id)    # same data as get_current_conditions, raw
client.get_device_info(device_id)       # metadata + current values as strings
client.get_wind_rose(device_id)         # wind direction distribution
client.get_update_status(device_id)     # seconds since last update
client.get_owner_profile(device_id)     # observer name, hardware brand/model
client.get_station_name(device_id)      # scrape the station name only

🧯 Error handling

Every method raises WeathercloudError on failure — network error, HTTP error, non-JSON body, or an unexpected response shape. Catch the one type and you're covered.

from weathercloud import WeathercloudClient, WeathercloudError

try:
    cond = client.get_current_conditions(device_id)
except WeathercloudError as exc:
    ...  # set unavailable, log it, retry — your call

🔎 Finding a device ID

It's the number at the end of the station URL:

app.weathercloud.net/d5726468552  →  device_id = "5726468552"

METAR (airport) stations use ICAO codes (EBBR, EGLL, …) and work on most device/* endpoints — just swap the prefix to metar/*.

💡 Notes

  • 🔓 No authentication required for public endpoints (recommended). Supply credentials only if you need to fetch private inside sensors of a station you own.
  • ⏱️ Poll at most every 10 minutes — that's how often free stations update.
  • 🧭 Based on the reverse-engineered OpenAPI spec in this repo.

🛠️ Development

git clone https://github.com/MauroDruwel/Weathercloud
cd Weathercloud
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"

ruff check .      # lint
mypy              # type-check
pytest            # tests
python -m build   # build sdist + wheel

CI runs the linter, type checker, and the test matrix (Python 3.10–3.13) on every push and pull request.

Local API explorer (Swagger UI)

A Swagger UI is hosted at weathercloud-api.maurodruwel.be, or run it locally against a small CORS proxy:

pip install flask
python docs/proxy.py   # serves the proxy + Swagger UI on :8765
# then open docs/index.html

📄 License

MIT

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

weathercloud-0.1.4.tar.gz (16.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

weathercloud-0.1.4-py3-none-any.whl (12.2 kB view details)

Uploaded Python 3

File details

Details for the file weathercloud-0.1.4.tar.gz.

File metadata

  • Download URL: weathercloud-0.1.4.tar.gz
  • Upload date:
  • Size: 16.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for weathercloud-0.1.4.tar.gz
Algorithm Hash digest
SHA256 c58aebb44bddee76fd9932a8db77dd4112d42fb525d8ac396c2b54e94c8345c3
MD5 736e0e2b7c854dded47a1b8c13429a01
BLAKE2b-256 3998564f82ce1eb49000c984377b55894b9f4ecb5a06681911551d3ef5163599

See more details on using hashes here.

Provenance

The following attestation bundles were made for weathercloud-0.1.4.tar.gz:

Publisher: publish.yml on MauroDruwel/Weathercloud

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file weathercloud-0.1.4-py3-none-any.whl.

File metadata

  • Download URL: weathercloud-0.1.4-py3-none-any.whl
  • Upload date:
  • Size: 12.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for weathercloud-0.1.4-py3-none-any.whl
Algorithm Hash digest
SHA256 957f48f30a49bb082011944dd25adc39c0122784c3902802ac19ad18883a503f
MD5 1ad71d8dedf38ff660c3c98b55d62700
BLAKE2b-256 b84e64873ace18c75054e1194bfb9e0d81695af012e3318fddac52e9d856f9b3

See more details on using hashes here.

Provenance

The following attestation bundles were made for weathercloud-0.1.4-py3-none-any.whl:

Publisher: publish.yml on MauroDruwel/Weathercloud

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.1.5

2 files

This release

0.1.4 This release

2 files

0.1.3

2 files

0.1.2

2 files

0.1.1

2 files

0.1.0

2 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