Processes
sandbox.run
Section titled “sandbox.run”Start a supervised process in a running sandbox.
sandbox.run(command: string | string[], options?: RunOptions): Promise<Process>sandbox.run(command, *, name=None, env=None, workdir=None, user=None, restart=None) -> ProcessExamples
const api = await sandbox.run("python -m http.server", { name: "api" });const db = await sandbox.run(["pg_ctlcluster", "16", "main", "start", "--foreground"], { name: "db", restart: { policy: "on-failure", retries: 5 },});const once = await sandbox.run("python script.py", { restart: { policy: "no" } });from useshards import Restart
api = sandbox.run("python -m http.server", name="api")db = sandbox.run( ["pg_ctlcluster", "16", "main", "start", "--foreground"], name="db", restart=Restart("on-failure", retries=5),)once = sandbox.run("python script.py", restart=Restart("no"))Arguments
| Argument | Description |
|---|---|
command |
a string runs under /bin/sh -c; an array or list runs as it is, with no shell |
Options
| TypeScript | Python | Description |
|---|---|---|
name |
name |
process name; the base name of the program by default |
env |
env |
variables added to the sandbox’s environment for this process |
workdir |
workdir |
working directory |
user |
user |
user name or uid in the sandbox |
restart |
restart |
when the process starts again: { policy, retries, backoff }, or Restart(policy, retries=0, backoff=0) |
The call returns as soon as the process runs. When a process exits, its sandbox stays running, so you can still run commands in it. Use sandbox.stop or sandbox.remove to end the sandbox.
Restarts
policyisno,on-failure(after a non-zero exit code or a signal),always(after any exit, and whenever the sandbox starts) orunless-stopped, the default.unless-stoppedis likealwaysuntilprocess.killends the process. A daemon restart leaves it down in a sandbox thatstopstopped.retriescaps how many times in a rowon-failurestarts the process again.0or no value means no cap.backoffis the first wait in seconds, 1 by default or when 0. Each later wait doubles, up to 60 seconds.
Names
Use up to 32 lowercase letters, digits, ., _ and -. A sandbox runs up to 16 processes. A run of a running name raises ConflictError with the code name_taken, and a run of an ended name replaces it.
process.wait
Section titled “process.wait”Wait until the process ends and its restart policy will not start it again.
process.wait(options?: { signal?: AbortSignal }): Promise<ProcessInfo>process.wait(timeout=None) -> ProcessInfoExamples
const info = await once.wait();console.log(info.status.state, info.status.exit);info = once.wait(timeout=60)print(info.status.state, info.status.exit)Options
| TypeScript | Python | Description |
|---|---|---|
signal |
an AbortSignal that ends the wait with the signal’s reason |
|
timeout |
seconds to wait before raising the built-in TimeoutError |
Ending the wait never ends the process.
process.kill
Section titled “process.kill”Stop the process and cancel its restarts.
process.kill(options?: { force?: boolean }): Promise<ProcessInfo>process.kill(*, force=False) -> ProcessInfoExamples
await api.kill();await api.kill({ force: true });api.kill()api.kill(force=True)Options
| TypeScript | Python | Description |
|---|---|---|
force |
force |
send KILL instead of TERM |
The sandbox keeps running.
process.logs
Section titled “process.logs”Return the output of every run of the process.
process.logs(): Promise<string>process.logs() -> strExamples
console.log(await api.logs());print(api.logs(), end="")The daemon keeps a bounded log, so for a long run it may hold only the end.
process.followLogs / follow_logs
Section titled “process.followLogs / follow_logs”Stream the log from its start, then new output as it arrives.
process.followLogs(options?: { signal?: AbortSignal }): AsyncGenerator<Uint8Array>process.follow_logs() -> Follow[bytes]Examples
for await (const chunk of api.followLogs()) process.stdout.write(chunk);with api.follow_logs() as follow: for chunk in follow: sys.stdout.buffer.write(chunk)The stream ends when the process ends or the sandbox stops. In TypeScript, an abort ends it with the signal’s reason. In Python, closing it ends it, and AsyncShard iterates it with async for.
process.inspect
Section titled “process.inspect”Read the process’s record from the daemon.
process.inspect(): Promise<ProcessInfo>process.inspect() -> ProcessInfoExamples
const { status } = await api.inspect();console.log(status.state, status.restarts);status = api.inspect().statusprint(status.state, status.restarts)A ProcessInfo holds name, command, env, workdir, user, restart, killed, and a status with state, restarts, exit and the start time. state is running, restarting, exited, killed, gave-up or stopped. process.info holds the record that the last call on that handle returned.
sandbox.processes.list
Section titled “sandbox.processes.list”List the processes of a sandbox, in the order they were first run.
sandbox.processes.list(): Promise<ProcessInfo[]>sandbox.processes.list() -> list[ProcessInfo]Examples
for (const info of await sandbox.processes.list()) console.log(info.name, info.status.state);for info in sandbox.processes.list(): print(info.name, info.status.state)The list includes the processes any client ran.
sandbox.processes.get
Section titled “sandbox.processes.get”Find a process by name and return a handle to it.
sandbox.processes.get(name: string): Promise<Process>sandbox.processes.get(name) -> ProcessExamples
const api = await sandbox.processes.get("api");api = sandbox.processes.get("api")For a server that keeps running, see Run a long-running server.