Python SDK
Operator client plus a robot-side helper for emitting structured logs that flow back to the dashboard.
The Python SDK has two shapes living in the same package:
Client— operator-side. Talks to the control plane over HTTPS. This is the analog of the TypeScriptRoboflareClient.Roboflare— robot-side. Writes structured JSONL records to the log path the agent tails, so your robot app can callRoboflare.log(...)and have lines show up in the dashboard log debugger.
Install
The SDK lives in this monorepo as sdk/python. Until it is published to
PyPI, install in editable mode:
pip install -e ./sdk/pythonOperator client
from roboflare import Client
with Client(token="rf_org_...") as rf:
robots = rf.robots.list()
print(f"{len(robots)} robots online")
release = rf.releases.create({"semver": "1.2.3", "notes": "speed tune"})
print(release["id"])The client unwraps Roboflare's { "data": ... } / { "items": [...] }
envelope automatically — list endpoints return the array, single-object
endpoints return the inner data.
Resources
rf.robots.list()
rf.robots.inspect(robot_id)
rf.robots.logs(robot_id)
rf.releases.list()
rf.releases.create({"semver": "1.2.3"})
rf.configs.list()
rf.configs.set({"name": "...", "namespace": "...", "payload": {...}})
rf.enrollment_keys.list()
rf.enrollment_keys.create({"site_id": "...", "fleet_id": "..."})
rf.enrollment_keys.revoke(key_id)Errors
Non-2xx responses raise RuntimeError with the API's error message
extracted from the { "error": { "message": "..." } } envelope. Catch
and inspect:
try:
rf.releases.create({})
except RuntimeError as e:
print("API rejected:", e)Robot-side Roboflare helper
On the robot, your application emits structured records and the agent tails them into the tunnel — your code never opens a socket.
from roboflare import Roboflare
robot = Roboflare.connect() # reads ROBOFLARE_LOG_PATH or defaults to ~/.roboflare/app.log
robot.log("starting pick task", task_id="abc123")
robot.event("pick_complete", duration_ms=842)
robot.metric("battery_pct", 73.2)
robot.ros_node("nav2_lifecycle_manager", status="running")
robot.rosbag("/var/lib/rosbags/2026-05-20T08-00.bag", action="started")Every call appends one JSON record to the log file with ts, level,
source, message, and the extra fields you passed. The agent tails
that file and streams it to the dashboard's log debugger.
Set ROBOFLARE_LOG_PATH if you want to write somewhere other than
~/.roboflare/app.log — useful when running your app inside a container
that mounts a host-side log volume.