Run commands with output capture, streaming, and error handling
Run shell commands inside sandboxes with full stdout/stderr capture, real-time streaming, and configurable timeouts.
Sandbox-specific operations use the sandbox proxy URL: https://<sandbox-id-or-name>.sandbox.tensorlake.aiFor named sandboxes, you can use the sandbox name in place of the ID — both in the proxy hostname and in CLI/API commands. For example, https://my-env.sandbox.tensorlake.ai/api/v1/processes and tl sbx exec my-env python main.py work the same as their ID-based equivalents. The proxy resolves the name to the underlying sandbox automatically.The command and process APIs documented here run on the management URL on port 9501, which always requires authentication. Unauthenticated proxy access applies only to exposed user ports.
# Run in an existing sandbox — use the sandbox ID or nametl sbx exec my-env python -c 'print("Hello from sandbox!")'# Or create, run, and tear down in one steptl sbx run python -c 'print("Hello from sandbox!")'
from tensorlake.sandbox import SandboxClientclient = SandboxClient()with client.create_and_connect() as sandbox: result = sandbox.run("python", ["-c", "print('Hello from sandbox!')"]) print(result.stdout) # Hello from sandbox! print(result.exit_code) # 0
const result = await sandbox.run("python", { args: ["-c", "print('Hello from sandbox!')"],});console.log(result.stdout); // Hello from sandbox!console.log(result.exitCode); // 0
# Start a Python process inside the sandboxcurl -X POST https://<sandbox-id>.sandbox.tensorlake.ai/api/v1/processes \ -H "Authorization: Bearer $TL_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "command": "python", "args": ["-c", "print(\"Hello from sandbox!\")"] }'
# Timeout is in secondstl sbx exec <sandbox-id> --timeout 10 python -c 'print("hi")'# Run from a specific working directorytl sbx exec <sandbox-id> --workdir /workspace python main.py# Inject environment variables into a single commandtl sbx exec <sandbox-id> --env MODE=prod --env DEBUG=0 /bin/sh -lc 'printf "%s %s\n" "$MODE" "$DEBUG"'# Keep the sandbox after a one-shot run so you can inspect it afterwardstl sbx run --keep /bin/sh -lc 'echo KEEP_TEST && sleep 1'
A verified --env run printed prod 0. A verified --keep run ended with Sandbox <id> kept alive., and tl sbx ls --all then showed that sandbox as running.
# Run with a timeout, working directory, and per-command environmentresult = sandbox.run( "python", ["main.py"], env={"MODE": "prod", "DEBUG": "0"}, working_dir="/workspace", timeout=10,)
# 2. Connect via WebSocketwscat -c "wss://<sandbox-id>.sandbox.tensorlake.ai/api/v1/pty/<session-id>/ws?token=<token>"
tl sbx ssh requires an interactive terminal and automatically resumes a suspended sandbox before opening the PTY session.For the full programmatic PTY flow, including the READY handshake, binary WebSocket opcodes, and clean shutdown, see PTY Sessions.
# The CLI prints stderr and returns a non-zero exit code on failuretl sbx exec <sandbox-id> python -c "import nonexistent_module"
with client.create_and_connect() as sandbox: result = sandbox.run("python", ["-c", "import nonexistent_module"]) if result.exit_code != 0: print(f"Command failed with exit code {result.exit_code}") print(f"stderr: {result.stderr}")
Stream stdout/stderr in real time for long-running commands using Server-Sent Events:
CLI
Python
TypeScript
HTTP
tl sbx exec streams combined output to your terminal while the process runs.
with client.create_and_connect() as sandbox: # Start a long-running process proc = sandbox.start_process("python", ["-c", """import timefor i in range(5): print(f"Step {i+1}/5") time.sleep(1)"""]) # Stream output as it arrives for event in sandbox.follow_output(proc.pid): print(event.line, end="")
const proc = await sandbox.startProcess("python", { args: [ "-c", "import time\nfor i in range(5):\n print(f'Step {i+1}/5')\n time.sleep(1)", ],});for await (const event of sandbox.followOutput(proc.pid)) { process.stdout.write(event.line);}