embodied-ops
embodied-ops is a small Python contract for composing embodied systems without
coupling applications to a particular robot framework or middleware. Its core remains
dependency-free; the grpc extra adds a versioned local service boundary.
It standardizes:
- capability-oriented device manifests;
- typed observation and action feature descriptions;
- strict, non-clamping scalar validation;
- lifecycle and health protocols;
- backend discovery through the standard
embodied_ops.backendsentry-point group; - an optional Protobuf/gRPC transport over Unix-domain sockets.
It intentionally does not own ROS nodes, robot drivers, teleoperation mappings, datasets, policy runtimes, process supervision, or safety limits. Those belong to installed backends and application runtimes.
Backend contract
An integration publishes a factory in pyproject.toml:
[project.entry-points."embodied_ops.backends"]
my_robot = "my_robot_runtime.backend:create_backend"
The factory accepts a plain mapping and returns an OperationalDevice. Constructing
the device must not open hardware; callers explicitly invoke connect() or use
device_session().
from embodied_ops import create_device
robot = create_device("my_robot", {"config": "robot.toml"})
robot.connect()
try:
print(robot.manifest.to_dict())
print(robot.health())
finally:
robot.disconnect()
Additional capabilities are expressed structurally through ObservableDevice,
CommandDevice, CalibratableDevice, and ResettableDevice. Adapters such as
LeRobot plugins translate these contracts into their framework-native interfaces.
RPC boundary
Install the optional transport when an adapter and its hardware runtime must live in separate processes:
python -m pip install "embodied-ops[grpc]"
The runtime owns the real device and serves it; clients receive only the manifest and capability operations:
from embodied_ops.rpc import DeviceRpcServer, RemoteDevice
endpoint = "unix:///run/my-robot/device.sock"
server = DeviceRpcServer(
device,
endpoint=endpoint,
lease_timeout_s=1.0,
command_timeout_s=0.5,
)
server.start()
robot = RemoteDevice(endpoint=endpoint, client_name="my-adapter")
robot.connect()
Protocol v1 provides describe, observe, command, health, calibration, and reset RPCs.
It carries scalar features and dependency-free typed tensor payloads. Command sessions
are exclusive and use opaque session ids, contiguous command sequence numbers,
monotonic timestamps, server-owned leases, and an independent command-inactivity
deadman. Heartbeats prove session liveness but do not keep an idle command lease alive.
Observe-only sessions may coexist. Devices that implement CommandLeaseDevice can
release their command resources while keeping read-only observation attached; other
devices retain the conservative disconnect-on-command-close behavior. The hardware
runtime remains responsible for its final fail-closed behavior.
Only absolute unix:/// endpoints are accepted in v1. TCP/TLS policy is intentionally
not implied by the local protocol.
Versioning
The Python package follows semantic versioning. DeviceManifest.api_version versions
the capability contract independently. The wire handshake has its own
protocol_version; both are currently version 1.
Development
uv sync --extra grpc --dev
uv run pytest
uv run ruff check .
uv run ruff format --check .
uv build
License
Apache-2.0
Metadata
Release files for embodied-ops 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| embodied_ops-0.2.0.tar.gz | 27.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| embodied_ops-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 55.5 kB
Release files / embodied_ops-0.2.0.tar.gz
| Download URL | embodied_ops-0.2.0.tar.gz |
|---|---|
| Size | 27.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
ba3cee8160f7aa06f8f17f9225c6aa64421f9fcf43be219cd852d656023e9f8c
|
|
BLAKE2b-256 checksum How to use checksums |
9c227e3873f1b5a49cfe4100175003a70f52b1658a696b5066cce4badefb7dcd
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.8 {"installer":{"name":"uv","version":"0.11.8","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"22.04","id":"jammy","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / embodied_ops-0.2.0-py3-none-any.whl
| Download URL | embodied_ops-0.2.0-py3-none-any.whl |
|---|---|
| Size | 28.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
c9df41e429cdebfd66a05fb1ad224819b9627844207c55bbcfa3cbd1e9ce959e
|
|
BLAKE2b-256 checksum How to use checksums |
344089ef2eb06f52f183e0492a4e5641be093c97c461fe2590f95e128357a5b5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.8 {"installer":{"name":"uv","version":"0.11.8","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"22.04","id":"jammy","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|