Quickstart
This page mirrors docs/wiki/Quickstart.md in the auki-sdk repo (branch develop).
The repository is the source of truth.
Boot an auki-session peer, declare its sensors / clocks / frames, register a sensor log, and inspect what the SDK writes to the catalog and to disk. ~10 minutes.
This page covers what the Peer / Session API exposes today (SDK v0.0.57, post-#282 split). The remaining pieces โ publishing frames into the log, joining a domain so other peers can see your catalog, materializing a remote peer's log โ are tracked separately; see Next steps.
What you'll buildโ
A single peer that:
- declares its peer / app identity and registers a reference frame and a camera sensor
- starts a session (the SDK mints the session id and the session's clocks)
- registers a sensor log (one peer-owned data product)
- emits a catalog row for that log
- writes a manifest to disk
Installโ
Rustโ
In Cargo.toml:
[dependencies]
auki-session = { git = "https://github.com/aukilabs/auki-sdk.git", tag = "v0.0.57" }
auki-registry = { git = "https://github.com/aukilabs/auki-sdk.git", tag = "v0.0.57" }
auki-domain = { git = "https://github.com/aukilabs/auki-sdk.git", tag = "v0.0.57" }
Pythonโ
From source for now (PyPI publishing is on the roadmap):
pip install "auki-session @ git+https://github.com/aukilabs/auki-sdk.git@v0.0.57#subdirectory=bindings/python/auki-session-py"
Construct a peer, start a sessionโ
Since #282 the entry point is a long-lived Peer that mints Sessions. The identities split across the two:
peer_idโ your network identity, on thePeer. Stable across boots for this device. (Any string works for local experiments; to join a domain later it must be the libp2p peer-id derived from your wallet.)app_idโ the app running on this peer (e.g.galbot-ctrlvsgalbot-teleop), on thePeer.session_idโ fresh ULID minted byPeer::start_session(), on theSession.
The storage root is where the SDK writes its registry entries and log manifests. Starting a session also auto-registers the session's monotonic + UTC clock pair (#284) โ no hand-rolled session clock.
Rust
use auki_session::Peer;
let peer = Peer::new("galbot-01", "galbot-ctrl")
.with_storage_root("/data/auki/galbot-01".into());
let session = peer.start_session().unwrap();
println!("session_id: {}", session.session_id());
Python
from auki_session import Peer
peer = Peer("galbot-01", "galbot-ctrl").with_storage_root("/data/auki/galbot-01")
session = peer.start_session()
print("session_id:", session.session_id)
Register a reference frameโ
A sensor log carries spatial data, so the data needs to be expressed in some frame of reference. Frames are peer-level (they outlive any one session), so registration happens on the Peer. The SDK ships four presets covering the common conventions:
FrameDef::ros_body() // x forward, y left, z up
FrameDef::ros_optical() // x right, y down, z forward (camera-frame default)
FrameDef::opengl() // x right, y up, z back
FrameDef::unity() // x right, y up, z forward (left-handed)
Rust
use auki_session::FrameDef;
let frame = peer.register_frame("head_left_camera_optical", FrameDef::ros_optical()).unwrap();
Python
from auki_session import FrameDef
frame = peer.register_frame("head_left_camera_optical", FrameDef.ros_optical())
The return value is a RegistryRef { peer_id, id, hash } โ pass that to anything that needs to reference this frame.
Register a sensorโ
The sensor declares what the data looks like (camera intrinsics, format, etc.). Sensors are peer-level too. The closed enum SensorKind (Camera, Imu, ...) keeps the family tight; the open type string differentiates within a family.
Rust
use auki_registry::{Camera, SensorBody};
let sensor = peer.register_sensor("head_left_rgb", SensorBody::Camera(Camera {
r#type: "rgb".into(),
width: 1920,
height: 1200,
frame_rate_hz: 30,
pixel_format: "rgb8".into(),
color_space: "srgb".into(),
intrinsics_model: "pinhole".into(),
distortion_model: "brown_conrady".into(),
frame: frame.clone(),
})).unwrap();
Python
sensor = peer.register_sensor("head_left_rgb", {
"kind": "camera",
"type": "rgb",
"width": 1920,
"height": 1200,
"frame_rate_hz": 30,
"pixel_format": "rgb8",
"color_space": "srgb",
"intrinsics_model": "pinhole",
"distortion_model": "brown_conrady",
"frame": {"peer_id": frame.peer_id, "id": frame.id, "hash": frame.hash},
})
Clocksโ
Every timestamp the SDK records is qualified by a named clock, so consumers can transform between clocks rather than assuming a canonical one.
Since #284 you usually don't register a clock yourself: start_session() already registered the session's monotonic + UTC pair, and Rust code grabs them directly:
Rust
let clock = session.monotonic_clock(); // RegistryRef to the auto-minted session clock
The Python binding doesn't expose the monotonic_clock() / utc_clock() getters yet, so from Python register an additional session-scoped clock (also the path for custom clocks in Rust, via session.register_clock(...)):
Python
clock = session.register_clock("session/sdk_clock", {
"type": "monotonic_clock",
"unit": "ns",
"monotonic": True,
"scope": "device-local",
})
Register a sensor logโ
The log is the actual peer-owned data product, and it belongs to the session. The spec ties together the sensor, the clock its samples are stamped against, the frame the data lives in, and a head window that controls retention.
Rust
use std::time::Duration;
use auki_session::{HeadSpec, SensorLogSpec};
let log = session.register_sensor_log(SensorLogSpec {
sensor: sensor.clone(),
clock,
frame: Some(frame),
head: HeadSpec::Rolling { retention_ns: 5_000_000_000 },
segment_duration: Duration::from_secs(1),
retention: Duration::from_secs(5),
}).unwrap();
println!("log_ref: {}/{}", log.log_ref().source_peer_id, log.log_ref().resource_id);
Python
from auki_session import HeadSpec, SensorLogSpec
log = session.register_sensor_log(SensorLogSpec(
sensor=sensor,
clock=clock,
frame=frame,
head=HeadSpec.rolling(5_000_000_000),
segment_duration_ns=1_000_000_000,
retention_ns=5_000_000_000,
))
print("log_ref:", log.log_ref.source_peer_id, "/", log.log_ref.resource_id)
Inspect the catalogโ
auki_domain::catalog_of(&peer, &session) returns one ResourceEntry row per registered log, in the /auki/resources/0.2.0 wire shape โ pure and network-free. This is the same payload Domain::join serves over the network so others can discover what this peer owns.
Over the network, /auki/resources/0.2.0 is a live snapshot of resources that
are currently requestable. A peer may join before every producer is ready.
Consumers should poll and reconcile rows that appear or disappear; producers
should omit resources that cannot currently accept stream opens and re-add the
same stable resource_id when they recover.
Rust
for row in auki_domain::catalog_of(&peer, &session) {
println!("{} owns {} ({})", row.source_peer_id, row.resource_id, row.state);
}
Prints:
galbot-01 owns head_left_rgb (live)
Python โ catalog building moved to the domain layer with #282 and isn't exposed from auki-session-py; Python daemons see catalog rows through auki-domain-py's ClusterManager resource fetches.
Inspect the manifest on diskโ
$ cat /data/auki/galbot-01/logs/galbot-01/head_left_rgb/manifest.json
{
"source_peer_id": "galbot-01",
"writer_peer_id": "galbot-01",
"sensor": { ... },
"clock": { ... },
...
}
source_peer_id == writer_peer_id says this is a locally-written, locally-owned log. When another peer materializes a copy, the materialized manifest preserves source_peer_id == "galbot-01" and sets writer_peer_id to the materializing peer โ ownership stays with the source. See Concept: Peer-Owned Logs.
Next stepsโ
The Peer / Session API doesn't yet expose, at this layer:
- Publishing frames into the log. A
SensorLogHandle::append-style surface is planned. The underlyingauki-logs::Log::appendexists; lifting it onto the session handle is the natural next step. - Joining a domain so other peers see your catalog.
auki_domain::Domain::join(&peer, &session, config)works in Rust but requires building a libp2p swarm yourself; there is no Python binding for it yet โ Python daemons driveauki-domain-py'sClusterManagerdirectly. - Materializing a remote peer's log.
Session::materialize_remote_logreturnsNotImplementedErrorโ this is the Phase 5 deliverable in the #216 plan.
This page will grow to cover each as it lands.
Worked exampleโ
The full working version of everything above lives in crates/auki-session/tests/end_to_end.rs. Copy it, swap the peer_id, and cargo test.
For the Python equivalent, see bindings/python/auki-session-py/python_tests/test_session.py โ specifically test_register_sensor_log_end_to_end and test_catalog_resource_id_and_shape.
โ Back to: For SDK Consumers ยท Concept: Peer-Owned Logs โ