Sandbox
Create, find, connect to and control sandboxes, and their lifecycle: wait, suspend, resume, restart, detach and delete.
cua.sandboxes() returns the Sandboxes collection; each sandbox is a Sandbox handle. The same options run locally and in the cloud: on is the switch (local, cloud, direct:<addr>), kind and runtime pick the machine.
Python programs usually use the high-level API instead: cua_sandbox.Sandbox.
A sandbox's id() is its ref, and every call that takes a sandbox name accepts one:
| Ref | Meaning |
|---|---|
local:<name> | A sandbox on this computer |
aws:<name> | A sandbox in your own cloud (gcp: and modal: the same way) |
direct:<host:port> | A computer reached by address |
relay:<computer-id> | An account computer reached through the relay (a Space) |
<name> | A bare name, searched across locations; AmbiguousSandbox when it matches more than one |
Readiness never assumes a guest agent: the provider reports the sandbox running, then the wait_for probes run, and creation fails fast if the sandbox exits.
Sandboxes#
Creates, finds and manages sandboxes.
Returned by Cua.sandboxes.
| Method | Description |
|---|---|
cancel_create | Cancels the create of the named sandbox name that is still running (in this process or the daemon): the work in flight stops (an image download, a boot) and what the create made is deleted; a sandbox of that name that existed before is never touched. |
connect | Reattaches to a sandbox by ref (local:<name>, cloud:<name>, direct:<host:port>, a legacy id) or by a name that is unique across locations (else AmbiguousSandbox, listing the qualified refs). |
connect_url | Connects directly to a machine by URL (http(s)://host:port, bare host:port or a relay URL) with an optional spacesd token. |
create | Creates (local, your cloud, a provider) or connects (direct) a sandbox and waits for the provider and every readiness probe. |
delete | Deletes a sandbox by ref or unique name. |
get | One sandbox's info, by ref or unique name. |
list | Sandboxes, each tagged with its location. |
list_all | Deprecated: Sandboxes.list with no location lists everything. |
list_with_warnings | Sandboxes.list with what the listing left out. |
bake | Bakes a Docker Compose project into a checkpoint that forks start from with its containers already running: a local VM (by default the docker tier, dockerd up at boot), the project uploaded, docker compose up --wait, the stack checked (every service running or healthy, none restarted) and health commands passed, run commands, then a live memory checkpoint. |
checkpoint | Saves sandbox name's state as checkpoint (memory and disk on a microVM or a QEMU VM; a container's filesystem). |
checkpoints | Every checkpoint: this machine's (oldest first), then those your machines that provide Spaces hold, each name once (CheckpointSummary.host). |
create_pool | Creates a pool: sandboxes of image (and options' shape) kept ready on this machine by cua daemon, so that a create from the pool (SandboxCreateOptions.pool) takes one in about 0.1 s. |
delete_checkpoint | Deletes a checkpoint, here and on every machine of yours that holds a copy (forks made from it keep running). |
delete_pool | Deletes pool name: its ready sandboxes go; sandboxes created from it stay. |
fork | Starts name from a sandbox (running or stopped) or a checkpoint. |
fork_groups | Sandboxes.fork_many for several checkpoints at once: each group (the forks of one checkpoint that belong together) goes to one machine, and groups of different checkpoints spread. |
fork_many | Forks checkpoint source count times at once and returns the running batch: each fork is reported as soon as it is ready (or failed: one failure does not stop the others). |
get_pool | Pool name, with what it holds now. |
list_pools | Every pool, with what each holds now. |
pin_checkpoint | Pins (pinned) or unpins a checkpoint. |
prune_checkpoints | Deletes every checkpoint that is not pinned (forks made from them keep running); returns their names. |
publish_checkpoint | Uploads checkpoint name to fallback (S3, or a folder every machine mounts), so batches on your other machines copy it from there when this machine cannot be reached. |
Sandboxes.cancel_create#
Cancels the create of the named sandbox name that is still
running (in this process or the daemon): the work in flight stops
(an image download, a boot) and what the create made is
deleted; a sandbox of that name that existed before is never
touched. Finished image downloads stay cached. Returns what was
removed, or None when no create of that name was running. The
create itself fails with Cancelled.
async def cancel_create(self, name: str) -> Optional[str]| Parameter | Type | Default |
|---|---|---|
name | String | required |
Returns Option<String> · Async · Raises CuaError (Cancelled)
Sandboxes.connect#
Reattaches to a sandbox by ref (local:<name>, cloud:<name>,
direct:<host:port>, a legacy id) or by a name that is unique across
locations (else AmbiguousSandbox, listing the qualified refs).
async def connect(self, name: str) -> Sandbox| Parameter | Type | Default |
|---|---|---|
name | String | required |
Returns Sandbox · Async · Raises CuaError (AmbiguousSandbox)
Sandboxes.connect_url#
Connects directly to a machine by URL (http(s)://host:port, bare
host:port or a relay URL) with an optional spacesd token. No daemon is assumed and nothing is probed.
async def connect_url(self, url: str, token: Optional[str], name: Optional[str]) -> Sandbox| Parameter | Type | Default |
|---|---|---|
url | String | required |
token | Option<String> | required |
name | Option<String> | required |
Returns Sandbox · Async · Raises CuaError
Example
import asyncio
import cua
async def main():
sb = await cua.embedded().sandboxes().connect_url(URL, TOKEN, "dev") # your spacesd's address and token
guest = await sb.spacesd(None)
out = await guest.run(cua.SpacesdCommand(program="echo", args=["hi"]))
print(out.stdout)
asyncio.run(main())Sandboxes.create#
Creates (local, your cloud, a provider) or connects (direct) a sandbox
and waits for the provider and every readiness probe. on: "cloud"
fails with the "Cua Cloud has ended" error.
async def create(self, options: SandboxCreateOptions) -> Sandbox| Parameter | Type | Default |
|---|---|---|
options | SandboxCreateOptions | required |
Returns Sandbox · Async · Raises CuaError
Example
import asyncio
import cua
async def main():
c = cua.embedded()
sb = await c.sandboxes().create(cua.SandboxCreateOptions(
on="local", # or "aws"
image=cua.canonical_image("linux", None),
name="dev",
wait_for=[cua.ReadinessProbe(service="env")], # until its spacesd answers
))
guest = await sb.spacesd(None)
print((await guest.sh("uname -a", None)).stdout.decode())
await sb.delete()
asyncio.run(main())Sandboxes.delete#
Deletes a sandbox by ref or unique name.
async def delete(self, name: str) -> None| Parameter | Type | Default |
|---|---|---|
name | String | required |
Async · Raises CuaError
Sandboxes.get#
One sandbox's info, by ref or unique name.
async def get(self, name: str) -> SandboxInfo| Parameter | Type | Default |
|---|---|---|
name | String | required |
Returns SandboxInfo · Async · Raises CuaError
Sandboxes.list#
Sandboxes, each tagged with its location. None (the default):
all of them, local and direct, whatever the default location is.
"local" or "direct": only those. Cua Cloud has ended, so
"cloud" lists none.
async def list(self, location: Optional[str]) -> List[SandboxInfo]| Parameter | Type | Default |
|---|---|---|
location | Option<String> | required |
Returns Vec<SandboxInfo> · Async · Raises CuaError
Sandboxes.list_all#
Deprecated: Sandboxes.list with no location lists everything.
async def list_all(self) -> List[SandboxInfo]Returns Vec<SandboxInfo> · Async · Raises CuaError
Sandboxes.list_with_warnings#
Sandboxes.list with what the listing left out.
async def list_with_warnings(self, location: Optional[str]) -> SandboxListing| Parameter | Type | Default |
|---|---|---|
location | Option<String> | required |
Returns SandboxListing · Async · Raises CuaError
Sandbox#
A sandbox handle.
Returned by Sandboxes.connect, Sandboxes.connect_url, Sandboxes.create, Sandboxes.fork.
| Method | Description |
|---|---|
overlay | Injects binaries (see Overlay): each replaces its guest file atomically, is recorded under /var/lib/cua/overlays with its sha256, and what runs it is restarted. |
spacesd | Attaches to cua-spacesd inside the sandbox (the env service or guest port 3211). |
viewer_url | A browser link to this sandbox's desktop in the cua-spacesd HTML5 viewer (/viewer on the env service): video, audio, input, clipboard, file drop and folder sharing, in any modern browser. |
agents | Coding agents inside this sandbox (needs cua-spacesd): run a harness over ACP, stream normalized events, follow up, interrupt, collect results; runs outlive this handle. |
delete | Deletes (local: removes it; direct: forgets it; your cloud: deletes the machine). |
expires_at_unix | When this sandbox's lifetime ends (Sandbox.set_lifetime), as Unix seconds; None when it has none. |
forward | Forwards a loopback port to guest port: a TCP forward locally (and over cua-spacesd's tunnel when the image has it). |
guest_display | The guest display without cua-spacesd: the VM's VNC endpoint and a host command that opens it (lume attach). |
guest_screenshot | Captures the guest framebuffer as PNG without cua-spacesd. |
guest_sh | Runs line with /bin/sh -c in the guest without cua-spacesd, to completion (default timeout 120 s). |
keep_alive | Extends the sandbox's lease by seconds, for a provider that has one. |
mcp | An MCP client (the official Rust SDK) for the MCP server behind service at path (default /mcp). |
mcp_config | Where the MCP server behind service is (URL of its endpoint at path, default /mcp, plus the headers every request needs), for any MCP client. |
open_media_bridge | Opens a media session and returns a loopback WebSocket bridge for a webview (daemon mode). |
public_url | A shareable URL for service that stops working after ttl_seconds (60 s to 24 h, default 1 h): a loopback URL with its own token, served by the cua daemon (started if needed; CUA_BIN names the CLI). |
refresh | Fresh info (status from the provider). |
resize | Gives a local VM another shape: cpus vCPUs, memory_mb MiB of memory and a disk grown to disk_gb GiB (each None keeps it). |
restart | Restarts. |
resume | Resumes. |
revoke_public_url | Revokes a URL from public_url. |
service | A named service (for example "server" or "env"). |
set_lifetime | Gives this local sandbox a lifetime of seconds from now, replacing any earlier one: the cua daemon then deletes it (on_expire "delete", the default) or suspends it ("suspend"), whether or not this process is still running. |
suspend | Suspends. |
wait_ready | Waits until every probe passes. |
| Accessor | Returns | Description |
|---|---|---|
id() | String | Qualified ref (local:<name>, cloud:<name>, direct:<host:port>), the same kind of value local and in the cloud; it round-trips through Sandboxes.connect. |
image_info() | Option<ImageInfo> | The image this sandbox runs, as resolved and pinned at create time: the digest and variant that actually ran. None for direct (URL) connections, images not resolved from a registry, and the daemon topology. |
info() | SandboxInfo | Info as of creation / connection. |
is_ephemeral() | bool | Whether the sandbox is torn down on delete and has no state file. |
kind() | String | What kind of machine: container, vm or microvm (empty when not known). |
location() | String | Where it runs: local, cloud, direct or relay. |
name() | String | Name. |
runtime() | String | The engine that runs it (gvisor, runc, qemu, lume, kubevirt; empty when not known). |
runtime_type() | String | runtime_type. |
Sandbox.overlay#
Injects binaries (see Overlay): each replaces its guest file
atomically, is recorded under /var/lib/cua/overlays with its
sha256, and what runs it is restarted. Local containers go through
the container engine; other sandboxes need cua-spacesd and root (or
passwordless sudo) in the guest. timeout_ms
bounds a cua-spacesd restart (default 180 s).
async def overlay(self, overlays: List[Overlay], timeout_ms: Optional[int] = None) -> List[OverlayResult]| Parameter | Type | Default |
|---|---|---|
overlays | Vec<Overlay> | required |
timeout_ms | Option<u32> | None |
Returns Vec<OverlayResult> · Async · Raises CuaError
Sandbox.spacesd#
Attaches to cua-spacesd inside the sandbox (the env service or
guest port 3211). Fails with SpacesdNotAvailable when none
answers; sandbox lifecycle never depends on it.
async def spacesd(self, probe_timeout_ms: Optional[int]) -> SpacesdClient| Parameter | Type | Default |
|---|---|---|
probe_timeout_ms | Option<u32> | required |
Returns SpacesdClient · Async · Raises CuaError (SpacesdNotAvailable)
Sandbox.viewer_url#
A browser link to this sandbox's desktop in the cua-spacesd HTML5
viewer (/viewer on the env service): video, audio, input,
clipboard, file drop and folder sharing, in any modern browser. The
link carries a scoped viewer ticket, never the sandbox token. Needs
cua-spacesd in the sandbox.
async def viewer_url(self, options: Optional[ViewerOptions] = None) -> ViewerLink| Parameter | Type | Default |
|---|---|---|
options | Option<ViewerOptions> | None |
Returns ViewerLink · Async · Raises CuaError
SandboxInfo record#
A sandbox as listed.
Returned by Sandbox.info, Sandbox.refresh, Sandboxes.get, Sandboxes.list, Sandboxes.list_all.
| Field | Type | Default | Description |
|---|---|---|---|
name | String | Name. | |
kind | String | What kind of machine: container, vm or microvm (empty when not known: an existing machine). | |
runtime | String | The engine that runs it: gvisor, runc, qemu, lume or a provider's own (empty when not known). | |
runtime_type / runtimeType | String | runtime_type as persisted (direct, gvisor, qemu, ...); prefer location, kind and runtime. | |
status | SandboxStatus | Status. | |
status_detail / statusDetail | Option<String> | Provider's word for an unknown status. | |
ephemeral | bool | No state file; torn down on delete. | |
services | HashMap<String, u16> | Declared services: name → guest port (0 = only the name is known). | |
endpoints | HashMap<String, String> | Service base URLs by name. | |
image | Option<String> | Image, when known. | |
id | String | Qualified ref: local:<name>, direct:<host:port> or <provider>:<name>. Every call that takes a sandbox name accepts it. | |
phase | SandboxPhase | Portable phase: provisioning, starting, ready or stopped. | |
location | String | Where it runs: local, direct (a machine by address), relay or a provider. | |
expires_at_unix / expiresAtUnix | Option<i64> | When it expires unless kept alive (unix seconds), when known. | |
provider_details / providerDetails | HashMap<String, String> | Provider internals (local: backend, container_id). Not part of the portable API. | |
image_info / imageInfo | Option<ImageInfo> | None | The image as resolved and pinned at create time (digest, variant). None for direct connections, images not resolved from a registry, and the daemon topology. |
stop_reason / stopReason | Option<String> | None | Why a local sandbox stopped without being asked to, in plain words ("out of memory", "killed", "exited with code 1"); None otherwise. |
SandboxListing record#
A sandbox listing and what it left out.
Returned by Sandboxes.list_with_warnings.
| Field | Type | Default | Description |
|---|---|---|---|
sandboxes | Vec<SandboxInfo> | Sandboxes, each with its location. | |
warnings | Vec<String> | Sources left out of the listing. |
SandboxPhase enum#
Portable lifecycle phase, the same words on every provider.
SandboxPhase.PROVISIONING
SandboxPhase.STARTING
SandboxPhase.READY
SandboxPhase.STOPPED| Variant | Description |
|---|---|
Provisioning | Being created. |
Starting | Booting; readiness probes have not passed yet. |
Ready | Running and ready. |
Stopped | Stopped or suspended. |
SandboxStatus enum#
Coarse lifecycle status.
SandboxStatus.RUNNING
SandboxStatus.SUSPENDED
SandboxStatus.STOPPED
SandboxStatus.PROVISIONING
SandboxStatus.UNKNOWN| Variant | Description |
|---|---|
Running | Running (or bound). |
Suspended | Suspended or scaled to zero. |
Stopped | Stopped. |
Provisioning | Starting. |
Unknown | Unknown; see SandboxInfo.status_detail. |
Overlay record#
A binary to inject into a sandbox.
| Field | Type | Default | Description |
|---|---|---|---|
name | String | cua-driver, cua-spacesd, or any name (then target is required). Letters, digits, ., _, -. | |
path | String | The local file to inject. | |
target | Option<String> | None | Guest path to replace. Default: resolved for cua-driver and cua-spacesd. |
source | Option<String> | None | Provenance recorded with it (for example the git sha it was built from). Default: the local path. |
OverlayResult record#
What an overlay did.
Returned by Sandbox.overlay.
| Field | Type | Default | Description |
|---|---|---|---|
name | String | Overlay name. | |
target | String | Guest path that was replaced. | |
sha256 | String | sha256 (hex) of the injected file (pass it to cua doctor --expect NAME=sha256:<hex>). | |
previous_sha256 / previousSha256 | String | sha256 of the file it replaced, empty when there was none. | |
size | u64 | Bytes. | |
restarted | String | How the running program was restarted (supervisor:cua-spacesd, systemd:cua-spacesd.service, stopped:<pids>), empty when nothing ran it. |
ViewerLink record#
A link to the sandbox desktop in the cua-spacesd HTML5 viewer.
Returned by Sandbox.viewer_url.
| Field | Type | Default | Description |
|---|---|---|---|
url | String | Open this in any modern browser. The credential is in the fragment (#ticket=), which browsers never send to a server. | |
expires_at_unix / expiresAtUnix | i64 | When the link stops working for new connections (unix seconds). |
ViewerOptions record#
Options for Sandbox.viewer_url.
| Field | Type | Default | Description |
|---|---|---|---|
ttl_seconds / ttlSeconds | Option<u32> | None | Lifetime of the link in seconds (60 to 86400). Default 3600. |
view_only / viewOnly | bool | false | Watch only: no input, clipboard, files or microphone. |
clipboard | bool | true | Two-way clipboard sync. |
files_root / filesRoot | Option<String> | None | Guest directory for uploads and folder sharing (~ is the desktop user's home). None means ~; an empty string turns files off. |
microphone | bool | true | Allow the microphone (also subject to the sandbox's uplink policy). |
contrib_providers_built#
The contrib providers this build includes (empty unless built with the
contrib feature).
def contrib_providers_built() -> List[str]Returns Vec<String>
sandbox_locations#
Every location word on= accepts, in display order: local, cloud,
then the contrib providers (e2b, daytona, modal, ...) and your own
clouds (aws, gcp, hetzner). A word is listed whether or not this build
includes that provider (see contrib_providers_built).
def sandbox_locations() -> List[str]Returns Vec<String>