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.Name-based proxy requests require an Authorization header. Unauthenticated access (sandboxes with allow_unauthenticated_access) must use the sandbox ID.
# 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
# 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,)
# Start a process with custom environment variables and working directorycurl -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": ["main.py"], "env": {"MODE": "prod", "DEBUG": "0"}, "working_dir": "/workspace" }'
# 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}")
# Check the exited process statuscurl https://<sandbox-id>.sandbox.tensorlake.ai/api/v1/processes/<pid> \ -H "Authorization: Bearer $TL_API_KEY"
Stream stdout/stderr in real time for long-running commands using Server-Sent Events:
CLI
Python
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="")