Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.declaw.ai/llms.txt

Use this file to discover all available pages before exploring further.

The Python SDK exposes stdio through sandbox.stdio. Use Stdio.start() to launch a process with an open stdin pipe, then send data, receive output, and close stdin or kill the process. For conceptual background see the Stdio feature overview.

sandbox.stdio.start(...)StdioProcess

Start a subprocess with an open stdin pipe. The sandbox runs the command and returns a StdioProcess handle.
proc = sandbox.stdio.start(
    "cat",
    envs={"FOO": "bar"},               # extra env vars (optional)
    user="user",                        # shell user (default "user")
    cwd="/workspace",                   # working directory (optional)
    on_stdout=lambda b: print(b),       # streaming stdout callback (optional)
    on_stderr=lambda b: print(b),       # streaming stderr callback (optional)
    request_timeout=None,               # httpx timeout for the POST
)

Parameters

NameTypeDefaultDescription
cmdstr(required)Shell command to execute.
envsdict[str, str] | NoneNoneEnvironment variables merged into the process env.
userstr"user"User the process runs as.
cwdstr | NoneNoneWorking directory.
on_stdoutCallable[[bytes], None] | NoneNoneIf provided, a background reader thread calls this for every stdout chunk.
on_stderrCallable[[bytes], None] | NoneNoneSame, for stderr.
request_timeoutfloat | NoneNonehttpx timeout for the start POST only.

Returns

A StdioProcess.

StdioProcess

Handle for an interactive subprocess with stdin pipe. Provides bidirectional I/O: send data via send_stdin, receive output via callbacks or iteration, and manage the process lifecycle.

Properties

  • proc.cmd_id: str — server-assigned command identifier.
  • proc.exit_code: int | NoneNone while the process is running; set once the exit SSE event arrives.

Methods

proc.send_stdin(data, request_timeout=None) -> None

Send data to the process’s stdin. Accepts bytes or str; str is UTF-8 encoded.
proc.send_stdin("hello\n")
proc.send_stdin(b"\x04")  # Ctrl-D

proc.close_stdin(request_timeout=None) -> None

Close the process’s stdin pipe, sending EOF. The process sees end-of-file on its stdin.
proc.close_stdin()

proc.kill(request_timeout=None) -> bool

Terminate the process. Returns True if the process existed at the time of the call.

proc.wait(timeout=None) -> StdioResult

Block until the process exits. If the process was started with callbacks, this joins the background reader thread. Otherwise it drains the SSE stream inline, discarding output.
result = proc.wait(timeout=30)
print(result.exit_code)

proc.stream(on_stdout=None, on_stderr=None) -> StdioResult

Block until the process exits, invoking callbacks for each output chunk. Use this when you didn’t provide callbacks at start time but want to consume output.
proc = sandbox.stdio.start("sh -c 'echo hi; echo err >&2'")
result = proc.stream(
    on_stdout=lambda d: print("out:", d),
    on_stderr=lambda d: print("err:", d),
)
Raises RuntimeError if a background reader is already running (i.e. callbacks were passed to start()). Use wait() in that case.

Iterator protocol

StdioProcess is iterable when no background reader is active. Each iteration yields a (stream_type, data) tuple where stream_type is "stdout" or "stderr" and data is bytes.
proc = sandbox.stdio.start("sh -c 'echo alpha; echo beta >&2; echo gamma'")
for stream_type, data in proc:
    print(f"[{stream_type}] {data.decode().strip()}")
# [stdout] alpha
# [stderr] beta
# [stdout] gamma
Use the iterator or callbacks, not both — they consume the same stream.

StdioResult

@dataclass
class StdioResult:
    exit_code: int
Int-coercible — int(result) and result == 0 both work.

Threading notes

  • The on_stdout / on_stderr callbacks run on a background daemon thread. Don’t do long blocking work inside them.
  • send_stdin, close_stdin, kill are safe to call from any thread.
  • wait() is synchronous. For async code, AsyncSandbox provides an equivalent stdio module with coroutine-based callbacks (same method names).