Async client for the Parkeren Den Haag API
Project description
pythehagueparking
Async client library for the Parkeren Den Haag API, designed for Home Assistant custom integrations but usable in any asyncio project.
Features
- Async-only HTTP calls via aiohttp
- Auth helper with automatic re-login on 401/403
- Typed dataclass models with parsed fields
- Caller-owned aiohttp session (no session management in the library)
- Caller-provided API base URL (use
DEFAULT_BASE_URLfor production)
Installation
python -m pip install pythehagueparking
Quick start
from aiohttp import ClientSession
from pythehagueparking import Auth, DEFAULT_BASE_URL, TheHagueParkingAPI
async def main() -> None:
async with ClientSession() as session:
auth = Auth(
session,
username="user",
password="pass",
base_url=DEFAULT_BASE_URL,
)
api = TheHagueParkingAPI(auth)
account = await api.async_get_account()
reservations = await api.async_list_reservations()
favorites = await api.async_list_favorites()
print(account, reservations, favorites)
API reference
API methods:
async_get_account() -> Account: Fetch account details.async_list_reservations() -> list[Reservation]: List reservations.async_create_reservation(name, license_plate, reservation_starts_at, reservation_ends_at) -> Reservation: Create a reservation (timestamps are ISO 8601Zstrings).async_set_reservation_end_time(reservation_id, *, end_time) -> Reservation: Update a reservation end time (ISO 8601Zstring).async_delete_reservation(reservation_id) -> None: Delete a reservation.async_list_favorites() -> list[Favorite]: List favorites.async_create_favorite(name, license_plate) -> Favorite: Create a favorite.async_update_favorite(favorite_id, name, license_plate) -> Favorite: Update a favorite.async_delete_favorite(favorite_id) -> None: Delete a favorite.
Example usage:
from datetime import UTC, datetime, timedelta
from aiohttp import ClientSession
from pythehagueparking import Auth, DEFAULT_BASE_URL, TheHagueParkingAPI
async with ClientSession() as session:
api = TheHagueParkingAPI(
Auth(session, "user", "pass", base_url=DEFAULT_BASE_URL)
)
starts_at = datetime.now(tz=UTC).replace(microsecond=0)
ends_at = (starts_at + timedelta(hours=2)).replace(microsecond=0)
starts_at_iso = starts_at.isoformat(timespec="seconds").replace("+00:00", "Z")
ends_at_iso = ends_at.isoformat(timespec="seconds").replace("+00:00", "Z")
extended_ends_at_iso = (
(ends_at + timedelta(hours=1))
.replace(microsecond=0)
.isoformat(timespec="seconds")
.replace("+00:00", "Z")
)
reservation = await api.async_create_reservation(
name="My Car",
license_plate="12-AB-34",
reservation_starts_at=starts_at_iso,
reservation_ends_at=ends_at_iso,
)
await api.async_set_reservation_end_time(
reservation.id,
end_time=extended_ends_at_iso,
)
await api.async_delete_reservation(reservation.id)
from pythehagueparking import __version__
print("pythehagueparking", __version__)
from aiohttp import ClientSession
from pythehagueparking import Auth, DEFAULT_BASE_URL, TheHagueParkingAPI
async with ClientSession() as session:
api = TheHagueParkingAPI(
Auth(session, "user", "pass", base_url=DEFAULT_BASE_URL)
)
favorites = await api.async_list_favorites()
if favorites:
favorite = favorites[0]
await api.async_update_favorite(
favorite.id,
name="My Car",
license_plate=favorite.license_plate,
)
from aiohttp import ClientSession
from pythehagueparking import Auth, DEFAULT_BASE_URL, RateLimitError, TheHagueParkingAPI
async with ClientSession() as session:
api = TheHagueParkingAPI(
Auth(session, "user", "pass", base_url=DEFAULT_BASE_URL)
)
try:
await api.async_list_reservations()
except RateLimitError as err:
print("Retry after:", err.retry_after)
API notes
- Start and end times are ISO 8601 UTC strings ending with
Z(seconds precision). - Naive timestamps (without
Z/offset) are treated as UTC. - Incoming timestamps are normalized to ISO 8601 UTC strings ending with
Z. - Provide
permit_media_type_idtoAuthto sendx-permit-media-type-idheaders when required.
Session ownership
- You always pass your own
aiohttp.ClientSession. - The library never creates or closes sessions.
Model fields and mapping
- Public methods return typed dataclasses with fields mapped from API payloads.
- Each model exposes parsed values instead of raw payload dictionaries.
Field mapping:
-
Account
id: intremaining_time: int(wasdebit_minutes)active_reservation_count: int(wasreservation_count)
-
Zone
id: intname: strstart_time: str(ISO 8601 UTC,Z)end_time: str(ISO 8601 UTC,Z)
-
Reservation
id: intlicense_plate: strname: strstart_time: str(ISO 8601 UTC,Z)end_time: str(ISO 8601 UTC,Z)
-
Favorite
id: intlicense_plate: strname: str
Compatibility notes
- Python 3.13.2+ is required, matching Home Assistant 2025.12.
- Async-only (
aiohttp); no synchronous wrapper is provided.
Error handling
AuthErrorfor authentication failures or expired sessionsParkingConnectionErrorfor network errors and timeoutsRateLimitErrorfor HTTP 429 responses (seeretry_after)ParseErrorfor unexpected response payloadsaiohttp.ClientResponseErrorfor HTTP status errors (raise_for_status)
Development
python -m pip install -e '.[test,dev]'
pytest
ruff check .
mypy
License
MIT License. See LICENSE and NOTICE.
Support
For questions or issues, open a GitHub issue: https://github.com/sir-Unknown/pythehagueparking/issues
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pythehagueparking-0.3.3.tar.gz.
File metadata
- Download URL: pythehagueparking-0.3.3.tar.gz
- Upload date:
- Size: 10.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e8cdd01c3561779404c4427ebc36d8f564e14f349f1d596dd4e11e71895ca858
|
|
| MD5 |
50d44ebfbaf5a8212a5420b7b62dea1d
|
|
| BLAKE2b-256 |
c7e548b65a504b594e5ace8fea214aa91599821279c3e39d8a025c4aabd7e9ba
|
Provenance
The following attestation bundles were made for pythehagueparking-0.3.3.tar.gz:
Publisher:
publish.yml on sir-Unknown/pyTheHagueParking
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pythehagueparking-0.3.3.tar.gz -
Subject digest:
e8cdd01c3561779404c4427ebc36d8f564e14f349f1d596dd4e11e71895ca858 - Sigstore transparency entry: 779504847
- Sigstore integration time:
-
Permalink:
sir-Unknown/pyTheHagueParking@6d0b544c0b7ee15d378eddede4530f3fbda4cebd -
Branch / Tag:
refs/tags/v0.3.3 - Owner: https://github.com/sir-Unknown
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@6d0b544c0b7ee15d378eddede4530f3fbda4cebd -
Trigger Event:
push
-
Statement type:
File details
Details for the file pythehagueparking-0.3.3-py3-none-any.whl.
File metadata
- Download URL: pythehagueparking-0.3.3-py3-none-any.whl
- Upload date:
- Size: 11.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ac900f2be24def5f603e87394363de72f92099a13a05c99cd2349e04e9df9b48
|
|
| MD5 |
927b55a1d502e91a6bda74766343391c
|
|
| BLAKE2b-256 |
de1dda170b96e5a7ddd7c9ef9e7170a6890b728af66b27a610c1a530aac5010e
|
Provenance
The following attestation bundles were made for pythehagueparking-0.3.3-py3-none-any.whl:
Publisher:
publish.yml on sir-Unknown/pyTheHagueParking
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pythehagueparking-0.3.3-py3-none-any.whl -
Subject digest:
ac900f2be24def5f603e87394363de72f92099a13a05c99cd2349e04e9df9b48 - Sigstore transparency entry: 779504849
- Sigstore integration time:
-
Permalink:
sir-Unknown/pyTheHagueParking@6d0b544c0b7ee15d378eddede4530f3fbda4cebd -
Branch / Tag:
refs/tags/v0.3.3 - Owner: https://github.com/sir-Unknown
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@6d0b544c0b7ee15d378eddede4530f3fbda4cebd -
Trigger Event:
push
-
Statement type: