auki-session-py
This page mirrors bindings/python/auki-session-py/README.md in the auki-sdk repo (branch develop).
The repository is the source of truth.
PyO3 bindings for auki-session — Python surface for the SDK's declarative control-plane API. Shipped in #224; tracks the post-#282 Peer / Session split.
Status: Shipped. Tested in python_tests/. Cluster lifecycle is not in this package — Python daemons drive auki-domain-py's ClusterManager directly (the Rust Domain::join path has no Python binding yet).
Public surface
Peer class
from auki_session import Peer, FrameDef, HeadSpec, SensorLogSpec
peer = Peer("12D3KooW...", "galbot-ctrl").with_storage_root("/data/auki")
frame = peer.register_frame("head_left_optical", FrameDef.ros_optical())
sensor = peer.register_sensor("head_left_rgb", {"kind": "camera", "type": "rgb", ...})
session = peer.start_session()
Peer(peer_id, app_id)— long-lived identity;peer_idis the libp2p peer-id string. The peer outlives any one session.with_storage_root(path)— in-place builder; mutates the peer's storage root and returnsselffor chaining. Under the hood, calls Rust'sPeer::set_storage_root(the binding-friendly sibling ofPeer::with_storage_root(self, root) -> Self).- Read accessors:
peer_id,app_id,storage_root. register_sensor(sensor_id, body_dict)—body_dicthas"kind"and"type"fields (e.g.{"kind": "camera", "type": "rgb", ...}).register_frame(frame_id, FrameDef)— takes aFrameDefpreset object. Classmethods:FrameDef.ros_body(),FrameDef.ros_optical(),FrameDef.opengl(),FrameDef.unity().register_detector(detector_id, body_dict, output_types: list[str]).start_session()→Session— mints a ULIDsession_idand auto-registers the session's monotonic + UTC clocks ({peer_id}/{session_id}/monotonic/…/utc).
Each register_* returns a RegistryRef instance (peer_id, id, hash). IDs must not contain >, @, or whitespace.
Session class
Sessions are born from peer.start_session() — there is no Python Session constructor.
- Read accessors:
peer_id,app_id,session_id,storage_root. register_clock(clock_id, body_dict)— additional session-scoped clocks.
Not yet exposed: the Rust Session::monotonic_clock() / utc_clock() getters for the auto-minted clock pair — Python apps that need a clock RegistryRef for a log spec register their own via register_clock.
Log registration
Each returns a typed handle with resource_id and log_ref attributes. Specs take RegistryRef instances or dicts.
register_sensor_log(SensorLogSpec)→SensorLogHandle—resource_idissensor.id.register_pose_log(PoseLogSpec)→PoseLogHandle—resource_idis"<from_frame.id>-><to_frame.id>".register_time_transform_log(TimeTransformLogSpec)→TimeTransformLogHandle—resource_idis"<from_clock.id>-><to_clock.id>".register_detection_log(DetectionLogSpec)→DetectionLogHandle—resource_idis"<detector.id>@<input_sensor.id>".
HeadSpec factory methods: HeadSpec.rolling(retention_ns), HeadSpec.fixed().
LogRef class: LogRef(source_peer_id, resource_id).
Async stubs (raise NotImplementedError)
materialize_remote_log(log_ref, *, retention_ns, segment_duration_ns)— deferred to Phase 5.resolve_static_transform(log_ref)— deferred to Phase 5.
Catalog and domain — not here
catalog() and join_domain / leave_domain were removed with the #282 split (they no longer exist on the Rust Session either). Resource catalogs and cluster lifecycle live in auki-domain-py (ClusterManager, ResourceEntry).
Type sharing
RegistryRef and LogRef come from auki-registry-py. This package re-exports them in the auki_session namespace so callers can import from either package. Input parsing is duck-typed: any object with the right field names (including auki_registry.RegistryRef instances, plain dicts, or SimpleNamespace) is accepted.
Depends on
auki-session— Rust crate it wraps.auki-registry— forRegistryRef/LogRefRust types.auki-registry-py— source-of-truth forRegistryRef/LogRefpyclasses.auki-manifests— forPoseSource,PoseWriterMode,TimeTransformSource.