Skip to main content
Run shell commands inside sandboxes with full stdout/stderr capture, real-time streaming, and configurable timeouts — then keep long-running services alive with background processes, signals, stdin, and supervised restarts. Commands and processes share one API. Use run / exec when you want to run something and wait for the result; use start_process when you want to start something that keeps running and manage its lifecycle.
Sandbox-specific operations use sandbox-specific ingress, commonly seen as https://<sandbox-id-or-name>.sandbox.tensorlake.ai, derived from the sandbox’s ingress_endpoint.For 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.

Basic Execution

# Run in an existing sandbox — use the sandbox ID or name
tl sbx exec my-env python -c 'print("Hello from sandbox!")'

# Or create, run, and tear down in one step
tl sbx run python -c 'print("Hello from sandbox!")'

CLI Options

# Timeout is in seconds
tl sbx exec <sandbox-id> --timeout 10 python -c 'print("hi")'

# Run from a specific working directory
tl sbx exec <sandbox-id> --workdir /workspace python main.py

# Inject environment variables into a single command
tl 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 afterwards
tl 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.

Shell Commands

# Count Python files in /workspace with a pipe
tl sbx exec <sandbox-id> bash -c "ls -la /workspace | grep '.py' | wc -l"

# Redirect stdout and stderr to files
tl sbx exec <sandbox-id> bash -c "python script.py > output.txt 2> errors.txt"

# Chain setup and execution in one shell command
tl sbx exec <sandbox-id> bash -c "cd /workspace && pip install -r requirements.txt && python main.py"

Get Process Output

Fetch the buffered stdout, stderr, or combined output of a running or finished process.
sandbox = Sandbox.create()
result = sandbox.run("python", ["-c", "print('hello')"])
print(result.stdout)
print(result.stderr)

Error Handling

# The CLI prints stderr and returns a non-zero exit code on failure
tl sbx exec <sandbox-id> python -c "import nonexistent_module"

Start a Background Process

Use start_process for work that should keep running after the call returns — servers, watchers, and other long-lived jobs.
from tensorlake.sandbox import Sandbox

sandbox = Sandbox.create()
# Start a background process
proc = sandbox.start_process("python", ["-m", "http.server", "8080"])
print(f"PID: {proc.pid}")

List Processes

procs = sandbox.list_processes()
for p in procs:
    print(f"PID {p.pid}: {p.status}")

Stream Output

Stream stdout/stderr in real time for long-running commands using Server-Sent Events:
tl sbx exec streams combined output to your terminal while the process runs.

Send Signals

Send POSIX signals to running processes:
import signal

proc = sandbox.start_process("python", ["-m", "http.server", "8080"])

# Gracefully stop the process
sandbox.send_signal(proc.pid, signal.SIGTERM)

Kill a Process

import signal

sandbox.send_signal(proc.pid, signal.SIGKILL)

Write to Stdin

Send input to a running process started with stdin in pipe mode:
import { StdinMode } from "tensorlake";

const proc = await sandbox.startProcess("python", {
  args: ["-i"],
  stdinMode: StdinMode.PIPE,
});

await sandbox.writeStdin(
  proc.pid,
  new TextEncoder().encode("print('hello')\n"),
);

await sandbox.closeStdin(proc.pid);
# Start a process with stdin pipe
curl -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": ["-i"], "stdin_mode": "pipe"}'

# Write to stdin
curl -X POST https://<sandbox-id>.sandbox.tensorlake.ai/api/v1/processes/<pid>/stdin \
  -H "Authorization: Bearer $TL_API_KEY" \
  -H "Content-Type: application/octet-stream" \
  --data-binary "print('hello')\n"

# Close stdin
curl -X POST https://<sandbox-id>.sandbox.tensorlake.ai/api/v1/processes/<pid>/stdin/close \
  -H "Authorization: Bearer $TL_API_KEY"

Managed Processes

Use a managed process for long-running services that should restart after a crash or failed health check. Managed processes use the same process API as normal background commands, but opt into supervision when you provide a name, a restart policy, or a health check.
Managed process flags start a background process. In the CLI, these flags require --detach. For blocking one-shot commands that stream output and return an exit code, use plain tl sbx exec or sandbox.run(...).
# Start and supervise a web server. The CLI prints the PID.
tl sbx exec <sandbox-id> --detach \
  --name dev-server \
  --restart always \
  --health-http 8080 \
  python -m http.server 8080

# Inspect the managed process
tl sbx ps <sandbox-id> <pid> --json

# Manually restart it through the supervisor
tl sbx restart <sandbox-id> <pid>

# Stop the process and remove it from supervision
tl sbx kill <sandbox-id> <pid>
Restart policies are never, on_failure, and always. Health checks can be HTTP checks against a local sandbox port and optional path, or TCP checks against a local port. Process user selection accepts a username such as root, a UID string, a uid:gid string, or an object such as {"uid": 1000, "gid": 1000}. The default user is tl-user.

Interactive Shell

# Open an interactive shell in the sandbox
tl sbx ssh <sandbox-id>

# Use a custom shell
tl sbx ssh <sandbox-id> --shell /bin/sh
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.

Learn More

PTY Sessions

Interactive shells over WebSocket.

File Operations

Read, write, and copy files.

Lifecycle

Sandbox states, resources, and timeouts.

Networking

Control internet access and outbound destinations.