> ## Documentation Index
> Fetch the complete documentation index at: https://docs.nanovm.dev.lithosai.cloud/llms.txt
> Use this file to discover all available pages before exploring further.

# Python SDK

> Client configuration, sandbox methods, return values, and error handling.

Use the Python SDK from an environment configured by the [installer](/installation).
The examples below use `box` for the client and `sandbox` for a sandbox returned by
`box.sandboxes.create()` or `box.sandboxes.get()`.

## Configure the client

```python theme={null}
from lithosbox import LithosBox

box = LithosBox()
```

Run scripts with `lithosbox python` to use the key you saved during installation.
For other Python environments, provide `LITHOSBOX_TOKEN` through the environment
or pass `token=` to the client. Keep credentials outside your source code.

| Argument                                 | Purpose                                                                                                                                                                          |
| ---------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `token`                                  | API key or bearer token; defaults to `LITHOSBOX_TOKEN`.                                                                                                                          |
| `api_url`                                | API address; can also be set with `LITHOSBOX_API_URL`.                                                                                                                           |
| `timeout`                                | Request timeout in seconds; defaults to 120. Create requests allow at least 300 seconds.                                                                                         |
| `auth_url`, `client_id`, `client_secret` | OAuth client credentials, for accounts configured to use them. Corresponding `LITHOSBOX_AUTH_URL`, `LITHOSBOX_CLIENT_ID`, and `LITHOSBOX_CLIENT_SECRET` variables are supported. |

Keep a client open while you use its sandbox handles. Call `box.close()` when
finished, or use `with LithosBox() as box:`. Closing the client does not delete its
sandboxes.

For asynchronous code, use `AsyncLithosBox`, `async with`, and `await`:

```python theme={null}
import asyncio
from lithosbox import AsyncLithosBox

async def main():
    async with AsyncLithosBox() as box:
        async with await box.sandboxes.create() as sandbox:
            result = await sandbox.run(["python3", "-c", "print(42)"])
            print(result.check().stdout)

asyncio.run(main())
```

## Create and find sandboxes

### create

`box.sandboxes.create()`

Returns a `Sandbox`. Choose at most one of `image`, `template`, or `snapshot_id`.
Omit all three to use the default environment.

| Argument              | Default                         | Purpose                                                                    |
| --------------------- | ------------------------------- | -------------------------------------------------------------------------- |
| `image`               | None                            | OCI image reference.                                                       |
| `template`            | None                            | Template ID, name, or `name:version`.                                      |
| `snapshot_id`         | None                            | Snapshot to restore into a new sandbox.                                    |
| `cpus`                | 2 for an image create           | CPU count, from 1 to 4.                                                    |
| `memory_mb`           | 1024 for an image create        | Memory in MiB, from 128 to 8192.                                           |
| `runtime`             | `container` for an image create | `container` or `vm`; see [Custom images](/guides/images#choose-a-runtime). |
| `disable_internet`    | `False`                         | Disable outbound internet access.                                          |
| `wait_for_template`   | `True`                          | Wait for image preparation; otherwise raise `TemplateBuildingError`.       |
| `warm_timeout`        | 900                             | Maximum time in seconds to wait for image preparation.                     |
| `writable_size_bytes` | Fixed at 16 GiB                 | Other sizes are rejected.                                                  |

Template and snapshot creates use the source's CPU and memory configuration.
The SDK reuses the same sandbox ID during retries within a create call. If a call
fails without a response, inspect existing sandboxes before making a new create call.

| Method                     | Result                                        |
| -------------------------- | --------------------------------------------- |
| `box.sandboxes.get(id)`    | A `Sandbox` for an existing ID.               |
| `box.sandboxes.list()`     | List of the organization's sandboxes.         |
| `box.sandboxes.delete(id)` | Delete a sandbox. Repeating deletion is safe. |
| `sandbox.refresh()`        | Refresh `sandbox.info` and return the handle. |

A handle exposes `sandbox.id` and `sandbox.info`, including its state, image, CPU,
and memory configuration. `with box.sandboxes.create() as sandbox:` deletes the
sandbox when the block ends.

## Commands, sessions, and files

### run

`sandbox.run(command, *, background=False, stdin=None)`

Returns an `ExecResult` with `stdout`, `stderr`, and `exit_code`. Call `.check()` to
raise on a nonzero exit code. `stdout_truncated`, `stderr_truncated`, and `truncated`
indicate output limits were reached.

| Argument     | Default  | Purpose                                                                                                                                  |
| ------------ | -------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| `command`    | Required | Shell string with pipes, redirects, and variable expansion, or a list of literal string arguments. Use a list for user-provided values.  |
| `background` | `False`  | Wait for the command to finish. Set to `True` to start a server or worker and return after it starts; requires a shell string.           |
| `stdin`      | `None`   | Send bytes or text to the command's standard input, up to 4 MiB. Cannot be combined with `background=True`; write input to a file first. |

With `background=True`, the result reports startup status. No process ID is
returned. Redirect output to a file and check the job's eventual exit status
separately.

Foreground completion does not guarantee every child process has exited. Use
background mode explicitly for servers and workers. Synchronous commands allow
about 110 seconds; each output stream is limited to 16 MiB. See [Run commands](/guides/run-commands).

### session

`sandbox.session(session_id=None)`

Returns a `Session` that keeps its working directory, environment variables, and
shell state between commands.

| Argument     | Default | Purpose                                                                                                                                     |
| ------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| `session_id` | `None`  | Choose a shell ID. `None` generates a new ID; reusing an ID shares its shell within this sandbox. The returned handle exposes `session.id`. |

| Method         | Behavior                                                                                                                                             |
| -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| `run(command)` | `command` is a required shell string. Run it in this session and return an `ExecResult`. Does not accept an argument list, `background`, or `stdin`. |
| `close()`      | Close the shell. Further `run()` calls on this handle raise `ConflictError`.                                                                         |

Use `with sandbox.session() as session:` to close the shell when the block ends.
Handles using the same session ID share that shell; closing one ends it for all
handles. An individual session command has the same timeout as `sandbox.run()`.
A sandbox supports up to 256 concurrent sessions. See
[Keep shell state](/guides/run-commands#keep-shell-state) for an example.

### files

`sandbox.files`

| Method              | Behavior                                                                             |
| ------------------- | ------------------------------------------------------------------------------------ |
| `write(path, data)` | Write bytes or text, replacing any existing file. Create missing parent directories. |
| `read(path)`        | Read a text file.                                                                    |
| `read_bytes(path)`  | Read a binary file.                                                                  |
| `list(path=".")`    | List names in a directory.                                                           |
| `exists(path)`      | Return whether a path exists.                                                        |
| `mkdir(path)`       | Create a directory and missing parents.                                              |
| `rename(src, dst)`  | Move or rename a path.                                                               |
| `remove(path)`      | Delete a file or directory, recursively for directories.                             |

Writes allow up to 4 MiB per call. Reads allow approximately 16 MiB of text or
12 MiB of binary data. Use [larger-file transfers](/guides/files#transfer-larger-files)
for files beyond those limits. `write()` does not append.

## Public endpoints

`sandbox.expose(port, public_port=None)` returns `IngressInfo`. Its `id` identifies
the endpoint and its `url` is the public HTTPS address. Use the assigned public
port by leaving `public_port` unset.

Start an HTTP server on the specified sandbox port before using the URL. Remove
an endpoint with `box.ingress.delete(endpoint.id)`. List endpoints in the console
or with [`GET /vms/{id}/ingress`](/reference/http-api#public-endpoints).

See [Expose a web service](/guides/serve) for a complete example.

## Lifecycle and checkpoints

| Method                                      | Behavior                                                                                                                  |
| ------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| `sandbox.sleep()`                           | Park the sandbox and return whether it slept. Commands and file access wake it transparently; a busy sandbox stays awake. |
| `sandbox.wake()`                            | Wake a sleeping sandbox eagerly, ahead of a burst. Any command wakes it anyway.                                           |
| `sandbox.pause()` / `sandbox.resume()`      | Aliases for `sleep()` / `wake()`.                                                                                         |
| `sandbox.archive()` / `sandbox.unarchive()` | Save the sandbox for later, release its active slot, and resume it explicitly.                                            |
| `sandbox.reboot()`                          | Restart the environment, preserving files but ending processes and sessions. Return the refreshed handle.                 |
| `sandbox.delete()`                          | Delete the sandbox. Retained snapshots remain.                                                                            |

See [Manage sandbox lifecycle](/guides/lifecycle) for when to use each action.

### snapshot

`sandbox.snapshot(*, leave_paused=False, wait_durable=False, timeout=120)`

Returns `SnapshotInfo`, including `id`, `vm_id`, `state`, and `durable`. The
sandbox keeps running by default. `leave_paused=True` lets it rest after the
checkpoint; the next command or file operation wakes it automatically.

Use `wait_durable=True` to wait until saving completes, with `timeout` in seconds.
A timeout does not cancel saving. Restore with `box.snapshots.restore(snapshot)`;
it accepts either a snapshot object or its ID and returns a new `Sandbox`.

| Method                                        | Result                                                          |
| --------------------------------------------- | --------------------------------------------------------------- |
| `box.snapshots.list()`                        | List of organization snapshots.                                 |
| `box.snapshots.get(id)`                       | Current `SnapshotInfo`.                                         |
| `box.snapshots.wait_durable(id, timeout=120)` | Wait for a durable snapshot and return its updated information. |
| `box.snapshots.delete(id)`                    | Delete a snapshot. An in-progress export can prevent deletion.  |

### fork

`sandbox.fork(n=None)`

Without `n`, return one independent `Sandbox`. With `n`, return a list of that many
copies; `n=1` returns a one-element list. Up to four copies can be requested at once.

Copies include files and running processes. Fork between commands and reconnect
external services independently in each copy. See [Save, restore, fork](/guides/save-restore).

## Activity, logs, and metrics

| Method                                         | Result                                                                 |
| ---------------------------------------------- | ---------------------------------------------------------------------- |
| `sandbox.events(limit=200)`                    | List of events, newest first, with `kind`, `detail`, `node`, and `at`. |
| `sandbox.logs(tail_bytes=65536)`               | Text from system logs; at most 256 KiB per call.                       |
| `sandbox.metrics(since_unix=0, max_samples=0)` | Recent resource samples in `{"samples": [...], "cpus": n}`.            |
| `sandbox.metrics(hours=24)`                    | Historical points in `{"points": [...]}`.                              |
| `sandbox.metrics(start=..., end=...)`          | History for an RFC3339 time range, up to 15 days back.                 |
| `box.usage(start=None, end=None)`              | Organization resource usage, defaulting to the last 24 hours.          |
| `box.audit(limit=200, before=None)`            | Audit records and `next_before` for pagination.                        |

Recent metrics cover approximately two hours at 30-second intervals. Historical
metrics use minute intervals and remain available for archived and deleted
sandboxes. `measured=false` identifies a missing measurement. System logs and
recent metrics are unavailable while archived.

Recent CPU samples report milliseconds used over `interval_s`. Divide `cpu_ms` by
`interval_s * 1000 * cpus` for a fraction of allocated CPU capacity. Historical
points use `util_seconds` for the measured duration; do not assume every point
contains a full minute of measurements.

See [Monitor and troubleshoot](/guides/observability) for examples.

## Templates, registries, and exports

| Method                                                     | Purpose                                                                                                                  |
| ---------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| `box.templates.create(name=..., image=..., ...)`           | Create a named template. Optional `version`, `cpus`, `memory_mb`, `runtime`, and `disable_internet` configure it.        |
| `box.templates.build(image, ...)`                          | Prepare or reuse a template, waiting by default. Supports `name`, `cpus`, `memory_mb`, `runtime`, `wait`, and `timeout`. |
| `box.templates.list()` / `get(id)` / `delete(id)`          | Manage templates. Shared templates are read-only.                                                                        |
| `box.templates.wait(id, timeout=900)`                      | Wait until a template is ready, or raise if it fails.                                                                    |
| `box.registries.put(host=..., username=..., password=...)` | Store a private registry credential. Arguments are keyword-only.                                                         |
| `box.registries.list()` / `delete(host)`                   | List registry metadata or remove a credential.                                                                           |
| `box.snapshots.export(snapshot.id)`                        | Start an export of a durable snapshot. Return `ExportInfo`.                                                              |
| `box.exports.get(id)` / `wait(id, timeout=900)`            | Get export status or wait for downloadable files.                                                                        |
| `box.exports.delete(id)`                                   | Delete a completed export's files.                                                                                       |

Registry credentials can also use `secret=` or ECR role settings: `kind="ecr-assume-role"`,
`role_arn`, and `external_id`. Export file links are temporary; download before their
expiry. See [HTTP API](/reference/http-api#snapshots-and-exports) for export fields.

Existing aliases include `exec`, `exec_background`, `stop`/`start`, `branch`, and
`files.ls`. The guides use `run`, `archive`/`unarchive`, `fork`, and `files.list`.

## Errors

| Error                             | What to do                                                                                           |
| --------------------------------- | ---------------------------------------------------------------------------------------------------- |
| `InvalidRequestError`             | Check the arguments and resource limits.                                                             |
| `AuthError`                       | Check the key, organization, and permissions.                                                        |
| `NotFoundError`                   | Check that the resource ID exists in your organization.                                              |
| `SandboxPausedError`              | Call `resume()` before running commands.                                                             |
| `SandboxStoppedError`             | Call `unarchive()` before running commands.                                                          |
| `ConflictError`                   | Read the message and resolve the conflicting state before retrying.                                  |
| `TemplateBuildingError`           | Wait for the identified template. `create()` normally handles this automatically.                    |
| `TemplateBuildFailed`             | Inspect the template's `status_detail` and correct the image or configuration.                       |
| `QuotaError` with `kind="rate"`   | Wait for `retry_after` before retrying.                                                              |
| `QuotaError` with `kind="cap"`    | Archive or delete an unused sandbox to free a slot.                                                  |
| `CapacityError`                   | Capacity is temporarily unavailable. Retry with backoff and respect `retry_after` when supplied.     |
| `SandboxUnhealthyError`           | Try rebooting to keep files, or delete and recreate the sandbox.                                     |
| `WaitTimeout`                     | Check the operation's status; it may still be in progress.                                           |
| `ExportFailed`                    | Inspect the export's `error` field.                                                                  |
| `TransportError` or `ServerError` | The outcome may be unknown. Check resources before repeating an action that creates or changes them. |
| `ClientClosedError`               | Create a new client before making more calls.                                                        |

Error classes are available from `lithosbox.errors`. API errors expose `status`
and `body` where a response is available. `SandboxPausedError` and
`SandboxStoppedError` are subclasses of `ConflictError`.

`box.rate.acquire` and `box.rate.ops` expose rate-limit information from the
client's recent responses. They may be `None` before the first response. Treat the
values as advisory and follow `retry_after` on rate-limit errors. See
[Limits](/reference/limits#request-rates) and [HTTP status codes](/reference/http-api#status-codes).
