Manage sandbox lifecycle
Create, keep, reconnect to, list, suspend and delete sandboxes, keep cloud sandboxes alive, and run many at once.
Create, keep, reconnect to, list, suspend and delete sandboxes, keep cloud sandboxes alive, and run many at once.
Every lifecycle call takes the same local= switch as Sandbox.create. The
examples use local=True; pass local=False for the cloud.
from cua_sandbox import Image, Sandbox
# Deleted when the block exits.
async with Sandbox.ephemeral(Image.linux(), local=True) as sb:
...
# Kept until you delete it.
sb = await Sandbox.create(Image.linux(), name="dev", local=True)
await sb.disconnect() # the sandbox keeps runningDisconnecting never stops a sandbox. A connection and a sandbox have separate lifetimes.
print(sb.id) # its ref, like local:dev: what connect() and delete() take
info = await sb.info()
info.status # provisioning, starting, ready or stopped
info.location # local or cloud
info.services # {"web": 8000, ...}
info.expires_at # cloud: when the sandbox lapses without a keep-alive
info.provider_details # backend internals (local runtime; cloud pool and claim)| Status | Meaning |
|---|---|
provisioning | Capacity is being found or created (image pull, cloud capacity) |
starting | Booting, or wait_for probes have not passed yet |
ready | Running and every probe passed |
stopped | Exited, suspended or released |
Refs are local:<name>, cloud:<name> or direct:<host:port>. A bare name
works when it is unique; otherwise the call raises AmbiguousSandbox.
sb = await Sandbox.connect("dev", local=True)
for s in await Sandbox.list(): # local and cloud; local=True filters
print(s.name, s.status, s.location)
await Sandbox.suspend("dev", local=True)
sb = await Sandbox.resume("dev", local=True)
await Sandbox.delete("dev", local=True)await sb.destroy() deletes the sandbox you hold. Suspend, resume and restart
are local only: in the cloud suspend and restart raise Unsupported, and
resume of a running sandbox reconnects. The CLI and the SDK share local state
in ~/.cua/sandboxes, so either can reconnect to the other's sandboxes.
cua sb create linux --name dev # --on cloud for the cloud
cua sb ls # local and cloud; --local or --cloud filters
cua sb info dev
cua sb suspend dev && cua sb resume dev
cua sb keep-alive dev --for 2h # cloud
cua sb rm dev -fA cloud sandbox has a TTL (15 minutes by default) that the SDK renews while your process holds it. When the process exits, it lapses after the TTL. Set a longer TTL or extend it:
from datetime import timedelta
from cua_sandbox import CloudOptions
sb = await Sandbox.create(image, cloud=CloudOptions(claim_ttl=timedelta(hours=2)))
await sb.keep_alive(minutes=60)cloud= implies the cloud; passing it with local=True is an error.sb.to_dict() and Sandbox.from_dict(...) carry a cloud sandbox to another
process.cua daemon running, CLI-created cloud sandboxes keep being renewed
after the command exits.Local sandboxes run until you delete them. For pool and claim TTLs, see Capacity and claims.
Sandbox.ephemeral is async, so asyncio.gather runs sandboxes in parallel.
Cap concurrency with an asyncio.Semaphore (every local sandbox uses host CPU,
memory and disk) and pass return_exceptions=True so one failure does not
cancel the rest. In the cloud, one image runs at most 10 at once unless you
raise CloudOptions(max_pool_size=...).