# Processes

> The SDK methods that start and manage the named, supervised processes of a sandbox, in TypeScript and Python.

Source: https://useshards.com/docs/reference/sdks/processes/

## sandbox.run

Start a supervised process in a running sandbox.

**TypeScript**

```ts
sandbox.run(command: string | string[], options?: RunOptions): Promise<Process>
```

**Python**

```python
sandbox.run(command, *, name=None, env=None, workdir=None, user=None, restart=None) -> Process
```

**Examples**

**TypeScript**

```ts
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" } });
```

**Python**

```python
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`](https://useshards.com/docs/reference/sdks/sandboxes/#sandboxstop) or [`sandbox.remove`](https://useshards.com/docs/reference/sdks/sandboxes/#sandboxremove) to end the sandbox.

**Restarts**

- `policy` is `no`, `on-failure` (after a non-zero exit code or a signal), `always` (after any exit, and whenever the sandbox starts) or `unless-stopped`, the default.
- `unless-stopped` is like `always` until [`process.kill`](#processkill) ends the process. A daemon restart leaves it down in a sandbox that `stop` stopped.
- `retries` caps how many times in a row `on-failure` starts the process again. `0` or no value means no cap.
- `backoff` is 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

Wait until the process ends and its restart policy will not start it again.

**TypeScript**

```ts
process.wait(options?: { signal?: AbortSignal }): Promise<ProcessInfo>
```

**Python**

```python
process.wait(timeout=None) -> ProcessInfo
```

**Examples**

**TypeScript**

```ts
const info = await once.wait();
console.log(info.status.state, info.status.exit);
```

**Python**

```python
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

Stop the process and cancel its restarts.

**TypeScript**

```ts
process.kill(options?: { force?: boolean }): Promise<ProcessInfo>
```

**Python**

```python
process.kill(*, force=False) -> ProcessInfo
```

**Examples**

**TypeScript**

```ts
await api.kill();
await api.kill({ force: true });
```

**Python**

```python
api.kill()
api.kill(force=True)
```

**Options**

| TypeScript | Python | Description |
| --- | --- | --- |
| `force` | `force` | send `KILL` instead of `TERM` |

The sandbox keeps running.

## process.logs

Return the output of every run of the process.

**TypeScript**

```ts
process.logs(): Promise<string>
```

**Python**

```python
process.logs() -> str
```

**Examples**

**TypeScript**

```ts
console.log(await api.logs());
```

**Python**

```python
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

Stream the log from its start, then new output as it arrives.

**TypeScript**

```ts
process.followLogs(options?: { signal?: AbortSignal }): AsyncGenerator<Uint8Array>
```

**Python**

```python
process.follow_logs() -> Follow[bytes]
```

**Examples**

**TypeScript**

```ts
for await (const chunk of api.followLogs()) process.stdout.write(chunk);
```

**Python**

```python
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

Read the process's record from the daemon.

**TypeScript**

```ts
process.inspect(): Promise<ProcessInfo>
```

**Python**

```python
process.inspect() -> ProcessInfo
```

**Examples**

**TypeScript**

```ts
const { status } = await api.inspect();
console.log(status.state, status.restarts);
```

**Python**

```python
status = api.inspect().status
print(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

List the processes of a sandbox, in the order they were first run.

**TypeScript**

```ts
sandbox.processes.list(): Promise<ProcessInfo[]>
```

**Python**

```python
sandbox.processes.list() -> list[ProcessInfo]
```

**Examples**

**TypeScript**

```ts
for (const info of await sandbox.processes.list()) console.log(info.name, info.status.state);
```

**Python**

```python
for info in sandbox.processes.list():
    print(info.name, info.status.state)
```

The list includes the processes any client ran.

## sandbox.processes.get

Find a process by name and return a handle to it.

**TypeScript**

```ts
sandbox.processes.get(name: string): Promise<Process>
```

**Python**

```python
sandbox.processes.get(name) -> Process
```

**Examples**

**TypeScript**

```ts
const api = await sandbox.processes.get("api");
```

**Python**

```python
api = sandbox.processes.get("api")
```

For a server that keeps running, see [Run a long-running server](https://useshards.com/docs/essentials/long-running-server/).
