Async client for the CityParkingPermit parking service
Project description
pyCityParkingPermit
Async client for the CityParkingPermit parking service, built for Home Assistant custom integrations and any asyncio project.
Highlights
- Async-only HTTP calls via
aiohttp; you own theClientSession. - Auth helper handles login and retries on 401/403 with cached defaults.
- Typed dataclass models expose ISO 8601 timestamp strings.
- Reservation and favorite helpers map CityParkingPermit Permit endpoints.
- Requires the CityParkingPermit
base_urlto target your environment.
Requirements
- Python 3.13.2+ (matches Home Assistant 2025.12)
aiohttp>=3.10.0
Installation
python -m pip install pyCityParkingPermit
Quick start
import asyncio
from aiohttp import ClientSession
from pyCityParkingPermit import Auth, CityParkingPermitAPI
BASE_URL = "https://cityparkingpermit.example"
async def main() -> None:
async with ClientSession() as session:
auth = Auth(session, username="user", password="pass", base_url=BASE_URL)
api = CityParkingPermitAPI(auth)
account = await api.async_get_account()
reservations = await api.async_list_reservations()
favorites = await api.async_list_favorites()
print(account, reservations, favorites)
asyncio.run(main())
Auth requires the CityParkingPermit base_url; set it to your tenant's endpoint.
API overview
async_get_account() -> Account: Fetch account details with remaining time and active reservation count.async_get_zone() -> Zone | None: Fetch the paid block for the current day.async_list_reservations() -> list[Reservation]: List active reservations.async_create_reservation(...) -> Reservation: Create a reservation.async_end_reservation(...) -> None: End a reservation.async_delete_reservation(reservation_id) -> None: Alias for ending a reservation.async_list_favorites() -> list[Favorite]: List favorites.async_create_favorite(...) -> Favorite: Create a favorite.async_update_favorite(...) -> Favorite: Update a favorite by remove + upsert.async_delete_favorite(...) -> None: Delete a favorite.
Creating and ending a reservation:
from datetime import UTC, datetime, timedelta
from aiohttp import ClientSession
from pyCityParkingPermit import Auth, CityParkingPermitAPI
async with ClientSession() as session:
api = CityParkingPermitAPI(
Auth(session, "user", "pass", base_url="https://cityparkingpermit.example")
)
starts_at = datetime.now(tz=UTC)
ends_at = starts_at + timedelta(hours=2)
reservation = await api.async_create_reservation(
license_plate_value="12-AB-34",
license_plate_name="My Car",
date_from=starts_at,
date_until=ends_at,
)
await api.async_end_reservation(reservation_id=reservation.id)
Managing favorites:
await api.async_update_favorite(name="My Car", license_plate="12-AB-34")
await api.async_delete_favorite(name="My Car", license_plate="12-AB-34")
Reading the package version:
from pyCityParkingPermit import __version__
print("pyCityParkingPermit", __version__)
API notes
- Datetimes are sent as ISO 8601 strings with seconds precision.
- Incoming timestamps are normalized to ISO 8601 UTC strings;
ZoneandReservationtimestamp fields are always strings, notdatetimeobjects. - Session ownership: you always pass your own
aiohttp.ClientSession; the library never creates or closes sessions.
Error handling
from aiohttp import ClientSession
from pyCityParkingPermit import Auth, CityParkingPermitAPI, RateLimitError
async with ClientSession() as session:
api = CityParkingPermitAPI(
Auth(session, "user", "pass", base_url="https://cityparkingpermit.example")
)
try:
await api.async_list_reservations()
except RateLimitError as err:
print("Retry after:", err.retry_after)
AuthErrorfor authentication failures or expired sessions.ParkingConnectionErrorfor network errors and timeouts.RateLimitErrorfor HTTP 429 responses (retry_afterhints).ParseErrorfor unexpected response payloads.aiohttp.ClientResponseErroris raised for other HTTP errors viaraise_for_status().
Development
python -m pip install -e '.[test,dev]'
python -m pip install pre-commit
pre-commit install
pre-commit run --all-files
pytest tests/
ruff check .
ruff format .
mypy
Support and security
- Issues: https://github.com/sir-Unknown/pyCityParkingPermit/issues
- Security: https://github.com/sir-Unknown/pyCityParkingPermit/security/policy
MIT License. See LICENSE and NOTICE.
Project details
Release history Release notifications | RSS feed
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 pycityparkingpermit-0.3.0.tar.gz.
File metadata
- Download URL: pycityparkingpermit-0.3.0.tar.gz
- Upload date:
- Size: 12.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5e8cc826b253cb180ff1760aebe64e28d7f318f040f11820c4c1f1138aa63293
|
|
| MD5 |
603cda8018f71bde6344872279d8bb7b
|
|
| BLAKE2b-256 |
7157073164dc54ba1a2c72bc787977d61d40cffbaab670aee6cb7426d5d6828c
|
Provenance
The following attestation bundles were made for pycityparkingpermit-0.3.0.tar.gz:
Publisher:
publish.yml on sir-Unknown/pyCityParkingPermit
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pycityparkingpermit-0.3.0.tar.gz -
Subject digest:
5e8cc826b253cb180ff1760aebe64e28d7f318f040f11820c4c1f1138aa63293 - Sigstore transparency entry: 779253671
- Sigstore integration time:
-
Permalink:
sir-Unknown/pyCityParkingPermit@b825dc7db20d3290539948a77128214d57e73e05 -
Branch / Tag:
refs/tags/v0.3.0 - Owner: https://github.com/sir-Unknown
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@b825dc7db20d3290539948a77128214d57e73e05 -
Trigger Event:
push
-
Statement type:
File details
Details for the file pycityparkingpermit-0.3.0-py3-none-any.whl.
File metadata
- Download URL: pycityparkingpermit-0.3.0-py3-none-any.whl
- Upload date:
- Size: 13.4 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 |
cbbee75269c595a4e10c81dfae119578aab3f6775ea98a36cebba3f78c79e1a5
|
|
| MD5 |
00d5d0a8f0cd0fe7dbac05893fcbe95b
|
|
| BLAKE2b-256 |
c5e49b45b8239d1931fefc15b878e97c3afa07de2c5da39c1a1602cc0919bda6
|
Provenance
The following attestation bundles were made for pycityparkingpermit-0.3.0-py3-none-any.whl:
Publisher:
publish.yml on sir-Unknown/pyCityParkingPermit
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pycityparkingpermit-0.3.0-py3-none-any.whl -
Subject digest:
cbbee75269c595a4e10c81dfae119578aab3f6775ea98a36cebba3f78c79e1a5 - Sigstore transparency entry: 779253672
- Sigstore integration time:
-
Permalink:
sir-Unknown/pyCityParkingPermit@b825dc7db20d3290539948a77128214d57e73e05 -
Branch / Tag:
refs/tags/v0.3.0 - Owner: https://github.com/sir-Unknown
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@b825dc7db20d3290539948a77128214d57e73e05 -
Trigger Event:
push
-
Statement type: