DataNet Python SDK — async realtime pub/sub client for the DataNet platform
Project description
DataNet Python SDK
Async Python client for the DataNet realtime platform. Supports pub/sub over WebSocket with automatic reconnection and heartbeats. Payloads can be JSON values and nested data structures, bytes-like binary payloads, or content-type-labeled formats such as DMX, Art-Net, float vectors, BLE batches, and compact interaction frames.
Requirements
- Python 3.11+
aiohttp>= 3.9websockets>= 12.0
Installation
Install from PyPI:
pip install datanet-sdk
For local development from this repo:
pip install -e .[dev]
Quick start
Async pattern (recommended)
import asyncio
from datanet import DataNet
async def main():
dn = DataNet(api_key="ak_your_key_here")
async def on_message(data, meta):
print(f"[{meta.channel}] {data}")
async with dn: # connects, disconnects on exit
dn.subscribe("project.abc.sensor", on_message)
await asyncio.sleep(60) # keep running
asyncio.run(main())
Sync / background-thread pattern
For scripts that don't manage their own event loop:
import time
from datanet import DataNet
dn = DataNet(api_key="ak_your_key_here")
@dn.on("connect")
async def handle_connect():
print("Connected!")
@dn.on("error")
async def handle_error(exc):
print(f"Error: {exc}")
async def on_sensor(data, meta):
print(f"sensor reading: {data}")
dn.connect_sync() # blocks until connected, runs in bg thread
dn.subscribe("project.abc.sensor", on_sensor)
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
dn.disconnect_sync()
API reference
DataNet(api_key, device_id=None, client_id=None, device_name=None, api_url=..., ws_url=..., max_reconnect_attempts=5)
| Parameter | Default | Description |
|---|---|---|
api_key |
— | Your DataNet API key (ak_...) |
device_id |
— | Stable device identifier for presence/history |
client_id |
— | Optional app/client identifier |
device_name |
— | Optional display name for dashboards/admin tools |
api_url |
https://api.datanet.art |
REST API base URL |
ws_url |
wss://ws.datanet.art |
WebSocket base URL |
max_reconnect_attempts |
5 |
Max consecutive reconnects; 0 = unlimited |
Payload formats
The Python SDK supports the same protocol classes as the JavaScript SDK:
- JSON scalars, arrays, dictionaries, and nested structures via
publish(...). - Bytes-like values (
bytes,bytearray,memoryview) viapublish(...)auto-detection. - Explicit binary packets via
publish_binary(...). - DMX frames via
build_dmx_frame(...)/publish_dmx(...). - Art-Net ArtDMX packets via
build_art_dmx_packet(...)/publish_artnet(...). - Mixed JSON and binary subscriptions via
subscribe_any(...).
Binary messages include metadata with the packet: channel, from_,
timestamp, content_type, bytes, and optional custom metadata.
When connected to an older gateway that still emits raw binary WebSocket frames,
the SDK falls back safely and marks those messages with metadata={"raw": True}.
from datanet import DataNet, build_dmx_frame
dn = DataNet(api_key="ak_your_key_here")
frame = build_dmx_frame([255, 80, 20, 180], 512)
async with dn:
await dn.publish_binary(
"project.abc.lighting.dmx",
frame,
content_type="binary/dmx",
metadata={"universe": 1, "format": "dmx512"},
)
Local development
When you want to test against a local gateway instead of production, pass the URLs explicitly:
dn = DataNet(
api_key="ak_local_key_here",
api_url="http://localhost:8080",
ws_url="ws://localhost:8080",
)
The bundled examples automatically load configuration from a repo-level .env
file if present. Copy the template once, add your real key/channel values, and
keep .env local:
cp .env.example .env
The examples also support shell environment overrides, which take precedence
over values in .env:
DATANET_API_KEY='ak_local_key_here' \
DATANET_CHANNEL='demo.text.basic' \
DATANET_API_URL='http://localhost:8080' \
DATANET_WS_URL='ws://localhost:8080' \
python examples/publish.py
Binary examples
The JSON examples use DATANET_CHANNEL.
The binary DMX examples use DATANET_BINARY_CHANNEL first, then fall back to
DATANET_CHANNEL if no binary channel is set. Use the same binary channel for
both publisher and subscriber:
DATANET_API_KEY='ak_local_key_here' \
DATANET_BINARY_CHANNEL='project.abc.lighting.dmx' \
python examples/binary_dmx_subscribe.py
In another terminal:
DATANET_API_KEY='ak_local_key_here' \
DATANET_BINARY_CHANNEL='project.abc.lighting.dmx' \
python examples/binary_dmx_publish.py
To drive the browser p5 visualizer demo directly with pixel coordinates:
DATANET_API_KEY='ak_local_key_here' \
DATANET_CHANNEL='demo.text.basic' \
DATANET_API_URL='http://localhost:8080' \
DATANET_WS_URL='ws://localhost:8080' \
DATANET_X_MIN='0' \
DATANET_X_MAX='1000' \
DATANET_Y_MIN='0' \
DATANET_Y_MAX='450' \
python examples/publish_p5.py
Methods
| Method | Description |
|---|---|
await connect() |
Fetch JWT and open WebSocket |
connect_sync(timeout=10) |
Same, but runs in a background thread |
await disconnect() |
Close connection and stop run loop |
disconnect_sync(timeout=10) |
Close a sync/background-thread connection |
subscribe(channel, handler) |
Register an async message handler |
unsubscribe(channel, handler=None) |
Remove handler (or all) from channel |
await publish(channel, data, content_type=None, metadata=None) |
Send JSON, or auto-detect bytes-like binary data |
await publish_binary(channel, data, content_type=..., metadata=None) |
Send binary bytes with content type and metadata |
await publish_dmx(channel, values, length=512, metadata=None) |
Publish a clamped DMX frame as binary/dmx |
await publish_artnet(channel, dmx, ..., metadata=None) |
Publish an ArtDMX packet as binary/artnet |
subscribe_binary(channel, handler, content_type=None) |
Register an async binary handler |
subscribe_any(channel, handler) |
Register an async handler for JSON and binary messages |
on(event, handler) |
Register an event handler (decorator or direct) |
Events
| Event | Handler signature | Fired when |
|---|---|---|
"connect" |
async def() |
WebSocket connection established |
"disconnect" |
async def() |
Connection closed |
"error" |
async def(exc) |
An error occurs |
MessageMeta
Passed as the second argument to every message handler:
@dataclass
class MessageMeta:
channel: str # e.g. "project.abc.sensor"
from_: str # sender connection ID
timestamp: int # Unix timestamp (ms) from the server
BinaryMessageMeta
Passed as the second argument to every binary message handler:
@dataclass
class BinaryMessageMeta:
channel: str
from_: str
timestamp: int
content_type: str
bytes: int
metadata: dict | None = None
Reconnection
The SDK reconnects automatically with exponential backoff:
| Attempt | Delay |
|---|---|
| 1st | 1 s |
| 2nd | 2 s |
| 3rd | 4 s |
| 4th | 8 s |
| 5th | 16 s |
| subsequent | capped at 30 s |
All subscriptions are replayed after each reconnect.
Logging
The SDK uses Python's standard logging module under the logger name datanet.client.
import logging
logging.basicConfig(level=logging.DEBUG)
Examples
See the examples/ directory:
basic_subscribe.py— subscribe and print messagespublish.py— publish simulated sensor readingspublish_p5.py— publish p5-stylex/ycoordinatesbinary_dmx_publish.py— publish binary DMX framesbinary_dmx_subscribe.py— subscribe to binary DMX frames
Standalone showcase projects that use the published package live in datanet-examples.
For custom clients or other SDK implementations, see PROTOCOL.md.
Tests
python -m pip install -e .[dev]
python -m pytest
About
DataNet is developed and supported by Studio Jordan Shaw, a creative technology studio building tools for realtime, networked, and physical-digital work.
- DataNet: datanet.art
- Studio: jordanshaw.com
- Instagram: @jshaw3
- GitHub: datanet-art
- Source: datanet-python
- Examples: datanet-examples
License
MIT
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 datanet_sdk-0.1.0.tar.gz.
File metadata
- Download URL: datanet_sdk-0.1.0.tar.gz
- Upload date:
- Size: 25.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c3f323d2e588ed208004afe6f63bafe777f241b328c1fea5bed6ab7e27b49af7
|
|
| MD5 |
c63c95ec30216196598e872597ee818a
|
|
| BLAKE2b-256 |
2ce61ddb87cc34c83272949d1f1286ab45476a942cd060736163f7bf7c45d89e
|
Provenance
The following attestation bundles were made for datanet_sdk-0.1.0.tar.gz:
Publisher:
release.yml on datanet-art/datanet-python
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
datanet_sdk-0.1.0.tar.gz -
Subject digest:
c3f323d2e588ed208004afe6f63bafe777f241b328c1fea5bed6ab7e27b49af7 - Sigstore transparency entry: 1806412189
- Sigstore integration time:
-
Permalink:
datanet-art/datanet-python@19061e11446e10a24d60f644298c6ee5b413ff15 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/datanet-art
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@19061e11446e10a24d60f644298c6ee5b413ff15 -
Trigger Event:
push
-
Statement type:
File details
Details for the file datanet_sdk-0.1.0-py3-none-any.whl.
File metadata
- Download URL: datanet_sdk-0.1.0-py3-none-any.whl
- Upload date:
- Size: 15.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5f1601d65ed72425a3ce11fd62025346feb04b4096e93a236f6f0d26d666d74e
|
|
| MD5 |
53deb3aff712251fe4a3e67f81931fc2
|
|
| BLAKE2b-256 |
643a2a46fc68c7cc97eb6aa90b87508053cd2d9ff0553cfb0e16a18bb5d1e683
|
Provenance
The following attestation bundles were made for datanet_sdk-0.1.0-py3-none-any.whl:
Publisher:
release.yml on datanet-art/datanet-python
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
datanet_sdk-0.1.0-py3-none-any.whl -
Subject digest:
5f1601d65ed72425a3ce11fd62025346feb04b4096e93a236f6f0d26d666d74e - Sigstore transparency entry: 1806412231
- Sigstore integration time:
-
Permalink:
datanet-art/datanet-python@19061e11446e10a24d60f644298c6ee5b413ff15 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/datanet-art
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@19061e11446e10a24d60f644298c6ee5b413ff15 -
Trigger Event:
push
-
Statement type: