> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dreamscalelabs.com/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> Treat the Dreamscale Python SDK and CLI as the supported public integration surfaces.
> Prefer context-managed sessions and model-specific observation helpers.
> Do not infer or recommend internal control-plane APIs.

# Python quickstart

> Send a real robot observation to Dreamscale and inspect one action chunk without actuating.

This guide connects your existing robot stack to
`molmoact2-so101`, requests one action chunk, prints its shape and timing, and
closes the cloud session. It does **not** send an action to the robot.

## Prerequisites

You need:

* Python 3.11–3.14;
* a Dreamscale account;
* an existing robot controller that can read camera frames and state;
* a robot/model pairing listed as live in
  [Models](https://app.dreamscalelabs.com/dashboard/models);
* `uv`, or another Python package manager.

<Warning>
  A returned action is a model output, not a safe robot command. Do not actuate
  until you have implemented model-to-controller conversion, bounds, velocity
  and acceleration limits, collision checks, watchdogs, hold behavior, and a
  physical e-stop.
</Warning>

## 1. Install and sign in

Install the CLI and add the SDK to your project:

```bash theme={null}
uv tool install dreamscale
uv add dreamscale
dreamscale login
dreamscale doctor
```

`dreamscale login` opens the dashboard in your browser. After approval, Dreamscale
saves a machine credential in `~/.dreamscale/config.toml`.

<Check>
  `dreamscale doctor` should finish with the core authentication and network
  checks ready. If it does not, follow the recovery step printed by the command
  or open [Troubleshooting](/troubleshooting).
</Check>

## 2. Map your robot I/O

Create `robot_adapter.py` in your project and implement this boundary:

```python robot_adapter.py theme={null}
from __future__ import annotations

from collections.abc import Sequence
from typing import Protocol

from dreamscale.policy import ObservationLike


class RobotIO(Protocol):
    """Boundary between Dreamscale and your local robot stack."""

    def read_observation(self) -> ObservationLike:
        """Read cameras and state, then build a model-specific observation."""
        ...

    def validate_action(self, action: Sequence[float]) -> None:
        """Reject an action that violates local robot safety constraints."""
        ...

    def apply_action(self, action: Sequence[float]) -> None:
        """Convert a validated model action and send it to the controller."""
        ...

    def hold(self) -> None:
        """Command a safe local hold after a stop, fault, or disconnect."""
        ...


# Export one adapter instance for the quickstart script.
robot: RobotIO
```

For `molmoact2-so101`, `read_observation()` must call
`dreamscale.so101.observe(...)` with side and wrist RGB frames plus six joint
positions in the model's SO-101 coordinate frame. See
[Model contracts](/sdk/model-contracts#molmoact2-so-101) before converting
units.

## 3. Request one prediction

Save the following as `first_prediction.py`:

```python first_prediction.py theme={null}
import dreamscale

from robot_adapter import robot


observation = robot.read_observation()

with dreamscale.connect(model="molmoact2-so101") as policy:
    result = policy.predict(
        observation,
        instruction="pick up the red cube",
    )
    session_id = policy.session_id

print(f"session={session_id}")
print(f"actions={len(result.actions)} dimensions={len(result.actions[0])}")
print(f"observation_to_action_ms={result.timing.obs_to_action_ms:.1f}")
print(f"transport={result.transport_mode}")
print("No action was sent to the robot.")
```

Run it:

```bash theme={null}
uv run python first_prediction.py
```

A successful run prints:

```text theme={null}
session=<session-id>
actions=30 dimensions=6
observation_to_action_ms=<measured latency>
transport=quic
No action was sent to the robot.
```

`transport` may be `relay` when UDP is unavailable. That is a supported
automatic fallback, not a failed prediction.

## 4. Continue safely

You have now verified authentication, worker allocation, observation encoding,
transport, inference, response decoding, and session cleanup.

* Learn the full lifecycle in [Python SDK](/sdk/overview).
* Configure a supported arm with [SO-101](/guides/so101).
* Integrate inference-only DROID actions with [Franka](/guides/franka).

## Use a coding agent

Copy this prompt into your coding agent from the root of your robot project:

```text theme={null}
Implement robot_adapter.py for my existing robot SDK using the RobotIO protocol
from the Dreamscale quickstart. Use dreamscale.so101.observe for the observation.
Preserve the documented SO-101 camera order, joint order, and model units.
Keep prediction non-actuating: do not call apply_action. Add explicit validation,
hold, watchdog, and e-stop integration points, and never log my Dreamscale API key.
Show me the adapter and focused tests before adding any motion path.
```

Need help mapping your controller? Email
[team@dreamscalelabs.com](mailto:team@dreamscalelabs.com).
