⌘K
Python client
packages/api/python holds a small Python client for /api/v1, generated from the OpenAPI spec. Standard library only (no requests), Python 3.9 or newer.
Last updated: · Markdown version
packages/api/python holds a small Python client for /api/v1, generated from the OpenAPI spec. Standard library
only (no requests), Python 3.9 or newer.
from timetracking_api import ApiError, Client
api = Client("tt_live_…") # API key, or a user access token (+ org_id="…")
people = api.list_persons(query={"limit": 100}) # {"items": [...], "next_cursor": ...}
unit = api.create_unit(body={"kind": "branch", "name": "Heerlen"})
try:
api.get_person("00000000-0000-0000-0000-000000000000")
except ApiError as e:
print(e.status, e.code, e.reason)
print(api.rate_limit) # last X-RateLimit-* values: limit, remaining, reset (epoch seconds)
What the client does for you:
- One method per operation: the
operationIdin snake_case (listPersons→list_persons). Path parameters are positional arguments,body=is the JSON body,query=the query string. Methods return the unwrappeddata. - Writes (POST, PUT, PATCH, DELETE) get an
Idempotency-Key(or passidempotency_key=), reused on every retry, so a retried write is never applied twice. 429: waitsRetry-After(or untilX-RateLimit-Reset) and retries, up tomax_retries(default 3). A wait longer thanmax_retry_delay(default 60 s) raisesApiErrorinstead.502/503/504and network errors are retried with backoff for calls that are safe to repeat (GET, or a write with an Idempotency-Key).- Response types:
timetracking_api.schemashas oneTypedDictper schema of the spec.
Rate limits: 120 requests per minute per API key, 300 per minute per login for user access tokens (see rate limits).
Regenerate after an API change (from the repository root):
pnpm --filter @tt/api generate # openapi.json + TypeScript types
pnpm --filter @tt/api generate:python # python/timetracking_api/schemas.py + operations.py
pnpm --filter @tt/api test checks that both are up to date and runs the Python smoke test when python3 is
installed.