Skip to main content
from declaw import Sandbox, CommandResult, CommandHandle, ProcessInfo
sbx.commands is the Commands sub-module available on every Sandbox instance. It provides methods to run foreground commands, launch background processes, stream real-time output, and interact with running processes via stdin.

sbx.commands.run()

Run a command and block until it completes, returning its stdout, stderr, and exit code.
result = sbx.commands.run("echo hello")
print(result.stdout)   # "hello\n"
print(result.exit_code)  # 0
Pass background=True to launch the command in the background and receive a CommandHandle immediately.
handle: CommandHandle = sbx.commands.run("sleep 30", background=True)
print("PID:", handle.pid)
cmd
str
required
Shell command to execute inside the sandbox.
background
bool
default:"False"
When True, the API returns immediately and the method returns a CommandHandle. When False (default), the method blocks and returns a CommandResult.
envs
dict[str, str] | None
default:"None"
Additional environment variables for this command.
user
str
default:"'user'"
Unix user to run the command as inside the sandbox.
cwd
str | None
default:"None"
Working directory. Defaults to the user’s home directory.
on_stdout
Callable[[str], None] | None
default:"None"
Callback invoked for each line of stdout after the command completes. For real-time streaming, use run_stream() instead.
on_stderr
Callable[[str], None] | None
default:"None"
Callback invoked for each line of stderr after the command completes.
stdin
bool | None
default:"None"
Whether to attach a stdin pipe to the process.
timeout
float | None
default:"60"
Maximum time in seconds to wait for the command to complete.
request_timeout
float | None
default:"None"
Per-request HTTP timeout in seconds.
Returns CommandResult when background=False, CommandHandle when background=True.

sbx.commands.run_stream()

Run a command with real-time SSE streaming. Callbacks are invoked as each chunk of output arrives, before the command completes.
def on_line(line: str) -> None:
    print(line, end="", flush=True)

result = sbx.commands.run_stream(
    "python3 -u long_script.py",
    on_stdout=on_line,
    on_stderr=on_line,
)
print("Exit code:", result.exit_code)
cmd
str
required
Shell command to execute.
on_stdout
Callable[[str], None] | None
default:"None"
Called in real-time for each stdout chunk as it arrives from the SSE stream.
on_stderr
Callable[[str], None] | None
default:"None"
Called in real-time for each stderr chunk as it arrives.
envs
dict[str, str] | None
default:"None"
Environment variables for the command.
user
str
default:"'user'"
Unix user to run as.
cwd
str | None
default:"None"
Working directory.
timeout
float | None
default:"60"
Command execution timeout in seconds.
Returns CommandResult with the accumulated stdout and stderr after the command finishes.

sbx.commands.list()

List all running (background) processes in the sandbox.
processes: list[ProcessInfo] = sbx.commands.list()
for p in processes:
    print(p.pid, p.cmd)
request_timeout
float | None
default:"None"
Per-request HTTP timeout in seconds.
Returns list[ProcessInfo]

sbx.commands.kill()

Send SIGKILL to a running process by PID.
killed = sbx.commands.kill(pid=1234)
pid
int
required
Process ID of the command to kill.
request_timeout
float | None
default:"None"
Per-request HTTP timeout in seconds.
Returns boolTrue if the process was killed, False if it was already dead.

sbx.commands.send_stdin()

Write data to the stdin of a running background process.
handle = sbx.commands.run("cat", background=True)
sbx.commands.send_stdin(handle.pid, "hello\n")
sbx.commands.send_stdin(handle.pid, "world\n")
pid
int
required
Process ID of the running command.
data
str
required
Data to write to stdin. Include \n for newlines.
request_timeout
float | None
default:"None"
Per-request HTTP timeout in seconds.
Returns None

sbx.commands.connect()

Create a CommandHandle for an already-running process by PID without making an API call. Useful when you have a PID from list() and want to wait on it.
handle = sbx.commands.connect(pid=5678)
result = handle.wait()
pid
int
required
Process ID of the running command.
Returns CommandHandle

CommandHandle

CommandHandle is returned by sbx.commands.run(background=True) and sbx.commands.connect(). It provides methods to wait for or kill the process.
handle = sbx.commands.run("python3 script.py", background=True)

# Later, wait for it to finish
result = handle.wait(
    on_stdout=lambda line: print("OUT:", line),
    on_stderr=lambda line: print("ERR:", line),
)

handle.wait()

Wait for the background command to complete.
on_stdout
Callable[[str], None] | None
default:"None"
Called for each stdout line after the command completes.
on_stderr
Callable[[str], None] | None
default:"None"
Called for each stderr line after the command completes.
Returns CommandResult. Raises CommandExitException if the exit code is non-zero.

handle.kill()

Kill the process. Returns bool

handle.pid

Type int — the process ID.

Data models

CommandResult

@dataclass
class CommandResult:
    stdout: str = ""
    stderr: str = ""
    exit_code: int = 0

ProcessInfo

@dataclass
class ProcessInfo:
    pid: int
    cmd: str
    is_pty: bool = False
    envs: dict[str, str] = field(default_factory=dict)

Stdout / Stderr

Line-level output models used when streaming output with timestamps:
@dataclass
class Stdout:
    line: str
    timestamp: float | None = None

@dataclass
class Stderr:
    line: str
    timestamp: float | None = None

Examples

Run a Python script

result = sbx.commands.run(
    "python3 -c \"import sys; print(sys.version)\"",
    timeout=10,
)
print(result.stdout)

Run with environment variables

result = sbx.commands.run(
    "echo $MY_SECRET",
    envs={"MY_SECRET": "s3cr3t"},
)

Stream long-running output

lines = []

result = sbx.commands.run_stream(
    "for i in $(seq 1 100); do echo $i; sleep 0.05; done",
    on_stdout=lines.append,
)
print(f"Received {len(lines)} lines")

Background process with stdin

import time

handle = sbx.commands.run("python3 -c \"import sys; [print(l.strip()+'!') for l in sys.stdin]\"", background=True)
time.sleep(0.1)
sbx.commands.send_stdin(handle.pid, "hello\nworld\n")
result = handle.wait()
print(result.stdout)  # "hello!\nworld!\n"