CWSANDBOX_API_KEY. For Forge API key authentication, see Get started. For CKS requirements, see Placement modes.
This guide helps you choose between synchronous and asynchronous patterns in the CoreWeave sandbox Python SDK (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 What do common sandbox SDK error messages mean?
for the full exception hierarchy and recovery patterns.