cwsandbox) and shows the sync and async form of each common operation.
The SDK has a single async implementation internally. The sync/async flexibility comes from how you consume results: use .result() for sync and await for async.
Quick decision guide
Rule of thumb: Use sync patterns (
.result()) for simplicity. Switch to await only when you’re already
in an async codebase.
Core concept: OperationRef
Most SDK methods returnOperationRef[T], a wrapper that is both .result()-able and awaitable.
Both paths raise the same exceptions.
Sandbox.exec() returns Process, which extends OperationRef[ProcessResult] with streaming
and stdin.
Auto-start behavior
session.sandbox() returns an unstarted sandbox. The sandbox auto-starts on the first operation
that requires it:
Triggers auto-start: exec(), read_file(), write_file(), wait(), wait_until_complete()
Does not auto-start: get_status() (raises SandboxNotRunningError), stop() (no-op if never started)
Operations
Create sandboxes
- Sync
- Async
Sandbox.run() calls start().result() internally, which blocks the event loop.
In async code, construct with Sandbox(...) and use async with or await sandbox
to reach RUNNING status without blocking.start()
- Sync
- Async
exec()
- Sync
- Async
read_file()
- Sync
- Async
write_file()
- Sync
- Async
stop()
- Sync
- Async
wait()
wait() blocks until the sandbox reaches RUNNING status. It’s sync-only because blocking is
the intent. In async code, await sandbox achieves the same thing.
wait_until_complete()
- Sync
- Async
get_status()
get_status() is sync-only. It fetches the current status from the API.
Sandbox.list()
- Sync
- Async
Sandbox.from_id()
- Sync
- Async
Sandbox.delete()
- Sync
- Async
session.list()
- Sync
- Async
session.from_id()
- Sync
- Async
Stream stdout
- Sync
- Async
Stream stdin
Enable stdin withstdin=True. Use write() for raw bytes, writeline() for text lines,
and close() to signal EOF.
- Sync
- Async
cwsandbox.results()
cwsandbox.results() is a sync-only batch helper. It calls .result() on one or more OperationRef objects.
cwsandbox.wait()
cwsandbox.wait() is sync-only. It waits for a sequence of Sandbox, OperationRef, or Process
objects and returns (done, pending). Sandboxes resolve when they reach RUNNING status, not on
completion.
@session.function()
- Sync
- Async
Parallel execution
The sync API supports parallel execution because operations are non-blocking by design. Methods likeexec(), read_file(), and write_file() return immediately. You only block when you call
.result().
Sandbox.run() blocks until the backend accepts the start request (it calls start().result()
internally). For parallel startup, use session.sandbox() (auto-starts on first operation) or
collect start() refs:
Jupyter notebooks
The sync API works in Jupyter withoutnest_asyncio because the SDK runs its own background event
loop in a daemon thread:
await works directly since Jupyter has a built-in event loop:
Error handling
Both sync and async paths raise the same exceptions..result() re-raises any exception
from the underlying operation, and await does the same. See the Troubleshooting guide
for the full exception hierarchy and recovery patterns.