Official SDKs integrate with Spanda through the Control Center API (spanda-api) — a stable
REST v1, gRPC, and WebSocket gateway. SDKs are thin clients: all business logic remains in Rust
runtime crates; the CLI and SDKs call the same APIs.
| SDK | Package | Priority | Status |
|---|---|---|---|
| Rust | spanda-sdk on crates.io |
P0 | Stable (v0.5.9 — publish via crates-sdk-v0.5.9) |
| Python | spanda-sdk on PyPI |
P1 | Stable (v0.5.9 — publish via sdk-python-v0.5.9) |
| TypeScript | @davalgi-spanda/sdk on npm |
P2 | Stable (v0.5.9 published) |
| Web panel | @davalgi-spanda/web on npm |
— | Experimental (publish via npm-web-v*) |
| Desktop | @spanda/control-center-desktop (Tauri) |
— | Stable (v0.6.3 — publish via desktop-v0.6.3 GitHub Release) |
Install from registries:
cargo add spanda-sdk
pip install spanda-sdk
npm install @davalgi-spanda/sdk
npm install @davalgi-spanda/webInstall failures (PEP 668 on Python, cargo add in the Spanda monorepo): troubleshooting.md —
Official SDK install.
Maintainers: Publishing SDKs (crates-sdk-v*, sdk-python-v*, npm-sdk-v*,
desktop-v* tags) · Control Center versioning.
Legacy Python client: packages/sdk-python (Control Center helpers; use sdk/python for full SDK
surface).
Spanda ships one Control Center API and three official client libraries — not three
different platforms. All business logic stays in Rust (spanda-api, runtime crates); each SDK is a
thin HTTP/gRPC/WebSocket client that calls the same /v1/* routes the CLI uses.
You do not need all three in one project. Pick the package that matches the language your app is written in:
| Install | Language | Typical use |
|---|---|---|
cargo add spanda-sdk |
Rust | On-robot services, embedded tools, high-performance backends, crates already in a Cargo workspace |
pip install spanda-sdk |
Python | Notebooks, CI scripts, ROS2 / rclpy bridges, ML pipelines, quick ops automation |
npm install @davalgi-spanda/sdk |
TypeScript / JavaScript | Web dashboards, Node backends, VS Code extensions, Control Center integrations |
Each SDK exposes the same operations (readiness, fleet ops, recovery, admin, …) with idiomatic
types for that ecosystem:
| SDK | Idioms |
|---|---|
| Rust | Result<T, SpandaError>, optional grpc feature for native tonic client |
| Python | dict/JSON-style responses, from spanda import SpandaClient, ROS2-friendly scripts |
| TypeScript | async/await, typed interfaces, runs in Node or bundled for the browser |
Package names differ by registry, not by capability:
- crates.io — flat name:
spanda-sdk - PyPI — same flat name:
spanda-sdk(different registry from Rust) - npm — scoped name:
@davalgi-spanda/sdk
SDK versions are bumped together when client APIs change — see versioning.md.
All three assume Control Center is running (or reachable):
spanda control-center serve --bind 127.0.0.1:8080Then connect with the client for your language — same server, same API:
// Rust
let client = SpandaClient::local();# Python
client = SpandaClient.local()// TypeScript
const client = SpandaClient.local();Install issues: troubleshooting.md — Official SDK install.
Application / Robot / Dashboard
│
▼
SDK (Rust / Python / TypeScript)
│
▼
spanda-api ── REST /v1/* ──► domain crates
│ gRPC ControlCenter
│ WS /v1/stream/telemetry
▼
spanda-readiness, spanda-assurance, spanda-config, …
Start Control Center (serves API + optional UI):
spanda control-center serve --config examples/robotics --program examples/robotics/rover.sduse spanda_sdk::SpandaClient;
let client = SpandaClient::local();
let report = client.readiness("rover.sd")?;
println!("{}", report.score.unwrap_or(0));from spanda import SpandaClient
client = SpandaClient.local()
report = client.readiness("rover.sd")
print(report["report"]["score"])import { SpandaClient } from "@davalgi-spanda/sdk";
const client = SpandaClient.local();
const report = await client.readiness("rover.sd");
console.log(report.score);| Mode | Configuration |
|---|---|
| Local | Default http://127.0.0.1:8080 — no auth for read-only program ops |
| API key | SPANDA_API_KEY or client api_key / Bearer token |
| Session JWT | OIDC sign-in — short-lived Bearer JWT (operators); see authentication.md |
| Remote | SPANDA_CONTROL_CENTER_URL |
| mTLS (transport) | Robot/fleet wire security — secure-communication.md |
Real-time events (health_changed, readiness_changed, mission_started, recovery_triggered, …)
are available via:
- WebSocket:
WS /v1/stream/telemetry - gRPC: streaming RPCs on
ControlCenterservice
See language-specific docs for stream helpers.
All SDKs expose structured errors:
SpandaError— base typeValidationError,ReadinessError,VerificationErrorSecurityError,ConnectionError,PermissionError
- Rust SDK
- Python SDK
- TypeScript SDK
- Cognitive & Resilience domain clients —
ReflexClient,HomeostasisClient,FusionClient, … - Recovery Orchestrator SDK —
planRecovery,getRecoveryPredictive,listRecoverableEntities, … (SDK 0.5.6+) - Entity Mesh SDK —
meshTopology,meshGraph,meshDiscover, … (REST 0.5.7+; TypeScriptGrpcClient0.5.8+) - Publishing SDKs (PyPI / npm / desktop)
- Control Center versioning (UI / CLI / desktop releases)
- Control Center API
| Language | Path |
|---|---|
| Rust | crates/spanda-sdk/examples/ |
| Python | examples/sdk/python/ |
| TypeScript | examples/sdk/typescript/ |
- Simulation / replay: Pass
"execute": trueonPOST /v1/programs/simulationto run the driver; replay supports"deterministic": trueand"playback": true. Default remains inspect-only metadata. - Local file paths: Program endpoints resolve paths relative to Control Center
--configproject root. - Pool vs program readiness:
POST /v1/readiness/runremains device-pool impact; usePOST /v1/programs/readinessfor CLI-equivalent program scoring.