Skip to main content

Python client for the Menlo Robot Control Service (RCS) control plane.

Project description

menlo-robot-sdk

Python client for the Robot Control Service (RCS) control plane: robot CRUD and LiveKit session lifecycle.

⚠️ Alpha — Not for Production Use

This package is in active development and may have breaking changes between minor versions. APIs are subject to change. Use at your own risk.

Roadmap — Stage 0 (control plane) is shipped; Stages 1–5 cover production hardening, command/telemetry API, identity, publishing, and observability. No fixed dates — see docs/ROADMAP.md and issue #125.

Rough product spec (connect, skills, runtime helpers): ADR 0002 — what works today vs blocked on RCS (#136).

Install

uv add menlo-robot-sdk

# With LiveKit support
uv add "menlo-robot-sdk[livekit]"
cd packages/py/menlo-robot-sdk
uv sync --all-extras --dev
uv run python -c "from menlo_robot_sdk import AsyncClient; print('ok')"

Path dependency from another uv project:

[tool.uv.sources]
menlo-robot-sdk = { path = "../../packages/py/menlo-robot-sdk", editable = true }

When PyPI publishing lands (ROADMAP Stage 4): uv add menlo-robot-sdk and uv add "menlo-robot-sdk[livekit]".

Configuration

See .env.example for all client env vars (placeholders only — no secrets).

Variable Description
MENLO_RCS_URL RCS base URL (e.g. http://localhost:8002)
MENLO_IDENTITY Full X-Menlo-Identity header value (JWS or unsigned JSON)
MENLO_IDENTITY_FILE Path to file containing identity (overrides MENLO_IDENTITY)
MENLO_ROBOT_SDK_TIMEOUT Per-request timeout in seconds (default 30)
MENLO_ROBOT_SDK_MAX_RETRIES Max retries on transport errors / safe HTTP codes (default 2)
MENLO_ROBOT_SDK_DEBUG Set to 1 to log httpx request/response events
MENLO_LIVEKIT_URL Optional override for connect_session() when RCS returns an internal hostname
MENLO_RCS_INTEGRATION Set to 1 to run integration tests (see MANUAL_TESTING.md)

MENLO_API_KEY alone is not supported for RCS; use MENLO_IDENTITY until token exchange ships (#136). Rough-spec url = MENLO_RCS_URL / MenloSettings.url.

Pass MenloSettings or omit rcs_url / identity on Client / AsyncClient to load from env. If you pass rcs_url and identity explicitly, you must pass both; passing only one raises ValueError. Optional timeout / max_retries override env defaults when using the env path.

robots.update(robot_id, name=...) sends only the keyword arguments you provide (omitted fields are not sent as null).

from menlo_robot_sdk import AsyncClient, DevIdentity, MenloSettings, workers

settings = MenloSettings.from_env()
# or local unsigned JSON:
settings = MenloSettings(
    rcs_url="http://localhost:8002",
    identity=DevIdentity(sub="user_dev", organization_id="org_dev", team_id="team_dev").to_header(),
)

async with AsyncClient(settings=settings) as client:
    created = await client.robots.create(name="Lab bot", model="asimov-v0")
    print(created.pin_code)  # show-once PIN — save securely

    page = await client.robots.list(limit=20)
    async for robot in client.robots.iter(limit=50):
        print(robot.id)

    session = await client.robots.create_session(
        created.robot.id,
        workers=workers.for_rcs_stack(),
    )

LiveKit (optional)

from menlo_robot_sdk.livekit import connect_session

room = await connect_session(session)  # uses session.livekit_url
# room = await connect_session(session, livekit_url=<URL reachable from your host>)  # override for Docker

In a sync-only script (no running event loop), use asyncio.run(connect_session(session)).

Connect helper (rough spec — partial)

from menlo_robot_sdk import AsyncClient, ConnectCallbacks, connect, workers

async with AsyncClient() as client:
    handle = await connect(
        client,
        "rb_myrobot",
        workers=workers.for_rcs_stack(),
        join_livekit=False,  # default True needs menlo-robot-sdk[livekit] for LiveKit + callbacks
    )
    # handle.get_robot_status(), invoke(), … raise MenloNotAvailableError until mono#136
    await handle.disconnect()

See ADR 0002 for the full matrix.

Errors and retries

RCS errors use { "code", "message", "details" }. The SDK raises MenloAPIError for HTTP status ≥ 400. Retries (default 2) apply to transport failures and 429 on safe methods; POST /v1/robots and POST …/session are not retried. Backoff is capped at 30s. See ADR 0001.

Examples

Runnable cookbooks (one use case per file, flat snippets): examples/README.md. Run after local rcs-stack — see MANUAL_TESTING.md.

Testing

Development

cd packages/py/menlo-robot-sdk
uv sync --all-extras --dev
cd ../../../services/rcs && uv sync --frozen --no-dev && cd ../../packages/py/menlo-robot-sdk
uv run python scripts/export_rcs_openapi.py
uv run python scripts/regen_models.py --check
uv run ruff check .
uv run mypy src
uv run pytest -q
export MENLO_RCS_INTEGRATION=1
uv run pytest tests/integration -m integration -q   # live RCS; see MANUAL_TESTING.md

Publishing

This package is published to PyPI via GitHub Actions on version tags. No API token needed — uses PyPI Trusted Publishing (OIDC).

To release a new version:

# 1. Bump version in pyproject.toml
cd packages/py/menlo-robot-sdk
# Edit version in pyproject.toml, then:
uv lock

# 2. Commit and merge to main
git add pyproject.toml uv.lock
git commit -m "chore: bump menlo-robot-sdk to v0.5.0"
# ... push PR, get approval, merge

# 3. Create and push the version tag (triggers publish workflow)
git checkout main && git pull
git tag menlo-robot-sdk-v0.5.0
git push origin menlo-robot-sdk-v0.5.0

The workflow .github/workflows/menlo-robot-sdk-publish.yml builds and publishes automatically. Check the Actions tab for status.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

menlo_robot_sdk-0.1.0.tar.gz (27.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

menlo_robot_sdk-0.1.0-py3-none-any.whl (25.6 kB view details)

Uploaded Python 3

File details

Details for the file menlo_robot_sdk-0.1.0.tar.gz.

File metadata

  • Download URL: menlo_robot_sdk-0.1.0.tar.gz
  • Upload date:
  • Size: 27.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for menlo_robot_sdk-0.1.0.tar.gz
Algorithm Hash digest
SHA256 afde8bb9877d6376be9e43ea99ee79aa1c919f37d896ea25206c3e86c00a9a70
MD5 7baf6c3a16d7bd9850d0b0608108b27b
BLAKE2b-256 b8c25783df381519486043208bc8b73c0167717796b4301d149a195566471cf6

See more details on using hashes here.

Provenance

The following attestation bundles were made for menlo_robot_sdk-0.1.0.tar.gz:

Publisher: menlo-robot-sdk-publish.yml on menloresearch/mono

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file menlo_robot_sdk-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for menlo_robot_sdk-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 9a08f57bd3935c4844935664e54a2def581ede560d0275d8dc5863124829716d
MD5 2748e7f8aba7b47307f2f6f046387ffe
BLAKE2b-256 1972304e19628b94afcb5773bab6cb8d50b358f39c352312d1ac629361aa1661

See more details on using hashes here.

Provenance

The following attestation bundles were made for menlo_robot_sdk-0.1.0-py3-none-any.whl:

Publisher: menlo-robot-sdk-publish.yml on menloresearch/mono

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page