Async Python client for the DIVERA 24/7 REST API.
Project description
divera247
An async Python client for the DIVERA 24/7 REST API
and WebSocket push stream, built on httpx
and pydantic.
Installation
pip install divera247
# or, with uv:
uv add divera247
Optional: WebSocket streaming
The push-event WebSocket subscription talks to wss://ws.divera247.com/ws via
httpx-ws, which is kept out of the
default install for users who only need the REST API. Install it through the
ws extra:
pip install 'divera247[ws]'
# or, with uv:
uv add 'divera247[ws]'
Quickstart
import anyio
from divera247 import AccessKeyAuth, Divera247Client
async def main() -> None:
async with Divera247Client(auth=AccessKeyAuth('YOUR_ACCESS_KEY')) as client:
alarms = await client.alarm.get_alarms()
for alarm in alarms.data or []:
print(alarm)
anyio.run(main)
Every v2 endpoint group is exposed as a lazily-instantiated attribute on
Divera247Client:
| Attribute | Endpoint group |
|---|---|
client.alarm |
/api/v2/alarms |
client.attachment |
/api/v2/attachments |
client.auth_api |
/api/v2/auth |
client.dashboard |
/api/v2/dashboard |
client.event |
/api/v2/events |
client.file |
/api/v2/file |
client.message |
/api/v2/messages |
client.message_channel |
/api/v2/message-channels |
client.news |
/api/v2/news |
client.operations |
/api/v2/operations |
client.password |
/api/v2/password |
client.pull |
/api/v2/pull |
client.reporttype |
/api/v2/reporttypes |
client.shift_plans |
/api/v2/shift-plans |
client.statusgeber |
/api/v2/statusgeber |
client.using_vehicle |
/api/v2/using-vehicles |
client.using_vehicle_crew |
/api/v2/using-vehicles/... |
client.using_vehicle_property |
/api/v2/using-vehicles/... |
Authentication
Three auth flows are provided in divera247.auth, all of which set the
Authorization: Bearer <token> header so the same credentials work for both
REST and WebSocket:
from divera247 import AccessKeyAuth, JwtAuth, RefreshingJwtAuth
# Static access key (simplest; no token refresh).
AccessKeyAuth('YOUR_ACCESS_KEY')
# Pre-obtained JWT.
JwtAuth('eyJhbGciOi...')
# Access-key backed JWT that is fetched on first use and refreshed shortly
# before `exp`. Safe to share between concurrent tasks.
RefreshingJwtAuth('YOUR_ACCESS_KEY')
Error handling
HTTP errors and envelope errors (success: false) are both funnelled through
the hierarchy in divera247.errors:
from divera247 import (
DiveraAPIError,
DiveraAuthError,
DiveraRateLimitError,
DiveraValidationError,
)
try:
await client.alarm.get_alarms()
except DiveraAuthError:
... # 401 / 403
except DiveraRateLimitError as exc:
await anyio.sleep(exc.retry_after or 1)
except DiveraValidationError as exc:
print(exc.errors) # field -> message mapping
except DiveraAPIError as exc:
print(exc.status_code, exc.body) # catch-all for other HTTP errors
Endpoints that return the standard {"success": ..., "data": ...} envelope
can be additionally guarded with ensure_success(parsed) when success=false
bodies should turn into exceptions.
Customising the HTTP client
Divera247Client is deliberately a thin wrapper: its own constructor only
takes the auth, an optional base_url, and an optional pre-built
session. Anything you'd normally configure on an httpx.AsyncClient --
timeouts, headers (including User-Agent), proxies, transports, event hooks
-- is done by building your own client and passing it in via session=:
import httpx
async with httpx.AsyncClient(
auth=AccessKeyAuth('...'),
base_url='https://app.divera247.com/api/',
timeout=httpx.Timeout(60.0, connect=15.0),
headers={'User-Agent': 'my-app/1.0', 'Accept-Language': 'de'},
proxy='http://proxy.local:3128',
verify=False,
) as external:
client = Divera247Client(auth=AccessKeyAuth('...'), session=external)
...
When a session= is passed the caller keeps ownership: the session is
not closed when the client is exited.
WebSocket streaming
Two entry points live in divera247.websocket:
subscribe_websocket(client, ...)yields events from a single session and exits when the server disconnects. Use it when you want to drive your own reconnect policy.stream_websocket(client, ...)wrapssubscribe_websocketin a jittered exponential-backoff reconnect loop. Use it when you want a "just keep me subscribed" iterator.
from divera247.websocket import (
ClusterPullEvent,
ClusterVehicleEvent,
UnknownEvent,
UserStatusEvent,
stream_websocket,
)
async for event in stream_websocket(client, ucr_id=1_234):
match event:
case UserStatusEvent(ucr=ucr, status=status):
... # status is a PullStatusData
case ClusterPullEvent(cluster=cluster, pull=pull):
... # re-fetch pull.type (e.g. "alarm") + pull.id
case ClusterVehicleEvent(cluster=cluster, vehicle=vehicle):
... # vehicle.id / vehicle.fmsstatus_id update
case UnknownEvent():
... # forward-compatible fallback
WebSocketAuthenticationError propagates out of the loop so an unusable
credential doesn't get retried forever.
API schemas
The schemas/ directory contains the vendor-published OpenAPI YAML files
that this client was built against -- see schemas/README.md
for details and the mapping to divera247.endpoints / divera247.models.
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 divera247-0.0.1b5.tar.gz.
File metadata
- Download URL: divera247-0.0.1b5.tar.gz
- Upload date:
- Size: 50.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.7 {"installer":{"name":"uv","version":"0.11.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
08fe4d97272d33e6f0cc4c268698b19ce72eaae933eff0b459478d13e4232b93
|
|
| MD5 |
0863857bc61fffa6737c09a5916ff8e9
|
|
| BLAKE2b-256 |
6d261ee916ffd8d683415462e39830873c39ff0effde4aa5ab38bff55c826526
|
File details
Details for the file divera247-0.0.1b5-py3-none-any.whl.
File metadata
- Download URL: divera247-0.0.1b5-py3-none-any.whl
- Upload date:
- Size: 70.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.7 {"installer":{"name":"uv","version":"0.11.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4131c756687cc3c52f664a25b7bb1bb8ea3a3ef7fb346c13066d68a0b1b16799
|
|
| MD5 |
1bdfd10ae194849c9c930301220fdaac
|
|
| BLAKE2b-256 |
83ecbcc179e4def98cbb7f816611593c2161a3568c7da5277e5ec184253e8c57
|