Skip to content

Releases: jasonjhofmann/aranet-cloud

v0.2.1

11 Jun 04:57
b96fcbf

Choose a tag to compare

Error-contract hardening from the remaining v0.1.0 audit findings. No API changes.

Fixed

  • get_bytes (binary attachment downloads) no longer leaks a raw TimeoutError — timeouts are now retried and, once retries are exhausted, wrapped in AranetConnectionError, matching the JSON path and the documented "all errors derive from AranetError" contract.
  • The polite-spacing floor (_respect_min_interval) now runs before every attempt of a binary download, not just once before the retry loop, so retries can no longer hammer the API back-to-back.
  • A 200 response whose body is valid JSON but not an object (e.g. a top-level array or string) now raises AranetServerError instead of surfacing later as an AttributeError outside the exception hierarchy.
  • AranetRateLimitError.retry_after is now populated from the final 429 response's Retry-After header (the value already honoured for backoff) instead of attempting to float() the response body, which effectively always yielded None.

Full Changelog: v0.2.0...v0.2.1

v0.2.0 — audit hardening

10 Jun 21:18

Choose a tag to compare

Hardening release from a code audit. One breaking change: numeric measurement values are now float | None.

Changed

  • Breaking: Reading.value, Alarm.value, and Alarm.worst are now float | None. A null (or unparseable) value from the API surfaces as None instead of being silently coerced to 0.0 — missing data can no longer masquerade as a genuine zero reading (e.g. 0 ppm CO₂).
  • Sample payloads in docs/ and the test fixtures are now fully synthetic: all real identifiers replaced with fabricated equivalents (originals remain in git history prior to this release).

Fixed

  • The configured request timeout (default 30 s) is now applied to every request, including when an aiohttp.ClientSession is injected by the caller. Previously it only took effect on transport-owned sessions, so Home Assistant-style deployments silently ran with aiohttp's 300 s default.

Security

  • Server-supplied pagination next links are only followed when their origin (scheme + host + port) matches the configured base_url. A foreign host or https→http downgrade raises AranetError instead of being requested with the ApiKey header attached.

Note: this release is not yet on PyPI — the repo has no automated publish workflow and no publish credentials were available at release time. PyPI still has 0.1.0.

v0.1.0 — Initial release

28 May 03:38

Choose a tag to compare

Async client for every endpoint in the Aranet Cloud OpenAPI 3.0 spec (27 GETs, read-only), typed dataclass models, hidden pagination, full exception hierarchy.

Available on PyPI: pip install aranet-cloud==0.1.0

Added

  • AranetCloudClient — async client with one method per documented endpoint:
    • Sensors: get_sensors, get_sensor, get_sensor_types, get_sensor_type
    • Measurements: get_measurements_last, iter_measurements_history
    • Telemetry: get_telemetry_last, iter_telemetry_history
    • Bases: get_bases, get_base
    • Alarms: get_alarms_actual, get_alarms_history, get_alarm_rules, get_alarm_rule
    • Assets: get_assets, get_asset
    • Tags: get_tags, get_tag
    • Catalog: get_metrics, get_metric, get_unit
    • Attachments: download_sensor_attachment, download_asset_attachment
  • 21 dataclasses covering the response schemas, each with a from_dict that silently ignores unknown fields (forward-compatible).
  • Exception hierarchy: AranetError (base), AranetAuthError (401), AranetValidationError (400 with correlation_id), AranetRateLimitError (429 with retry_after), AranetServerError (5xx after retries), AranetConnectionError, AranetNotFoundError.
  • Async-iterator paginationiter_measurements_history and iter_telemetry_history follow the next URL transparently.
  • Exponential-backoff retry on 5xx / 429 / transient network errors, capped at 30 s; honours server-supplied Retry-After on 429.
  • Polite-spacing floor (250 ms) between successive requests.
  • Optional session injection — pass an existing aiohttp.ClientSession; lib auto-creates and owns its session otherwise.
  • py.typed marker for PEP-561 type checkers.
  • 23 unit + integration tests against aioresponses.

Notes

  • Live-verified end-to-end against the production Aranet Cloud API on 2026-05-19.
  • Build tooling: ruff (lint), mypy --strict (types), pytest + pytest-asyncio (tests), hatchling (wheel/sdist).