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

# Python SDK Reference

<a id="wrenn" />

# wrenn

<a id="wrenn.client" />

# wrenn.client

<a id="wrenn.client.CapsulesResource" />

## CapsulesResource Objects

```python theme={null}
class CapsulesResource()
```

Sync capsule control-plane operations.

<a id="wrenn.client.CapsulesResource.create" />

#### create

```python theme={null}
def create(template: str | None = None,
           vcpus: int | None = None,
           memory_mb: int | None = None,
           timeout_sec: int | None = None) -> CapsuleModel
```

Create a new capsule.

**Arguments**:

* `template` *str | None* - Template name to boot from.
* `vcpus` *int | None* - Number of virtual CPUs.
* `memory_mb` *int | None* - Memory in MiB.
* `timeout_sec` *int | None* - Inactivity TTL in seconds before
  auto-pause. `0` disables auto-pause.

**Returns**:

* `CapsuleModel` - The newly created capsule.

<a id="wrenn.client.CapsulesResource.list" />

#### list

```python theme={null}
def list() -> list[CapsuleModel]
```

List all capsules for the authenticated team.

**Returns**:

* `list[CapsuleModel]` - All capsules belonging to the team.

<a id="wrenn.client.CapsulesResource.get" />

#### get

```python theme={null}
def get(id: str) -> CapsuleModel
```

Get a capsule by ID.

**Arguments**:

* `id` *str* - Capsule ID.

**Returns**:

* `CapsuleModel` - Current state of the capsule.

**Raises**:

* `WrennNotFoundError` - If no capsule with the given ID exists.

<a id="wrenn.client.CapsulesResource.destroy" />

#### destroy

```python theme={null}
def destroy(id: str) -> None
```

Destroy a capsule permanently.

**Arguments**:

* `id` *str* - Capsule ID.

**Raises**:

* `WrennNotFoundError` - If no capsule with the given ID exists.

<a id="wrenn.client.CapsulesResource.pause" />

#### pause

```python theme={null}
def pause(id: str) -> CapsuleModel
```

Pause a running capsule.

**Arguments**:

* `id` *str* - Capsule ID.

**Returns**:

* `CapsuleModel` - Updated capsule state.

**Raises**:

* `WrennNotFoundError` - If no capsule with the given ID exists.

<a id="wrenn.client.CapsulesResource.resume" />

#### resume

```python theme={null}
def resume(id: str) -> CapsuleModel
```

Resume a paused capsule.

**Arguments**:

* `id` *str* - Capsule ID.

**Returns**:

* `CapsuleModel` - Updated capsule state.

**Raises**:

* `WrennNotFoundError` - If no capsule with the given ID exists.

<a id="wrenn.client.CapsulesResource.ping" />

#### ping

```python theme={null}
def ping(id: str) -> None
```

Reset the inactivity timer for a capsule.

**Arguments**:

* `id` *str* - Capsule ID.

**Raises**:

* `WrennNotFoundError` - If no capsule with the given ID exists.

<a id="wrenn.client.AsyncCapsulesResource" />

## AsyncCapsulesResource Objects

```python theme={null}
class AsyncCapsulesResource()
```

Async capsule control-plane operations.

<a id="wrenn.client.AsyncCapsulesResource.create" />

#### create

```python theme={null}
async def create(template: str | None = None,
                 vcpus: int | None = None,
                 memory_mb: int | None = None,
                 timeout_sec: int | None = None) -> CapsuleModel
```

Create a new capsule.

**Arguments**:

* `template` *str | None* - Template name to boot from.
* `vcpus` *int | None* - Number of virtual CPUs.
* `memory_mb` *int | None* - Memory in MiB.
* `timeout_sec` *int | None* - Inactivity TTL in seconds before
  auto-pause. `0` disables auto-pause.

**Returns**:

* `CapsuleModel` - The newly created capsule.

<a id="wrenn.client.AsyncCapsulesResource.list" />

#### list

```python theme={null}
async def list() -> list[CapsuleModel]
```

List all capsules for the authenticated team.

**Returns**:

* `list[CapsuleModel]` - All capsules belonging to the team.

<a id="wrenn.client.AsyncCapsulesResource.get" />

#### get

```python theme={null}
async def get(id: str) -> CapsuleModel
```

Get a capsule by ID.

**Arguments**:

* `id` *str* - Capsule ID.

**Returns**:

* `CapsuleModel` - Current state of the capsule.

**Raises**:

* `WrennNotFoundError` - If no capsule with the given ID exists.

<a id="wrenn.client.AsyncCapsulesResource.destroy" />

#### destroy

```python theme={null}
async def destroy(id: str) -> None
```

Destroy a capsule permanently.

**Arguments**:

* `id` *str* - Capsule ID.

**Raises**:

* `WrennNotFoundError` - If no capsule with the given ID exists.

<a id="wrenn.client.AsyncCapsulesResource.pause" />

#### pause

```python theme={null}
async def pause(id: str) -> CapsuleModel
```

Pause a running capsule.

**Arguments**:

* `id` *str* - Capsule ID.

**Returns**:

* `CapsuleModel` - Updated capsule state.

**Raises**:

* `WrennNotFoundError` - If no capsule with the given ID exists.

<a id="wrenn.client.AsyncCapsulesResource.resume" />

#### resume

```python theme={null}
async def resume(id: str) -> CapsuleModel
```

Resume a paused capsule.

**Arguments**:

* `id` *str* - Capsule ID.

**Returns**:

* `CapsuleModel` - Updated capsule state.

**Raises**:

* `WrennNotFoundError` - If no capsule with the given ID exists.

<a id="wrenn.client.AsyncCapsulesResource.ping" />

#### ping

```python theme={null}
async def ping(id: str) -> None
```

Reset the inactivity timer for a capsule.

**Arguments**:

* `id` *str* - Capsule ID.

**Raises**:

* `WrennNotFoundError` - If no capsule with the given ID exists.

<a id="wrenn.client.SnapshotsResource" />

## SnapshotsResource Objects

```python theme={null}
class SnapshotsResource()
```

Sync snapshot operations.

<a id="wrenn.client.SnapshotsResource.create" />

#### create

```python theme={null}
def create(capsule_id: str,
           name: str | None = None,
           overwrite: bool = False) -> Template
```

Create a snapshot template from a running capsule.

**Arguments**:

* `capsule_id` *str* - ID of the capsule to snapshot.
* `name` *str | None* - Name for the snapshot template. Auto-generated
  if not provided.
* `overwrite` *bool* - If `True`, overwrite an existing template with
  the same name. Defaults to `False`.

**Returns**:

* `Template` - The created snapshot template.

<a id="wrenn.client.SnapshotsResource.list" />

#### list

```python theme={null}
def list(type: str | None = None) -> list[Template]
```

List snapshot templates.

**Arguments**:

* `type` *str | None* - Filter by template type. Returns all templates
  if not provided.

**Returns**:

* `list[Template]` - Matching snapshot templates.

<a id="wrenn.client.SnapshotsResource.delete" />

#### delete

```python theme={null}
def delete(name: str) -> None
```

Delete a snapshot template by name.

**Arguments**:

* `name` *str* - Template name to delete.

**Raises**:

* `WrennNotFoundError` - If no template with the given name exists.

<a id="wrenn.client.AsyncSnapshotsResource" />

## AsyncSnapshotsResource Objects

```python theme={null}
class AsyncSnapshotsResource()
```

Async snapshot operations.

<a id="wrenn.client.AsyncSnapshotsResource.create" />

#### create

```python theme={null}
async def create(capsule_id: str,
                 name: str | None = None,
                 overwrite: bool = False) -> Template
```

Create a snapshot template from a running capsule.

**Arguments**:

* `capsule_id` *str* - ID of the capsule to snapshot.
* `name` *str | None* - Name for the snapshot template. Auto-generated
  if not provided.
* `overwrite` *bool* - If `True`, overwrite an existing template with
  the same name. Defaults to `False`.

**Returns**:

* `Template` - The created snapshot template.

<a id="wrenn.client.AsyncSnapshotsResource.list" />

#### list

```python theme={null}
async def list(type: str | None = None) -> list[Template]
```

List snapshot templates.

**Arguments**:

* `type` *str | None* - Filter by template type. Returns all templates
  if not provided.

**Returns**:

* `list[Template]` - Matching snapshot templates.

<a id="wrenn.client.AsyncSnapshotsResource.delete" />

#### delete

```python theme={null}
async def delete(name: str) -> None
```

Delete a snapshot template by name.

**Arguments**:

* `name` *str* - Template name to delete.

**Raises**:

* `WrennNotFoundError` - If no template with the given name exists.

<a id="wrenn.client.WrennClient" />

## WrennClient Objects

```python theme={null}
class WrennClient()
```

Synchronous client for the Wrenn API.

Authenticates with an API key.

**Arguments**:

* `api_key` - API key (`wrn_...`). Falls back to `WRENN_API_KEY` env var.
* `base_url` - Wrenn API base URL.

<a id="wrenn.client.WrennClient.http" />

#### http

```python theme={null}
@property
def http() -> httpx.Client
```

The underlying httpx.Client (for sub-objects that need direct access).

<a id="wrenn.client.WrennClient.close" />

#### close

```python theme={null}
def close() -> None
```

Close the underlying HTTP connection pool.

<a id="wrenn.client.AsyncWrennClient" />

## AsyncWrennClient Objects

```python theme={null}
class AsyncWrennClient()
```

Asynchronous client for the Wrenn API.

Authenticates with an API key.

**Arguments**:

* `api_key` - API key (`wrn_...`). Falls back to `WRENN_API_KEY` env var.
* `base_url` - Wrenn API base URL. Falls back to `WRENN_BASE_URL` env var.

<a id="wrenn.client.AsyncWrennClient.http" />

#### http

```python theme={null}
@property
def http() -> httpx.AsyncClient
```

The underlying httpx.AsyncClient.

<a id="wrenn.client.AsyncWrennClient.aclose" />

#### aclose

```python theme={null}
async def aclose() -> None
```

Close the underlying async HTTP connection pool.

<a id="wrenn.sandbox" />

# wrenn.sandbox

<a id="wrenn.commands" />

# wrenn.commands

<a id="wrenn.commands.CommandResult" />

## CommandResult Objects

```python theme={null}
@dataclass
class CommandResult()
```

Result from a foreground command execution.

<a id="wrenn.commands.CommandHandle" />

## CommandHandle Objects

```python theme={null}
@dataclass
class CommandHandle()
```

Handle for a background process.

<a id="wrenn.commands.ProcessInfo" />

## ProcessInfo Objects

```python theme={null}
@dataclass
class ProcessInfo()
```

Information about a running process.

<a id="wrenn.commands.StreamEvent" />

## StreamEvent Objects

```python theme={null}
class StreamEvent()
```

Base class for streaming exec events.

<a id="wrenn.commands.Commands" />

## Commands Objects

```python theme={null}
class Commands()
```

Sync command execution interface. Accessed via `capsule.commands`.

<a id="wrenn.commands.Commands.run" />

#### run

```python theme={null}
def run(cmd: str,
        *,
        background: bool = False,
        timeout: int | None = 30,
        envs: dict[str, str] | None = None,
        cwd: str | None = None,
        tag: str | None = None) -> CommandResult | CommandHandle
```

Execute a shell command inside the capsule.

**Arguments**:

* `cmd` *str* - Shell command string to execute.
* `background` *bool* - If `True`, launch the process in the
  background and return a :class:`CommandHandle` immediately.
  Defaults to `False`.
* `timeout` *int | None* - Seconds before the foreground command times
  out. Ignored for background commands. Defaults to `30`.
* `envs` *dict\[str, str] | None* - Additional environment variables
  to set for the process.
* `cwd` *str | None* - Working directory for the process.
* `tag` *str | None* - Optional label attached to background processes
  for later retrieval via :meth:`connect`.

**Returns**:

* `CommandResult` - stdout, stderr, exit code, and duration for
  foreground commands (`background=False`).

* `CommandHandle` - PID and tag for background commands
  (`background=True`).

<a id="wrenn.commands.Commands.list" />

#### list

```python theme={null}
def list() -> list[ProcessInfo]
```

List all running background processes in the capsule.

**Returns**:

* `list[ProcessInfo]` - Running processes with their PID, tag, and
  command information.

<a id="wrenn.commands.Commands.kill" />

#### kill

```python theme={null}
def kill(pid: int) -> None
```

Send SIGKILL to a background process.

**Arguments**:

* `pid` *int* - PID of the process to kill.

**Raises**:

* `WrennNotFoundError` - If no process with the given PID exists.

<a id="wrenn.commands.Commands.connect" />

#### connect

```python theme={null}
def connect(pid: int) -> Iterator[StreamEvent]
```

Connect to a running background process and stream its output.

**Arguments**:

* `pid` *int* - PID of the background process to attach to.

**Yields**:

* `StreamEvent` - Successive output events. Stops on
  :class:`StreamExitEvent` or :class:`StreamErrorEvent`.

<a id="wrenn.commands.Commands.stream" />

#### stream

```python theme={null}
def stream(cmd: str, args: list[str] | None = None) -> Iterator[StreamEvent]
```

Execute a command via WebSocket, streaming output as events.

**Arguments**:

* `cmd` *str* - Command to execute.
* `args` *list\[str] | None* - Additional arguments for the command.
  When omitted, *cmd* is interpreted as a shell command
  string and executed via `/bin/sh -c`.

**Yields**:

* `StreamEvent` - Successive events including :class:`StreamStartEvent`,
  :class:`StreamStdoutEvent`, :class:`StreamStderrEvent`,
  :class:`StreamExitEvent`, and :class:`StreamErrorEvent`.

<a id="wrenn.commands.AsyncCommands" />

## AsyncCommands Objects

```python theme={null}
class AsyncCommands()
```

Async command execution interface. Accessed via `capsule.commands`.

<a id="wrenn.commands.AsyncCommands.run" />

#### run

```python theme={null}
async def run(cmd: str,
              *,
              background: bool = False,
              timeout: int | None = 30,
              envs: dict[str, str] | None = None,
              cwd: str | None = None,
              tag: str | None = None) -> CommandResult | CommandHandle
```

Execute a shell command inside the capsule.

**Arguments**:

* `cmd` *str* - Shell command string to execute.
* `background` *bool* - If `True`, launch the process in the
  background and return a :class:`CommandHandle` immediately.
  Defaults to `False`.
* `timeout` *int | None* - Seconds before the foreground command times
  out. Ignored for background commands. Defaults to `30`.
* `envs` *dict\[str, str] | None* - Additional environment variables
  to set for the process.
* `cwd` *str | None* - Working directory for the process.
* `tag` *str | None* - Optional label attached to background processes
  for later retrieval via :meth:`connect`.

**Returns**:

* `CommandResult` - stdout, stderr, exit code, and duration for
  foreground commands (`background=False`).

* `CommandHandle` - PID and tag for background commands
  (`background=True`).

<a id="wrenn.commands.AsyncCommands.list" />

#### list

```python theme={null}
async def list() -> list[ProcessInfo]
```

List all running background processes in the capsule.

**Returns**:

* `list[ProcessInfo]` - Running processes with their PID, tag, and
  command information.

<a id="wrenn.commands.AsyncCommands.kill" />

#### kill

```python theme={null}
async def kill(pid: int) -> None
```

Send SIGKILL to a background process.

**Arguments**:

* `pid` *int* - PID of the process to kill.

**Raises**:

* `WrennNotFoundError` - If no process with the given PID exists.

<a id="wrenn.commands.AsyncCommands.connect" />

#### connect

```python theme={null}
async def connect(pid: int) -> AsyncIterator[StreamEvent]
```

Connect to a running background process and stream its output.

**Arguments**:

* `pid` *int* - PID of the background process to attach to.

**Yields**:

* `StreamEvent` - Successive output events. Stops on
  :class:`StreamExitEvent` or :class:`StreamErrorEvent`.

<a id="wrenn.commands.AsyncCommands.stream" />

#### stream

```python theme={null}
async def stream(cmd: str,
                 args: list[str] | None = None) -> AsyncIterator[StreamEvent]
```

Execute a command via WebSocket, streaming output as events.

**Arguments**:

* `cmd` *str* - Command to execute.
* `args` *list\[str] | None* - Additional arguments for the command.
  When omitted, *cmd* is interpreted as a shell command
  string and executed via `/bin/sh -c`.

**Yields**:

* `StreamEvent` - Successive events including :class:`StreamStartEvent`,
  :class:`StreamStdoutEvent`, :class:`StreamStderrEvent`,
  :class:`StreamExitEvent`, and :class:`StreamErrorEvent`.

<a id="wrenn.files" />

# wrenn.files

<a id="wrenn.files.Files" />

## Files Objects

```python theme={null}
class Files()
```

Sync filesystem interface. Accessed via `capsule.files`.

<a id="wrenn.files.Files.read" />

#### read

```python theme={null}
def read(path: str) -> str
```

Read a file as a UTF-8 string.

**Arguments**:

* `path` *str* - Absolute path to the file inside the capsule.

**Returns**:

* `str` - File contents decoded as UTF-8.

**Raises**:

* `WrennNotFoundError` - If the path does not exist.

<a id="wrenn.files.Files.read_bytes" />

#### read\_bytes

```python theme={null}
def read_bytes(path: str) -> bytes
```

Read a file as raw bytes.

**Arguments**:

* `path` *str* - Absolute path to the file inside the capsule.

**Returns**:

* `bytes` - Raw file contents.

**Raises**:

* `WrennNotFoundError` - If the path does not exist.

<a id="wrenn.files.Files.write" />

#### write

```python theme={null}
def write(path: str, data: str | bytes) -> None
```

Write data to a file inside the capsule.

Creates parent directories if they do not exist.

**Arguments**:

* `path` *str* - Absolute destination path inside the capsule.
* `data` *str | bytes* - Content to write. Strings are UTF-8 encoded.

<a id="wrenn.files.Files.list" />

#### list

```python theme={null}
def list(path: str, depth: int = 1) -> list[FileEntry]
```

List directory contents.

**Arguments**:

* `path` *str* - Absolute path to the directory inside the capsule.
* `depth` *int* - Recursion depth. `1` lists only immediate children.
  Defaults to `1`.

**Returns**:

* `list[FileEntry]` - Entries in the directory.

**Raises**:

* `WrennNotFoundError` - If the path does not exist.

<a id="wrenn.files.Files.exists" />

#### exists

```python theme={null}
def exists(path: str) -> bool
```

Check whether a path exists inside the capsule.

**Arguments**:

* `path` *str* - Absolute path to check.

**Returns**:

* `bool` - `True` if the path exists.

<a id="wrenn.files.Files.make_dir" />

#### make\_dir

```python theme={null}
def make_dir(path: str) -> FileEntry
```

Create a directory (with parents). Idempotent.

**Arguments**:

* `path` *str* - Absolute path of the directory to create.

**Returns**:

* `FileEntry` - The created (or already-existing) directory entry.

<a id="wrenn.files.Files.remove" />

#### remove

```python theme={null}
def remove(path: str) -> None
```

Remove a file or directory recursively.

**Arguments**:

* `path` *str* - Absolute path to remove.

**Raises**:

* `WrennNotFoundError` - If the path does not exist.

<a id="wrenn.files.Files.upload_stream" />

#### upload\_stream

```python theme={null}
def upload_stream(path: str, stream: Iterator[bytes]) -> None
```

Stream a large file into the capsule.

Prefer this over :meth:`write` when the file is too large to hold in
memory.

**Arguments**:

* `path` *str* - Absolute destination path inside the capsule.
* `stream` *Iterator\[bytes]* - Iterable of byte chunks to upload.

<a id="wrenn.files.Files.download_stream" />

#### download\_stream

```python theme={null}
def download_stream(path: str) -> Iterator[bytes]
```

Stream a large file out of the capsule.

Prefer this over :meth:`read_bytes` when the file is too large to hold
in memory.

**Arguments**:

* `path` *str* - Absolute path to the file inside the capsule.

**Yields**:

* `bytes` - Successive byte chunks of the file.

**Raises**:

* `WrennNotFoundError` - If the path does not exist.

<a id="wrenn.files.AsyncFiles" />

## AsyncFiles Objects

```python theme={null}
class AsyncFiles()
```

Async filesystem interface. Accessed via `capsule.files`.

<a id="wrenn.files.AsyncFiles.read" />

#### read

```python theme={null}
async def read(path: str) -> str
```

Read a file as a UTF-8 string.

**Arguments**:

* `path` *str* - Absolute path to the file inside the capsule.

**Returns**:

* `str` - File contents decoded as UTF-8.

**Raises**:

* `WrennNotFoundError` - If the path does not exist.

<a id="wrenn.files.AsyncFiles.read_bytes" />

#### read\_bytes

```python theme={null}
async def read_bytes(path: str) -> bytes
```

Read a file as raw bytes.

**Arguments**:

* `path` *str* - Absolute path to the file inside the capsule.

**Returns**:

* `bytes` - Raw file contents.

**Raises**:

* `WrennNotFoundError` - If the path does not exist.

<a id="wrenn.files.AsyncFiles.write" />

#### write

```python theme={null}
async def write(path: str, data: str | bytes) -> None
```

Write data to a file inside the capsule.

Creates parent directories if they do not exist.

**Arguments**:

* `path` *str* - Absolute destination path inside the capsule.
* `data` *str | bytes* - Content to write. Strings are UTF-8 encoded.

<a id="wrenn.files.AsyncFiles.list" />

#### list

```python theme={null}
async def list(path: str, depth: int = 1) -> list[FileEntry]
```

List directory contents.

**Arguments**:

* `path` *str* - Absolute path to the directory inside the capsule.
* `depth` *int* - Recursion depth. `1` lists only immediate children.
  Defaults to `1`.

**Returns**:

* `list[FileEntry]` - Entries in the directory.

**Raises**:

* `WrennNotFoundError` - If the path does not exist.

<a id="wrenn.files.AsyncFiles.exists" />

#### exists

```python theme={null}
async def exists(path: str) -> bool
```

Check whether a path exists inside the capsule.

**Arguments**:

* `path` *str* - Absolute path to check.

**Returns**:

* `bool` - `True` if the path exists.

<a id="wrenn.files.AsyncFiles.make_dir" />

#### make\_dir

```python theme={null}
async def make_dir(path: str) -> FileEntry
```

Create a directory (with parents). Idempotent.

**Arguments**:

* `path` *str* - Absolute path of the directory to create.

**Returns**:

* `FileEntry` - The created (or already-existing) directory entry.

<a id="wrenn.files.AsyncFiles.remove" />

#### remove

```python theme={null}
async def remove(path: str) -> None
```

Remove a file or directory recursively.

**Arguments**:

* `path` *str* - Absolute path to remove.

**Raises**:

* `WrennNotFoundError` - If the path does not exist.

<a id="wrenn.files.AsyncFiles.upload_stream" />

#### upload\_stream

```python theme={null}
async def upload_stream(path: str, stream: AsyncIterator[bytes]) -> None
```

Stream a large file into the capsule.

Prefer this over :meth:`write` when the file is too large to hold in
memory.

**Arguments**:

* `path` *str* - Absolute destination path inside the capsule.
* `stream` *AsyncIterator\[bytes]* - Async iterable of byte chunks to
  upload.

<a id="wrenn.files.AsyncFiles.download_stream" />

#### download\_stream

```python theme={null}
async def download_stream(path: str) -> AsyncIterator[bytes]
```

Stream a large file out of the capsule.

Prefer this over :meth:`read_bytes` when the file is too large to hold
in memory.

**Arguments**:

* `path` *str* - Absolute path to the file inside the capsule.

**Yields**:

* `bytes` - Successive byte chunks of the file.

**Raises**:

* `WrennNotFoundError` - If the path does not exist.

<a id="wrenn.code_interpreter.models" />

# wrenn.code\_interpreter.models

<a id="wrenn.code_interpreter.models.ExecutionError" />

## ExecutionError Objects

```python theme={null}
@dataclass
class ExecutionError()
```

Error raised during code execution.

**Attributes**:

* `name` - Exception class name (e.g. `"NameError"`).
* `value` - Exception message.
* `traceback` - Full traceback string.

<a id="wrenn.code_interpreter.models.Logs" />

## Logs Objects

```python theme={null}
@dataclass
class Logs()
```

Captured stdout/stderr streams.

Each element in the list is one chunk of text as it arrived from
the kernel.

<a id="wrenn.code_interpreter.models.Result" />

## Result Objects

```python theme={null}
@dataclass
class Result()
```

A single rich output from code execution.

Jupyter cells can produce multiple outputs — one `execute_result`
(the expression value) and zero or more `display_data` messages
(from `plt.show()`, `display()`, etc.).  Each becomes a
`Result`.

Known MIME types are unpacked into named attributes; anything else
lands in :pyattr:`extra`.

<a id="wrenn.code_interpreter.models.Result.text" />

#### text

`text/plain` representation.

<a id="wrenn.code_interpreter.models.Result.html" />

#### html

`text/html` representation.

<a id="wrenn.code_interpreter.models.Result.markdown" />

#### markdown

`text/markdown` representation.

<a id="wrenn.code_interpreter.models.Result.svg" />

#### svg

`image/svg+xml` representation.

<a id="wrenn.code_interpreter.models.Result.png" />

#### png

`image/png` — base64-encoded.

<a id="wrenn.code_interpreter.models.Result.jpeg" />

#### jpeg

`image/jpeg` — base64-encoded.

<a id="wrenn.code_interpreter.models.Result.pdf" />

#### pdf

`application/pdf` — base64-encoded.

<a id="wrenn.code_interpreter.models.Result.latex" />

#### latex

`text/latex` representation.

<a id="wrenn.code_interpreter.models.Result.json" />

#### json

`application/json` representation.

<a id="wrenn.code_interpreter.models.Result.javascript" />

#### javascript

`application/javascript` representation.

<a id="wrenn.code_interpreter.models.Result.extra" />

#### extra

MIME types not covered by the named fields above.

<a id="wrenn.code_interpreter.models.Result.is_main_result" />

#### is\_main\_result

`True` when this came from an `execute_result` message
(i.e. the value of the last expression in the cell).  `False`
for `display_data` outputs.

<a id="wrenn.code_interpreter.models.Result.from_bundle" />

#### from\_bundle

```python theme={null}
@classmethod
def from_bundle(cls,
                bundle: dict[str, str],
                *,
                is_main_result: bool = False) -> Result
```

Build a `Result` from a Jupyter MIME bundle dict.

<a id="wrenn.code_interpreter.models.Result.formats" />

#### formats

```python theme={null}
def formats() -> list[str]
```

Return names of non-`None` MIME-type fields.

<a id="wrenn.code_interpreter.models.Execution" />

## Execution Objects

```python theme={null}
@dataclass
class Execution()
```

Complete result of a `run_code` call.

**Attributes**:

* `results` - All rich outputs produced by the cell — charts, tables,
  images, expression values, etc.
* `logs` - Captured stdout/stderr text.
* `error` - Populated when the cell raised an exception.
* `execution_count` - Jupyter execution counter (the `[N]` number).

<a id="wrenn.code_interpreter.models.Execution.text" />

#### text

```python theme={null}
@property
def text() -> str | None
```

Convenience — `text/plain` of the main `execute_result`,
or `None` if the cell had no expression value.

<a id="wrenn.code_interpreter.async_capsule" />

# wrenn.code\_interpreter.async\_capsule

<a id="wrenn.code_interpreter.async_capsule.AsyncCapsule" />

## AsyncCapsule Objects

```python theme={null}
class AsyncCapsule(BaseAsyncCapsule)
```

Async code interpreter capsule with `run_code` support.

Uses `code-runner-beta` template by default::

from wrenn.code\_interpreter import AsyncCapsule

capsule = await AsyncCapsule.create()
result = await capsule.run\_code("print('hello')")

<a id="wrenn.code_interpreter.async_capsule.AsyncCapsule.create" />

#### create

```python theme={null}
@classmethod
async def create(cls,
                 template: str | None = None,
                 vcpus: int | None = None,
                 memory_mb: int | None = None,
                 timeout: int | None = None,
                 *,
                 wait: bool = False,
                 api_key: str | None = None,
                 base_url: str | None = None) -> AsyncCapsule
```

Create a new async code interpreter capsule.

**Arguments**:

* `template` *str | None* - Template to boot from. Defaults to
  `"code-runner-beta"`.
* `vcpus` *int | None* - Number of virtual CPUs.
* `memory_mb` *int | None* - Memory in MiB.
* `timeout` *int | None* - Inactivity TTL in seconds before auto-pause.
* `wait` *bool* - Await until the capsule reaches `running` status.
* `api_key` *str | None* - Wrenn API key. Falls back to
  `WRENN_API_KEY` env var.
* `base_url` *str | None* - API base URL override.

**Returns**:

* `AsyncCapsule` - A new async code interpreter capsule instance.

<a id="wrenn.code_interpreter.async_capsule.AsyncCapsule.run_code" />

#### run\_code

```python theme={null}
async def run_code(
        code: str,
        language: str = "python",
        timeout: float = 30,
        jupyter_timeout: float = 30,
        on_result: Callable[[Result], Any] | None = None,
        on_stdout: Callable[[str], Any] | None = None,
        on_stderr: Callable[[str], Any] | None = None,
        on_error: Callable[[ExecutionError], Any] | None = None) -> Execution
```

Execute code in a persistent Jupyter kernel (async).

**Arguments**:

* `code` - Code string to execute.
* `language` - Execution backend language. Currently only `"python"`.
* `timeout` - Maximum seconds to wait for execution to complete.
* `jupyter_timeout` - Maximum seconds to wait for Jupyter to become
  available.
* `on_result` - Called for each rich output (charts, images, expression
  values).
* `on_stdout` - Called for each stdout chunk.
* `on_stderr` - Called for each stderr chunk.
* `on_error` - Called when the cell raises an exception.

**Returns**:

An :class:`Execution` with `.results`, `.logs`, `.error`,
and a convenience `.text` property.

<a id="wrenn.code_interpreter" />

# wrenn.code\_interpreter

<a id="wrenn.code_interpreter.capsule" />

# wrenn.code\_interpreter.capsule

<a id="wrenn.code_interpreter.capsule.Capsule" />

## Capsule Objects

```python theme={null}
class Capsule(BaseCapsule)
```

Code interpreter capsule with `run_code` support.

Uses `code-runner-beta` template by default::

from wrenn.code\_interpreter import Capsule

capsule = Capsule()
result = capsule.run\_code("print('hello')")
print(result.logs.stdout)  # \["hello\n"]

<a id="wrenn.code_interpreter.capsule.Capsule.__init__" />

#### \_\_init\_\_

```python theme={null}
def __init__(template: str | None = None,
             vcpus: int | None = None,
             memory_mb: int | None = None,
             timeout: int | None = None,
             *,
             api_key: str | None = None,
             base_url: str | None = None,
             **kwargs) -> None
```

Create a code interpreter capsule.

**Arguments**:

* `template` *str | None* - Template to boot from. Defaults to
  `"code-runner-beta"`.
* `vcpus` *int | None* - Number of virtual CPUs.
* `memory_mb` *int | None* - Memory in MiB.
* `timeout` *int | None* - Inactivity TTL in seconds before auto-pause.
* `api_key` *str | None* - Wrenn API key. Falls back to
  `WRENN_API_KEY` env var.
* `base_url` *str | None* - API base URL override.

<a id="wrenn.code_interpreter.capsule.Capsule.create" />

#### create

```python theme={null}
@classmethod
def create(cls,
           template: str | None = None,
           vcpus: int | None = None,
           memory_mb: int | None = None,
           timeout: int | None = None,
           *,
           wait: bool = False,
           api_key: str | None = None,
           base_url: str | None = None) -> Capsule
```

Create a new code interpreter capsule.

**Arguments**:

* `template` *str | None* - Template to boot from. Defaults to
  `"code-runner-beta"`.
* `vcpus` *int | None* - Number of virtual CPUs.
* `memory_mb` *int | None* - Memory in MiB.
* `timeout` *int | None* - Inactivity TTL in seconds before auto-pause.
* `wait` *bool* - Block until the capsule reaches `running` status.
* `api_key` *str | None* - Wrenn API key. Falls back to
  `WRENN_API_KEY` env var.
* `base_url` *str | None* - API base URL override.

**Returns**:

* `Capsule` - A new code interpreter capsule instance.

<a id="wrenn.code_interpreter.capsule.Capsule.run_code" />

#### run\_code

```python theme={null}
def run_code(
        code: str,
        language: str = "python",
        timeout: float = 30,
        jupyter_timeout: float = 30,
        on_result: Callable[[Result], Any] | None = None,
        on_stdout: Callable[[str], Any] | None = None,
        on_stderr: Callable[[str], Any] | None = None,
        on_error: Callable[[ExecutionError], Any] | None = None) -> Execution
```

Execute code in a persistent Jupyter kernel.

Variables, imports, and function definitions survive across calls.

**Arguments**:

* `code` - Code string to execute.
* `language` - Execution backend language. Currently only `"python"`.
* `timeout` - Maximum seconds to wait for execution to complete.
* `jupyter_timeout` - Maximum seconds to wait for Jupyter to become
  available.
* `on_result` - Called for each rich output (charts, images, expression
  values).
* `on_stdout` - Called for each stdout chunk.
* `on_stderr` - Called for each stderr chunk.
* `on_error` - Called when the cell raises an exception.

**Returns**:

An :class:`Execution` with `.results`, `.logs`, `.error`,
and a convenience `.text` property.

<a id="wrenn.exceptions" />

# wrenn.exceptions

<a id="wrenn.exceptions.WrennError" />

## WrennError Objects

```python theme={null}
class WrennError(Exception)
```

Base exception for all Wrenn SDK errors.

All SDK exceptions inherit from this class, so you can catch
`WrennError` to handle any API error generically.

**Attributes**:

* `code` *str* - Machine-readable error code from the API
  (e.g. `"not_found"`).
* `message` *str* - Human-readable error description.
* `status_code` *int* - HTTP status code of the response.

<a id="wrenn.exceptions.WrennError.__init__" />

#### \_\_init\_\_

```python theme={null}
def __init__(code: str, message: str, status_code: int) -> None
```

Initialize a WrennError.

**Arguments**:

* `code` *str* - Machine-readable error code.
* `message` *str* - Human-readable error description.
* `status_code` *int* - HTTP status code of the response.

<a id="wrenn.exceptions.WrennValidationError" />

## WrennValidationError Objects

```python theme={null}
class WrennValidationError(WrennError)
```

400 — Invalid request parameters.

<a id="wrenn.exceptions.WrennAuthenticationError" />

## WrennAuthenticationError Objects

```python theme={null}
class WrennAuthenticationError(WrennError)
```

401 — Invalid or missing authentication.

<a id="wrenn.exceptions.WrennForbiddenError" />

## WrennForbiddenError Objects

```python theme={null}
class WrennForbiddenError(WrennError)
```

403 — Authenticated but not authorized.

<a id="wrenn.exceptions.WrennNotFoundError" />

## WrennNotFoundError Objects

```python theme={null}
class WrennNotFoundError(WrennError)
```

404 — Resource not found.

<a id="wrenn.exceptions.WrennConflictError" />

## WrennConflictError Objects

```python theme={null}
class WrennConflictError(WrennError)
```

409 — State conflict (e.g. invalid\_state).

<a id="wrenn.exceptions.WrennHostHasCapsulesError" />

## WrennHostHasCapsulesError Objects

```python theme={null}
class WrennHostHasCapsulesError(WrennConflictError)
```

409 — Host still has running capsules.

**Attributes**:

* `capsule_ids` *list\[str]* - IDs of the capsules still running on the host.

<a id="wrenn.exceptions.WrennHostHasCapsulesError.__init__" />

#### \_\_init\_\_

```python theme={null}
def __init__(code: str, message: str, status_code: int,
             capsule_ids: list[str]) -> None
```

Initialize a WrennHostHasCapsulesError.

**Arguments**:

* `code` *str* - Machine-readable error code.
* `message` *str* - Human-readable error description.
* `status_code` *int* - HTTP status code of the response.
* `capsule_ids` *list\[str]* - IDs of capsules still on the host.

<a id="wrenn.exceptions.WrennHostUnavailableError" />

## WrennHostUnavailableError Objects

```python theme={null}
class WrennHostUnavailableError(WrennError)
```

503 — No suitable host available.

<a id="wrenn.exceptions.WrennAgentError" />

## WrennAgentError Objects

```python theme={null}
class WrennAgentError(WrennError)
```

502 — Host agent returned an error.

<a id="wrenn.exceptions.WrennInternalError" />

## WrennInternalError Objects

```python theme={null}
class WrennInternalError(WrennError)
```

500 — Unexpected server error.

<a id="wrenn.async_capsule" />

# wrenn.async\_capsule

<a id="wrenn.async_capsule.AsyncCapsule" />

## AsyncCapsule Objects

```python theme={null}
class AsyncCapsule()
```

Async Wrenn capsule with e2b-compatible interface.

Create via classmethod::

capsule = await AsyncCapsule.create(template="minimal")

Use as async context manager::

async with await AsyncCapsule.create() as capsule:
await capsule.commands.run("echo hello")

<a id="wrenn.async_capsule.AsyncCapsule.capsule_id" />

#### capsule\_id

```python theme={null}
@property
def capsule_id() -> str
```

The capsule's unique identifier.

**Returns**:

* `str` - Capsule ID assigned by the Wrenn API.

<a id="wrenn.async_capsule.AsyncCapsule.info" />

#### info

```python theme={null}
@property
def info() -> CapsuleModel | None
```

Cached capsule metadata from the last API call.

**Returns**:

CapsuleModel | None: The last-fetched capsule model, or `None`
if the capsule was connected without an initial fetch.

<a id="wrenn.async_capsule.AsyncCapsule.create" />

#### create

```python theme={null}
@classmethod
async def create(cls,
                 template: str | None = None,
                 vcpus: int | None = None,
                 memory_mb: int | None = None,
                 timeout: int | None = None,
                 *,
                 wait: bool = False,
                 api_key: str | None = None,
                 base_url: str | None = None) -> AsyncCapsule
```

Create a new capsule.

**Arguments**:

* `template` *str | None* - Template name to boot from.
* `vcpus` *int | None* - Number of virtual CPUs.
* `memory_mb` *int | None* - Memory in MiB.
* `timeout` *int | None* - Inactivity TTL in seconds before auto-pause.
* `wait` *bool* - Await until the capsule reaches `running` status.
* `api_key` *str | None* - Wrenn API key. Falls back to
  `WRENN_API_KEY` env var.
* `base_url` *str | None* - API base URL override.

**Returns**:

* `AsyncCapsule` - A new capsule instance.

<a id="wrenn.async_capsule.AsyncCapsule.connect" />

#### connect

```python theme={null}
@classmethod
async def connect(cls,
                  capsule_id: str,
                  *,
                  api_key: str | None = None,
                  base_url: str | None = None) -> AsyncCapsule
```

Connect to an existing capsule, resuming it if paused.

**Arguments**:

* `capsule_id` *str* - ID of the capsule to connect to.
* `api_key` *str | None* - Wrenn API key. Falls back to
  `WRENN_API_KEY` env var.
* `base_url` *str | None* - API base URL override.

**Returns**:

* `AsyncCapsule` - A capsule instance bound to the existing capsule.

**Raises**:

* `WrennNotFoundError` - If no capsule with the given ID exists.

<a id="wrenn.async_capsule.AsyncCapsule.ping" />

#### ping

```python theme={null}
async def ping() -> None
```

Reset the capsule inactivity timer.

Call this to prevent the capsule from being auto-paused when the
inactivity TTL is set.

<a id="wrenn.async_capsule.AsyncCapsule.wait_ready" />

#### wait\_ready

```python theme={null}
async def wait_ready(timeout: float = 30, interval: float = 0.5) -> None
```

Await until the capsule status is `running`.

**Arguments**:

* `timeout` *float* - Maximum seconds to wait. Defaults to `30`.
* `interval` *float* - Polling interval in seconds. Defaults to `0.5`.

**Raises**:

* `TimeoutError` - If the capsule does not reach `running` state
  within `timeout` seconds.
* `RuntimeError` - If the capsule enters an error, stopped, or paused
  state while waiting.

<a id="wrenn.async_capsule.AsyncCapsule.is_running" />

#### is\_running

```python theme={null}
async def is_running() -> bool
```

Check whether the capsule is currently running.

Makes a live API call to fetch current status.

**Returns**:

* `bool` - `True` if the capsule status is `running`.

<a id="wrenn.async_capsule.AsyncCapsule.list" />

#### list

```python theme={null}
@classmethod
async def list(cls,
               *,
               api_key: str | None = None,
               base_url: str | None = None) -> list[CapsuleModel]
```

List all capsules belonging to the team.

**Arguments**:

* `api_key` *str | None* - Wrenn API key. Falls back to
  `WRENN_API_KEY` env var.
* `base_url` *str | None* - API base URL override.

**Returns**:

* `list[CapsuleModel]` - All capsules for the authenticated team.

<a id="wrenn.async_capsule.AsyncCapsule.pty" />

#### pty

```python theme={null}
@asynccontextmanager
async def pty(cmd: str = "/bin/bash",
              args: list[str] | None = None,
              cols: int = 80,
              rows: int = 24,
              envs: dict[str, str] | None = None,
              cwd: str | None = None) -> AsyncIterator[AsyncPtySession]
```

Open an async interactive PTY session backed by a WebSocket.

Use as an async context manager and async iterate over
:class:`PtyEvent` objects::

async with capsule.pty() as term:
await term.write(b"echo hello\n")
async for event in term:
if event.type == "output":
print(event.data.decode())

**Arguments**:

* `cmd` *str* - Command to run inside the PTY. Defaults to
  `"/bin/bash"`.
* `args` *list\[str] | None* - Additional arguments for `cmd`.
* `cols` *int* - Initial terminal column count. Defaults to `80`.
* `rows` *int* - Initial terminal row count. Defaults to `24`.
* `envs` *dict\[str, str] | None* - Additional environment variables
  to inject into the process.
* `cwd` *str | None* - Working directory for the process.

**Yields**:

* `AsyncPtySession` - An interactive async PTY session.

<a id="wrenn.async_capsule.AsyncCapsule.pty_connect" />

#### pty\_connect

```python theme={null}
@asynccontextmanager
async def pty_connect(tag: str) -> AsyncIterator[AsyncPtySession]
```

Reconnect to an existing PTY session by tag.

**Arguments**:

* `tag` *str* - Session tag returned in the `started` PTY event.

**Yields**:

* `AsyncPtySession` - The reconnected async PTY session.

<a id="wrenn.async_capsule.AsyncCapsule.get_url" />

#### get\_url

```python theme={null}
def get_url(port: int) -> str
```

Get the proxy URL for a port exposed inside this capsule.

**Arguments**:

* `port` *int* - Port number to proxy.

**Returns**:

* `str` - A `wss://` (or `ws://`) URL that proxies to the given
  port inside the capsule.

<a id="wrenn.async_capsule.AsyncCapsule.create_snapshot" />

#### create\_snapshot

```python theme={null}
async def create_snapshot(name: str | None = None,
                          overwrite: bool = False) -> Template
```

Create a snapshot template from this capsule's current state.

**Arguments**:

* `name` *str | None* - Name for the snapshot template. Auto-generated
  if not provided.
* `overwrite` *bool* - If `True`, overwrite an existing template with
  the same name. Defaults to `False`.

**Returns**:

* `Template` - The created snapshot template.

<a id="wrenn.pty" />

# wrenn.pty

<a id="wrenn.pty.PtySession" />

## PtySession Objects

```python theme={null}
class PtySession()
```

Interactive PTY session backed by a WebSocket.

Use as a context manager and iterate over events::

with sb.pty(cmd="/bin/bash") as term:
term.write(b"ls -la\n")
for event in term:
if event.type == "output":
sys.stdout.buffer.write(event.data)
elif event.type == "exit":
break

<a id="wrenn.pty.PtySession.tag" />

#### tag

```python theme={null}
@property
def tag() -> str | None
```

Session tag. Available after the `started` event.

<a id="wrenn.pty.PtySession.pid" />

#### pid

```python theme={null}
@property
def pid() -> int | None
```

Process PID. Available after the `started` event.

<a id="wrenn.pty.PtySession.write" />

#### write

```python theme={null}
def write(data: bytes) -> None
```

Send raw bytes to the PTY stdin.

**Arguments**:

* `data` - Raw bytes to send. Base64-encoded internally.

<a id="wrenn.pty.PtySession.resize" />

#### resize

```python theme={null}
def resize(cols: int, rows: int) -> None
```

Resize the PTY terminal.

**Arguments**:

* `cols` - New column count. Must be > 0.
* `rows` - New row count. Must be > 0.

**Raises**:

* `ValueError` - If cols or rows is 0.

<a id="wrenn.pty.PtySession.kill" />

#### kill

```python theme={null}
def kill() -> None
```

Send SIGKILL to the PTY process.

<a id="wrenn.pty.AsyncPtySession" />

## AsyncPtySession Objects

```python theme={null}
class AsyncPtySession()
```

Async interactive PTY session backed by a WebSocket.

Use as an async context manager and async iterate over events::

async with sb.pty(cmd="/bin/bash") as term:
await term.write(b"ls -la\n")
async for event in term:
if event.type == "output":
sys.stdout.buffer.write(event.data)
elif event.type == "exit":
break

<a id="wrenn.pty.AsyncPtySession.tag" />

#### tag

```python theme={null}
@property
def tag() -> str | None
```

Session tag. Available after the `started` event.

<a id="wrenn.pty.AsyncPtySession.pid" />

#### pid

```python theme={null}
@property
def pid() -> int | None
```

Process PID. Available after the `started` event.

<a id="wrenn.pty.AsyncPtySession.write" />

#### write

```python theme={null}
async def write(data: bytes) -> None
```

Send raw bytes to the PTY stdin.

**Arguments**:

* `data` - Raw bytes to send. Base64-encoded internally.

<a id="wrenn.pty.AsyncPtySession.resize" />

#### resize

```python theme={null}
async def resize(cols: int, rows: int) -> None
```

Resize the PTY terminal.

**Arguments**:

* `cols` - New column count. Must be > 0.
* `rows` - New row count. Must be > 0.

**Raises**:

* `ValueError` - If cols or rows is 0.

<a id="wrenn.pty.AsyncPtySession.kill" />

#### kill

```python theme={null}
async def kill() -> None
```

Send SIGKILL to the PTY process.

<a id="wrenn.models._generated" />

# wrenn.models.\_generated

<a id="wrenn.models._generated.Peaks" />

## Peaks Objects

```python theme={null}
class Peaks(BaseModel)
```

Maximum values over the last 30 days.

<a id="wrenn.models._generated.Series" />

## Series Objects

```python theme={null}
class Series(BaseModel)
```

Parallel arrays for chart rendering.

<a id="wrenn.models._generated.Encoding" />

## Encoding Objects

```python theme={null}
class Encoding(StrEnum)
```

Output encoding. "base64" when stdout/stderr contain binary data.

<a id="wrenn.models._generated.Type2" />

## Type2 Objects

```python theme={null}
class Type2(StrEnum)
```

Host type. Regular hosts are shared; BYOC hosts belong to a team.

<a id="wrenn.models" />

# wrenn.models

<a id="wrenn.capsule" />

# wrenn.capsule

<a id="wrenn.capsule.Capsule" />

## Capsule Objects

```python theme={null}
class Capsule()
```

A Wrenn capsule (sandbox) with e2b-compatible interface.

Create directly::

capsule = Capsule(api\_key="wrn\_...")
capsule = Capsule(template="minimal")  # reads WRENN\_API\_KEY env

Or via classmethod::

capsule = Capsule.create(template="minimal")

Use as context manager for automatic cleanup::

with Capsule() as capsule:
capsule.commands.run("echo hello")

<a id="wrenn.capsule.Capsule.__init__" />

#### \_\_init\_\_

```python theme={null}
def __init__(template: str | None = None,
             vcpus: int | None = None,
             memory_mb: int | None = None,
             timeout: int | None = None,
             *,
             wait: bool = False,
             api_key: str | None = None,
             base_url: str | None = None,
             _capsule_id: str | None = None,
             _client: WrennClient | None = None,
             _info: CapsuleModel | None = None) -> None
```

Create and start a new capsule.

**Arguments**:

* `template` *str | None* - Template name to boot from. Defaults to
  the server-side default (`"minimal"`).
* `vcpus` *int | None* - Number of virtual CPUs. Defaults to the
  server-side default.
* `memory_mb` *int | None* - Memory in MiB. Defaults to the
  server-side default.
* `timeout` *int | None* - Inactivity TTL in seconds before the capsule
  is auto-paused. `0` disables auto-pause.
* `wait` *bool* - If `True`, block until the capsule status is
  `running` before returning.
* `api_key` *str | None* - Wrenn API key (`wrn_...`). Falls back to
  the `WRENN_API_KEY` environment variable.
* `base_url` *str | None* - Wrenn API base URL. Falls back to
  `WRENN_BASE_URL` or the default production endpoint.

<a id="wrenn.capsule.Capsule.capsule_id" />

#### capsule\_id

```python theme={null}
@property
def capsule_id() -> str
```

The capsule's unique identifier.

**Returns**:

* `str` - Capsule ID assigned by the Wrenn API.

<a id="wrenn.capsule.Capsule.info" />

#### info

```python theme={null}
@property
def info() -> CapsuleModel | None
```

Cached capsule metadata from the last API call.

**Returns**:

CapsuleModel | None: The last-fetched capsule model, or `None`
if the capsule was connected without an initial fetch.

<a id="wrenn.capsule.Capsule.create" />

#### create

```python theme={null}
@classmethod
def create(cls,
           template: str | None = None,
           vcpus: int | None = None,
           memory_mb: int | None = None,
           timeout: int | None = None,
           *,
           wait: bool = False,
           api_key: str | None = None,
           base_url: str | None = None) -> Capsule
```

Create a new capsule.

Equivalent to calling `Capsule(...)` directly.

**Arguments**:

* `template` *str | None* - Template name to boot from.
* `vcpus` *int | None* - Number of virtual CPUs.
* `memory_mb` *int | None* - Memory in MiB.
* `timeout` *int | None* - Inactivity TTL in seconds before auto-pause.
* `wait` *bool* - Block until the capsule reaches `running` status.
* `api_key` *str | None* - Wrenn API key. Falls back to
  `WRENN_API_KEY` env var.
* `base_url` *str | None* - API base URL override.

**Returns**:

* `Capsule` - A new capsule instance.

<a id="wrenn.capsule.Capsule.connect" />

#### connect

```python theme={null}
@classmethod
def connect(cls,
            capsule_id: str,
            *,
            api_key: str | None = None,
            base_url: str | None = None) -> Capsule
```

Connect to an existing capsule, resuming it if paused.

**Arguments**:

* `capsule_id` *str* - ID of the capsule to connect to.
* `api_key` *str | None* - Wrenn API key. Falls back to
  `WRENN_API_KEY` env var.
* `base_url` *str | None* - API base URL override.

**Returns**:

* `Capsule` - A capsule instance bound to the existing capsule.

**Raises**:

* `WrennNotFoundError` - If no capsule with the given ID exists.

<a id="wrenn.capsule.Capsule.ping" />

#### ping

```python theme={null}
def ping() -> None
```

Reset the capsule inactivity timer.

Call this to prevent the capsule from being auto-paused when the
inactivity TTL is set.

<a id="wrenn.capsule.Capsule.wait_ready" />

#### wait\_ready

```python theme={null}
def wait_ready(timeout: float = 30, interval: float = 0.5) -> None
```

Block until the capsule status is `running`.

**Arguments**:

* `timeout` *float* - Maximum seconds to wait. Defaults to `30`.
* `interval` *float* - Polling interval in seconds. Defaults to `0.5`.

**Raises**:

* `TimeoutError` - If the capsule does not reach `running` state
  within `timeout` seconds.
* `RuntimeError` - If the capsule enters an error, stopped, or paused
  state while waiting.

<a id="wrenn.capsule.Capsule.is_running" />

#### is\_running

```python theme={null}
def is_running() -> bool
```

Check whether the capsule is currently running.

Makes a live API call to fetch current status.

**Returns**:

* `bool` - `True` if the capsule status is `running`.

<a id="wrenn.capsule.Capsule.list" />

#### list

```python theme={null}
@classmethod
def list(cls,
         *,
         api_key: str | None = None,
         base_url: str | None = None) -> list[CapsuleModel]
```

List all capsules belonging to the team.

**Arguments**:

* `api_key` *str | None* - Wrenn API key. Falls back to
  `WRENN_API_KEY` env var.
* `base_url` *str | None* - API base URL override.

**Returns**:

* `list[CapsuleModel]` - All capsules for the authenticated team.

<a id="wrenn.capsule.Capsule.pty" />

#### pty

```python theme={null}
@contextmanager
def pty(cmd: str = "/bin/bash",
        args: list[str] | None = None,
        cols: int = 80,
        rows: int = 24,
        envs: dict[str, str] | None = None,
        cwd: str | None = None) -> Iterator[PtySession]
```

Open an interactive PTY session backed by a WebSocket.

Use as a context manager and iterate over :class:`PtyEvent` objects::

with capsule.pty() as term:
term.write(b"echo hello\n")
for event in term:
if event.type == "output":
print(event.data.decode())

**Arguments**:

* `cmd` *str* - Command to run inside the PTY. Defaults to
  `"/bin/bash"`.
* `args` *list\[str] | None* - Additional arguments for `cmd`.
* `cols` *int* - Initial terminal column count. Defaults to `80`.
* `rows` *int* - Initial terminal row count. Defaults to `24`.
* `envs` *dict\[str, str] | None* - Additional environment variables to
  inject into the process.
* `cwd` *str | None* - Working directory for the process.

**Yields**:

* `PtySession` - An interactive PTY session.

<a id="wrenn.capsule.Capsule.pty_connect" />

#### pty\_connect

```python theme={null}
@contextmanager
def pty_connect(tag: str) -> Iterator[PtySession]
```

Reconnect to an existing PTY session by tag.

**Arguments**:

* `tag` *str* - Session tag returned in the `started` PTY event.

**Yields**:

* `PtySession` - The reconnected PTY session.

<a id="wrenn.capsule.Capsule.get_url" />

#### get\_url

```python theme={null}
def get_url(port: int) -> str
```

Get the proxy URL for a port exposed inside this capsule.

**Arguments**:

* `port` *int* - Port number to proxy.

**Returns**:

* `str` - A `wss://` (or `ws://`) URL that proxies to the given
  port inside the capsule.

<a id="wrenn.capsule.Capsule.create_snapshot" />

#### create\_snapshot

```python theme={null}
def create_snapshot(name: str | None = None,
                    overwrite: bool = False) -> Template
```

Create a snapshot template from this capsule's current state.

**Arguments**:

* `name` *str | None* - Name for the snapshot template. Auto-generated
  if not provided.
* `overwrite` *bool* - If `True`, overwrite an existing template with
  the same name. Defaults to `False`.

**Returns**:

* `Template` - The created snapshot template.

<a id="wrenn._config" />

# wrenn.\_config

<a id="wrenn._config.ConnectionConfig" />

## ConnectionConfig Objects

```python theme={null}
@dataclass(frozen=True)
class ConnectionConfig()
```

Resolved credentials and base URL for Wrenn API calls.

<a id="wrenn._git._auth" />

# wrenn.\_git.\_auth

<a id="wrenn._git._auth.embed_credentials" />

#### embed\_credentials

```python theme={null}
def embed_credentials(url: str, username: str, password: str) -> str
```

Embed HTTP(S) credentials into a git URL.

**Arguments**:

* `url` - Git repository URL.
* `username` - Username for authentication.
* `password` - Password or personal access token.

**Returns**:

URL with `username:password@` embedded in the netloc.

**Raises**:

* `ValueError` - If the URL scheme is not `http` or `https`.

<a id="wrenn._git._auth.strip_credentials" />

#### strip\_credentials

```python theme={null}
def strip_credentials(url: str) -> str
```

Remove embedded credentials from a git URL.

**Arguments**:

* `url` - Git repository URL, possibly with credentials.

**Returns**:

URL with credentials removed. Non-HTTP(S) URLs are returned
unchanged.

<a id="wrenn._git._auth.is_auth_error" />

#### is\_auth\_error

```python theme={null}
def is_auth_error(stderr: str) -> bool
```

Check whether git stderr indicates an authentication failure.

**Arguments**:

* `stderr` - Combined stderr output from a git command.

**Returns**:

`True` if any known auth-failure pattern is found.

<a id="wrenn._git._auth.build_credential_approve_cmd" />

#### build\_credential\_approve\_cmd

```python theme={null}
def build_credential_approve_cmd(username: str,
                                 password: str,
                                 host: str = "github.com",
                                 protocol: str = "https") -> str
```

Build a shell command that pipes credentials into `git credential approve`.

**Arguments**:

* `username` - Git username.
* `password` - Password or personal access token.
* `host` - Target host. Defaults to `"github.com"`.
* `protocol` - Protocol. Defaults to `"https"`.

**Returns**:

A shell command string safe to pass to `commands.run()`.

<a id="wrenn._git._cmd" />

# wrenn.\_git.\_cmd

Pure functions that build git argument lists and parse git output.

No I/O, no network, no imports from `wrenn`. Every `build_*` function
returns a `list[str]` suitable for `shlex.join()`.  Every `parse_*`
function takes raw stdout and returns a typed structure.

<a id="wrenn._git._cmd.FileStatus" />

## FileStatus Objects

```python theme={null}
@dataclass
class FileStatus()
```

A single entry from `git status --porcelain=v1`.

**Attributes**:

* `path` *str* - File path relative to the repository root.
* `index_status` *str* - Index (staged) status character.
* `work_tree_status` *str* - Working-tree status character.
* `renamed_from` *str | None* - Original path when status is a rename.

<a id="wrenn._git._cmd.FileStatus.staged" />

#### staged

```python theme={null}
@property
def staged() -> bool
```

Whether the change is staged in the index.

<a id="wrenn._git._cmd.FileStatus.status" />

#### status

```python theme={null}
@property
def status() -> str
```

Normalized human-readable status label.

<a id="wrenn._git._cmd.GitStatus" />

## GitStatus Objects

```python theme={null}
@dataclass
class GitStatus()
```

Parsed output of `git status --porcelain=v1 --branch`.

**Attributes**:

* `branch` *str | None* - Current branch name, or `None` if detached.
* `upstream` *str | None* - Upstream tracking branch.
* `ahead` *int* - Commits ahead of upstream.
* `behind` *int* - Commits behind upstream.
* `detached` *bool* - Whether HEAD is detached.
* `files` *list\[FileStatus]* - Per-file status entries.

<a id="wrenn._git._cmd.GitStatus.is_clean" />

#### is\_clean

```python theme={null}
@property
def is_clean() -> bool
```

`True` when there are no changed or untracked files.

<a id="wrenn._git._cmd.GitStatus.has_staged" />

#### has\_staged

```python theme={null}
@property
def has_staged() -> bool
```

`True` when at least one file has staged changes.

<a id="wrenn._git._cmd.GitStatus.has_untracked" />

#### has\_untracked

```python theme={null}
@property
def has_untracked() -> bool
```

`True` when at least one file is untracked.

<a id="wrenn._git._cmd.GitStatus.has_conflicts" />

#### has\_conflicts

```python theme={null}
@property
def has_conflicts() -> bool
```

`True` when at least one file has merge conflicts.

<a id="wrenn._git._cmd.GitBranch" />

## GitBranch Objects

```python theme={null}
@dataclass
class GitBranch()
```

A single branch entry.

**Attributes**:

* `name` *str* - Branch name (short ref).
* `is_current` *bool* - Whether this is the checked-out branch.

<a id="wrenn._git._cmd.build_clone" />

#### build\_clone

```python theme={null}
def build_clone(url: str,
                dest: str | None = None,
                *,
                branch: str | None = None,
                depth: int | None = None) -> list[str]
```

Build `git clone` arguments.

<a id="wrenn._git._cmd.build_init" />

#### build\_init

```python theme={null}
def build_init(path: str = ".",
               *,
               bare: bool = False,
               initial_branch: str | None = None) -> list[str]
```

Build `git init` arguments.

<a id="wrenn._git._cmd.build_add" />

#### build\_add

```python theme={null}
def build_add(paths: list[str] | None = None,
              *,
              all: bool = False) -> list[str]
```

Build `git add` arguments.

<a id="wrenn._git._cmd.build_commit" />

#### build\_commit

```python theme={null}
def build_commit(message: str,
                 *,
                 allow_empty: bool = False,
                 author_name: str | None = None,
                 author_email: str | None = None) -> list[str]
```

Build `git commit` arguments.

<a id="wrenn._git._cmd.build_push" />

#### build\_push

```python theme={null}
def build_push(remote: str = "origin",
               branch: str | None = None,
               *,
               force: bool = False,
               set_upstream: bool = False) -> list[str]
```

Build `git push` arguments.

<a id="wrenn._git._cmd.build_pull" />

#### build\_pull

```python theme={null}
def build_pull(remote: str = "origin",
               branch: str | None = None,
               *,
               rebase: bool = False,
               ff_only: bool = False) -> list[str]
```

Build `git pull` arguments.

<a id="wrenn._git._cmd.build_status" />

#### build\_status

```python theme={null}
def build_status() -> list[str]
```

Build `git status` arguments for porcelain parsing.

<a id="wrenn._git._cmd.build_branches" />

#### build\_branches

```python theme={null}
def build_branches() -> list[str]
```

Build `git branch` arguments for structured parsing.

<a id="wrenn._git._cmd.build_create_branch" />

#### build\_create\_branch

```python theme={null}
def build_create_branch(name: str,
                        *,
                        start_point: str | None = None) -> list[str]
```

Build `git checkout -b` arguments.

<a id="wrenn._git._cmd.build_checkout" />

#### build\_checkout

```python theme={null}
def build_checkout(name: str) -> list[str]
```

Build `git checkout` arguments.

<a id="wrenn._git._cmd.build_delete_branch" />

#### build\_delete\_branch

```python theme={null}
def build_delete_branch(name: str, *, force: bool = False) -> list[str]
```

Build `git branch -d/-D` arguments.

<a id="wrenn._git._cmd.build_remote_add" />

#### build\_remote\_add

```python theme={null}
def build_remote_add(name: str, url: str, *, fetch: bool = False) -> list[str]
```

Build `git remote add` arguments.

<a id="wrenn._git._cmd.build_remote_get_url" />

#### build\_remote\_get\_url

```python theme={null}
def build_remote_get_url(name: str = "origin") -> list[str]
```

Build `git remote get-url` arguments.

<a id="wrenn._git._cmd.build_remote_set_url" />

#### build\_remote\_set\_url

```python theme={null}
def build_remote_set_url(name: str, url: str) -> list[str]
```

Build `git remote set-url` arguments.

<a id="wrenn._git._cmd.build_reset" />

#### build\_reset

```python theme={null}
def build_reset(*,
                mode: str | None = None,
                ref: str | None = None,
                paths: list[str] | None = None) -> list[str]
```

Build `git reset` arguments.

**Arguments**:

* `mode` - Reset mode (`soft`, `mixed`, `hard`, `merge`, `keep`).
* `ref` - Commit, branch, or ref to reset to.
* `paths` - Paths to reset (mutually exclusive with `mode`).

<a id="wrenn._git._cmd.build_restore" />

#### build\_restore

```python theme={null}
def build_restore(paths: list[str],
                  *,
                  staged: bool = False,
                  worktree: bool = False,
                  source: str | None = None) -> list[str]
```

Build `git restore` arguments.

**Arguments**:

* `paths` - Paths to restore.
* `staged` - Restore the index (unstage).
* `worktree` - Restore working-tree files.
* `source` - Commit or ref to restore from.

<a id="wrenn._git._cmd.build_config_set" />

#### build\_config\_set

```python theme={null}
def build_config_set(key: str,
                     value: str,
                     *,
                     scope: str = "local",
                     repo_path: str | None = None) -> list[str]
```

Build `git config` set arguments.

<a id="wrenn._git._cmd.build_config_get" />

#### build\_config\_get

```python theme={null}
def build_config_get(key: str,
                     *,
                     scope: str = "local",
                     repo_path: str | None = None) -> list[str]
```

Build `git config --get` arguments.

<a id="wrenn._git._cmd.build_has_upstream" />

#### build\_has\_upstream

```python theme={null}
def build_has_upstream() -> list[str]
```

Build arguments to check if current branch has upstream tracking.

<a id="wrenn._git._cmd.parse_status" />

#### parse\_status

```python theme={null}
def parse_status(stdout: str) -> GitStatus
```

Parse `git status --porcelain=v1 --branch` output.

**Arguments**:

* `stdout` - Raw stdout from the git status command.

**Returns**:

Parsed :class:`GitStatus`.

<a id="wrenn._git._cmd.parse_branches" />

#### parse\_branches

```python theme={null}
def parse_branches(stdout: str) -> list[GitBranch]
```

Parse `git branch --format=%(refname:short)\t%(HEAD)` output.

**Arguments**:

* `stdout` - Raw stdout from the git branch command.

**Returns**:

List of :class:`GitBranch`.

<a id="wrenn._git.exceptions" />

# wrenn.\_git.exceptions

<a id="wrenn._git.exceptions.GitError" />

## GitError Objects

```python theme={null}
class GitError(Exception)
```

Base exception for all git operations inside a capsule.

Not a subclass of :class:`WrennError` because git errors originate
from a process exit code, not an HTTP response.

**Attributes**:

* `message` *str* - Human-readable error description.
* `stderr` *str* - Raw stderr output from the git process.
* `exit_code` *int* - Process exit code.

<a id="wrenn._git.exceptions.GitCommandError" />

## GitCommandError Objects

```python theme={null}
class GitCommandError(GitError)
```

A git command exited with a non-zero exit code.

<a id="wrenn._git.exceptions.GitAuthError" />

## GitAuthError Objects

```python theme={null}
class GitAuthError(GitError)
```

Authentication failed when communicating with a remote.

<a id="wrenn._git" />

# wrenn.\_git

Git operations inside a Wrenn capsule.

Provides :class:`Git` (sync) and :class:`AsyncGit` (async) interfaces
accessed via `capsule.git`.  All operations execute the real `git`
binary inside the capsule through :class:`~wrenn.commands.Commands`.

<a id="wrenn._git.Git" />

## Git Objects

```python theme={null}
class Git()
```

Sync git interface. Accessed via `capsule.git`.

Executes the real `git` binary inside the capsule through
:meth:`Commands.run`. Methods raise :class:`GitCommandError` (or
:class:`GitAuthError`) on non-zero exit codes.

<a id="wrenn._git.Git.clone" />

#### clone

```python theme={null}
def clone(url: str,
          dest: str | None = None,
          *,
          branch: str | None = None,
          depth: int | None = None,
          username: str | None = None,
          password: str | None = None,
          dangerously_store_credentials: bool = False,
          cwd: str | None = None,
          envs: dict[str, str] | None = None,
          timeout: int | None = 300) -> CommandResult
```

Clone a remote repository into the capsule.

**Arguments**:

* `url` - Remote repository URL.
* `dest` - Destination path. Defaults to the repository name
  derived from the URL.
* `branch` - Branch or tag to check out.
* `depth` - Create a shallow clone with this many commits.
* `username` - Username for HTTP(S) authentication.
* `password` - Password or token for HTTP(S) authentication.
* `dangerously_store_credentials` - If `True`, leave credentials
  embedded in the remote URL after cloning.
* `cwd` - Working directory for the command.
* `envs` - Extra environment variables.
* `timeout` - Command timeout in seconds. Defaults to `300`.

**Returns**:

Command result with stdout, stderr, exit\_code, and duration.

**Raises**:

* `GitAuthError` - If the remote rejected authentication.
* `GitCommandError` - If clone failed for another reason.
* `ValueError` - If *password* is provided without *username*.

<a id="wrenn._git.Git.init" />

#### init

```python theme={null}
def init(path: str = ".",
         *,
         bare: bool = False,
         initial_branch: str | None = None,
         cwd: str | None = None,
         envs: dict[str, str] | None = None,
         timeout: int | None = 30) -> CommandResult
```

Initialize a new git repository.

**Arguments**:

* `path` - Destination path for the repository.
* `bare` - Create a bare repository.
* `initial_branch` - Name for the initial branch (e.g. `"main"`).
* `cwd` - Working directory for the command.
* `envs` - Extra environment variables.
* `timeout` - Command timeout in seconds.

**Returns**:

Command result.

**Raises**:

* `GitCommandError` - If init failed.

<a id="wrenn._git.Git.add" />

#### add

```python theme={null}
def add(paths: list[str] | None = None,
        *,
        all: bool = False,
        cwd: str | None = None,
        envs: dict[str, str] | None = None,
        timeout: int | None = 30) -> CommandResult
```

Stage files for commit.

**Arguments**:

* `paths` - Specific files to stage. If `None`, stages the
  current directory (or all with `all=True`).
* `all` - Stage all changes including untracked files.
* `cwd` - Working directory (repository root).
* `envs` - Extra environment variables.
* `timeout` - Command timeout in seconds.

**Returns**:

Command result.

**Raises**:

* `GitCommandError` - If add failed.

<a id="wrenn._git.Git.commit" />

#### commit

```python theme={null}
def commit(message: str,
           *,
           allow_empty: bool = False,
           author_name: str | None = None,
           author_email: str | None = None,
           cwd: str | None = None,
           envs: dict[str, str] | None = None,
           timeout: int | None = 30) -> CommandResult
```

Create a commit.

**Arguments**:

* `message` - Commit message.
* `allow_empty` - Allow creating a commit with no changes.
* `author_name` - Override the commit author name.
* `author_email` - Override the commit author email.
* `cwd` - Working directory (repository root).
* `envs` - Extra environment variables.
* `timeout` - Command timeout in seconds.

**Returns**:

Command result.

**Raises**:

* `GitCommandError` - If commit failed.

<a id="wrenn._git.Git.push" />

#### push

```python theme={null}
def push(remote: str = "origin",
         branch: str | None = None,
         *,
         force: bool = False,
         set_upstream: bool = False,
         username: str | None = None,
         password: str | None = None,
         cwd: str | None = None,
         envs: dict[str, str] | None = None,
         timeout: int | None = 60) -> CommandResult
```

Push commits to a remote.

**Arguments**:

* `remote` - Remote name. Defaults to `"origin"`.
* `branch` - Branch to push. Defaults to the current branch.
* `force` - Force-push.
* `set_upstream` - Set upstream tracking reference.
* `username` - Username for HTTP(S) authentication.
* `password` - Password or token for HTTP(S) authentication.
* `cwd` - Working directory (repository root).
* `envs` - Extra environment variables.
* `timeout` - Command timeout in seconds.

**Returns**:

Command result.

**Raises**:

* `GitAuthError` - If authentication failed.
* `GitCommandError` - If push failed.

<a id="wrenn._git.Git.pull" />

#### pull

```python theme={null}
def pull(remote: str = "origin",
         branch: str | None = None,
         *,
         rebase: bool = False,
         ff_only: bool = False,
         username: str | None = None,
         password: str | None = None,
         cwd: str | None = None,
         envs: dict[str, str] | None = None,
         timeout: int | None = 60) -> CommandResult
```

Pull changes from a remote.

**Arguments**:

* `remote` - Remote name. Defaults to `"origin"`.
* `branch` - Branch to pull.
* `rebase` - Rebase instead of merge.
* `ff_only` - Only allow fast-forward merges.
* `username` - Username for HTTP(S) authentication.
* `password` - Password or token for HTTP(S) authentication.
* `cwd` - Working directory (repository root).
* `envs` - Extra environment variables.
* `timeout` - Command timeout in seconds.

**Returns**:

Command result.

**Raises**:

* `GitAuthError` - If authentication failed.
* `GitCommandError` - If pull failed.

<a id="wrenn._git.Git.status" />

#### status

```python theme={null}
def status(*,
           cwd: str | None = None,
           envs: dict[str, str] | None = None,
           timeout: int | None = 30) -> GitStatus
```

Get repository status.

**Arguments**:

* `cwd` - Working directory (repository root).
* `envs` - Extra environment variables.
* `timeout` - Command timeout in seconds.

**Returns**:

Parsed :class:`GitStatus` with branch info and file changes.

**Raises**:

* `GitCommandError` - If the command failed.

<a id="wrenn._git.Git.branches" />

#### branches

```python theme={null}
def branches(*,
             cwd: str | None = None,
             envs: dict[str, str] | None = None,
             timeout: int | None = 30) -> list[GitBranch]
```

List local branches.

**Arguments**:

* `cwd` - Working directory (repository root).
* `envs` - Extra environment variables.
* `timeout` - Command timeout in seconds.

**Returns**:

List of :class:`GitBranch`.

**Raises**:

* `GitCommandError` - If the command failed.

<a id="wrenn._git.Git.create_branch" />

#### create\_branch

```python theme={null}
def create_branch(name: str,
                  *,
                  start_point: str | None = None,
                  cwd: str | None = None,
                  envs: dict[str, str] | None = None,
                  timeout: int | None = 30) -> CommandResult
```

Create and check out a new branch.

**Arguments**:

* `name` - Branch name.
* `start_point` - Commit or ref to branch from.
* `cwd` - Working directory (repository root).
* `envs` - Extra environment variables.
* `timeout` - Command timeout in seconds.

**Returns**:

Command result.

**Raises**:

* `GitCommandError` - If the command failed.

<a id="wrenn._git.Git.checkout_branch" />

#### checkout\_branch

```python theme={null}
def checkout_branch(name: str,
                    *,
                    cwd: str | None = None,
                    envs: dict[str, str] | None = None,
                    timeout: int | None = 30) -> CommandResult
```

Check out an existing branch.

**Arguments**:

* `name` - Branch name.
* `cwd` - Working directory (repository root).
* `envs` - Extra environment variables.
* `timeout` - Command timeout in seconds.

**Returns**:

Command result.

**Raises**:

* `GitCommandError` - If the command failed.

<a id="wrenn._git.Git.delete_branch" />

#### delete\_branch

```python theme={null}
def delete_branch(name: str,
                  *,
                  force: bool = False,
                  cwd: str | None = None,
                  envs: dict[str, str] | None = None,
                  timeout: int | None = 30) -> CommandResult
```

Delete a branch.

**Arguments**:

* `name` - Branch name.
* `force` - Force-delete with `-D`.
* `cwd` - Working directory (repository root).
* `envs` - Extra environment variables.
* `timeout` - Command timeout in seconds.

**Returns**:

Command result.

**Raises**:

* `GitCommandError` - If the command failed.

<a id="wrenn._git.Git.remote_add" />

#### remote\_add

```python theme={null}
def remote_add(name: str,
               url: str,
               *,
               fetch: bool = False,
               cwd: str | None = None,
               envs: dict[str, str] | None = None,
               timeout: int | None = 30) -> CommandResult
```

Add a remote.

**Arguments**:

* `name` - Remote name (e.g. `"origin"`).
* `url` - Remote URL.
* `fetch` - Fetch after adding.
* `cwd` - Working directory (repository root).
* `envs` - Extra environment variables.
* `timeout` - Command timeout in seconds.

**Returns**:

Command result.

**Raises**:

* `GitCommandError` - If the command failed.

<a id="wrenn._git.Git.remote_get" />

#### remote\_get

```python theme={null}
def remote_get(name: str = "origin",
               *,
               cwd: str | None = None,
               envs: dict[str, str] | None = None,
               timeout: int | None = 30) -> str | None
```

Get the URL of a remote.

Returns `None` if the remote does not exist rather than raising.

**Arguments**:

* `name` - Remote name. Defaults to `"origin"`.
* `cwd` - Working directory (repository root).
* `envs` - Extra environment variables.
* `timeout` - Command timeout in seconds.

**Returns**:

Remote URL or `None`.

<a id="wrenn._git.Git.reset" />

#### reset

```python theme={null}
def reset(*,
          mode: str | None = None,
          ref: str | None = None,
          paths: list[str] | None = None,
          cwd: str | None = None,
          envs: dict[str, str] | None = None,
          timeout: int | None = 30) -> CommandResult
```

Reset the current HEAD.

**Arguments**:

* `mode` - Reset mode (`soft`, `mixed`, `hard`, `merge`,
  `keep`).
* `ref` - Commit, branch, or ref to reset to.
* `paths` - Paths to reset.
* `cwd` - Working directory (repository root).
* `envs` - Extra environment variables.
* `timeout` - Command timeout in seconds.

**Returns**:

Command result.

**Raises**:

* `GitCommandError` - If the command failed.

<a id="wrenn._git.Git.restore" />

#### restore

```python theme={null}
def restore(paths: list[str],
            *,
            staged: bool = False,
            worktree: bool = False,
            source: str | None = None,
            cwd: str | None = None,
            envs: dict[str, str] | None = None,
            timeout: int | None = 30) -> CommandResult
```

Restore working-tree files or unstage changes.

**Arguments**:

* `paths` - Paths to restore.
* `staged` - Restore the index (unstage).
* `worktree` - Restore working-tree files.
* `source` - Commit or ref to restore from.
* `cwd` - Working directory (repository root).
* `envs` - Extra environment variables.
* `timeout` - Command timeout in seconds.

**Returns**:

Command result.

**Raises**:

* `GitCommandError` - If the command failed.

<a id="wrenn._git.Git.set_config" />

#### set\_config

```python theme={null}
def set_config(key: str,
               value: str,
               *,
               scope: str = "local",
               cwd: str | None = None,
               envs: dict[str, str] | None = None,
               timeout: int | None = 30) -> CommandResult
```

Set a git config value.

**Arguments**:

* `key` - Config key (e.g. `"user.name"`).
* `value` - Config value.
* `scope` - Config scope: `"local"`, `"global"`, or
  `"system"`.
* `cwd` - Working directory (repository root). Required when
  scope is `"local"`.
* `envs` - Extra environment variables.
* `timeout` - Command timeout in seconds.

**Returns**:

Command result.

**Raises**:

* `GitCommandError` - If the command failed.

<a id="wrenn._git.Git.get_config" />

#### get\_config

```python theme={null}
def get_config(key: str,
               *,
               scope: str = "local",
               cwd: str | None = None,
               envs: dict[str, str] | None = None,
               timeout: int | None = 30) -> str | None
```

Get a git config value.

Returns `None` if the key is not set rather than raising.

**Arguments**:

* `key` - Config key (e.g. `"user.name"`).
* `scope` - Config scope: `"local"`, `"global"`, or
  `"system"`.
* `cwd` - Working directory (repository root). Required when
  scope is `"local"`.
* `envs` - Extra environment variables.
* `timeout` - Command timeout in seconds.

**Returns**:

Config value or `None`.

<a id="wrenn._git.Git.configure_user" />

#### configure\_user

```python theme={null}
def configure_user(name: str,
                   email: str,
                   *,
                   scope: str = "global",
                   cwd: str | None = None,
                   envs: dict[str, str] | None = None,
                   timeout: int | None = 30) -> None
```

Configure git user name and email.

**Arguments**:

* `name` - Git user name.
* `email` - Git user email.
* `scope` - Config scope. Defaults to `"global"`.
* `cwd` - Working directory (repository root). Required when
  scope is `"local"`.
* `envs` - Extra environment variables.
* `timeout` - Command timeout in seconds.

**Raises**:

* `ValueError` - If *name* or *email* is empty.
* `GitCommandError` - If a config command failed.

<a id="wrenn._git.Git.dangerously_authenticate" />

#### dangerously\_authenticate

```python theme={null}
def dangerously_authenticate(username: str,
                             password: str,
                             host: str = "github.com",
                             protocol: str = "https",
                             *,
                             cwd: str | None = None,
                             envs: dict[str, str] | None = None,
                             timeout: int | None = 30) -> None
```

Persist git credentials via the credential store.

.. warning::

Credentials are written in plain text to the capsule
filesystem and are accessible to any process running inside
the capsule.  Prefer per-operation `username`/`password`
parameters on :meth:`clone`, :meth:`push`, and :meth:`pull`
instead.

**Arguments**:

* `username` - Git username.
* `password` - Password or personal access token.
* `host` - Target host. Defaults to `"github.com"`.
* `protocol` - Protocol. Defaults to `"https"`.
* `cwd` - Working directory.
* `envs` - Extra environment variables.
* `timeout` - Command timeout in seconds.

**Raises**:

* `ValueError` - If *username* or *password* is empty.
* `GitCommandError` - If a command failed.

<a id="wrenn._git.AsyncGit" />

## AsyncGit Objects

```python theme={null}
class AsyncGit()
```

Async git interface. Accessed via `capsule.git`.

Async mirror of :class:`Git`. See that class for full method
documentation.

<a id="wrenn._git.AsyncGit.clone" />

#### clone

```python theme={null}
async def clone(url: str,
                dest: str | None = None,
                *,
                branch: str | None = None,
                depth: int | None = None,
                username: str | None = None,
                password: str | None = None,
                dangerously_store_credentials: bool = False,
                cwd: str | None = None,
                envs: dict[str, str] | None = None,
                timeout: int | None = 300) -> CommandResult
```

Clone a remote repository into the capsule.

<a id="wrenn._git.AsyncGit.init" />

#### init

```python theme={null}
async def init(path: str = ".",
               *,
               bare: bool = False,
               initial_branch: str | None = None,
               cwd: str | None = None,
               envs: dict[str, str] | None = None,
               timeout: int | None = 30) -> CommandResult
```

Initialize a new git repository.

<a id="wrenn._git.AsyncGit.add" />

#### add

```python theme={null}
async def add(paths: list[str] | None = None,
              *,
              all: bool = False,
              cwd: str | None = None,
              envs: dict[str, str] | None = None,
              timeout: int | None = 30) -> CommandResult
```

Stage files for commit.

<a id="wrenn._git.AsyncGit.commit" />

#### commit

```python theme={null}
async def commit(message: str,
                 *,
                 allow_empty: bool = False,
                 author_name: str | None = None,
                 author_email: str | None = None,
                 cwd: str | None = None,
                 envs: dict[str, str] | None = None,
                 timeout: int | None = 30) -> CommandResult
```

Create a commit.

<a id="wrenn._git.AsyncGit.push" />

#### push

```python theme={null}
async def push(remote: str = "origin",
               branch: str | None = None,
               *,
               force: bool = False,
               set_upstream: bool = False,
               username: str | None = None,
               password: str | None = None,
               cwd: str | None = None,
               envs: dict[str, str] | None = None,
               timeout: int | None = 60) -> CommandResult
```

Push commits to a remote.

<a id="wrenn._git.AsyncGit.pull" />

#### pull

```python theme={null}
async def pull(remote: str = "origin",
               branch: str | None = None,
               *,
               rebase: bool = False,
               ff_only: bool = False,
               username: str | None = None,
               password: str | None = None,
               cwd: str | None = None,
               envs: dict[str, str] | None = None,
               timeout: int | None = 60) -> CommandResult
```

Pull changes from a remote.

<a id="wrenn._git.AsyncGit.status" />

#### status

```python theme={null}
async def status(*,
                 cwd: str | None = None,
                 envs: dict[str, str] | None = None,
                 timeout: int | None = 30) -> GitStatus
```

Get repository status.

<a id="wrenn._git.AsyncGit.branches" />

#### branches

```python theme={null}
async def branches(*,
                   cwd: str | None = None,
                   envs: dict[str, str] | None = None,
                   timeout: int | None = 30) -> list[GitBranch]
```

List local branches.

<a id="wrenn._git.AsyncGit.create_branch" />

#### create\_branch

```python theme={null}
async def create_branch(name: str,
                        *,
                        start_point: str | None = None,
                        cwd: str | None = None,
                        envs: dict[str, str] | None = None,
                        timeout: int | None = 30) -> CommandResult
```

Create and check out a new branch.

<a id="wrenn._git.AsyncGit.checkout_branch" />

#### checkout\_branch

```python theme={null}
async def checkout_branch(name: str,
                          *,
                          cwd: str | None = None,
                          envs: dict[str, str] | None = None,
                          timeout: int | None = 30) -> CommandResult
```

Check out an existing branch.

<a id="wrenn._git.AsyncGit.delete_branch" />

#### delete\_branch

```python theme={null}
async def delete_branch(name: str,
                        *,
                        force: bool = False,
                        cwd: str | None = None,
                        envs: dict[str, str] | None = None,
                        timeout: int | None = 30) -> CommandResult
```

Delete a branch.

<a id="wrenn._git.AsyncGit.remote_add" />

#### remote\_add

```python theme={null}
async def remote_add(name: str,
                     url: str,
                     *,
                     fetch: bool = False,
                     cwd: str | None = None,
                     envs: dict[str, str] | None = None,
                     timeout: int | None = 30) -> CommandResult
```

Add a remote.

<a id="wrenn._git.AsyncGit.remote_get" />

#### remote\_get

```python theme={null}
async def remote_get(name: str = "origin",
                     *,
                     cwd: str | None = None,
                     envs: dict[str, str] | None = None,
                     timeout: int | None = 30) -> str | None
```

Get the URL of a remote. Returns `None` if not found.

<a id="wrenn._git.AsyncGit.reset" />

#### reset

```python theme={null}
async def reset(*,
                mode: str | None = None,
                ref: str | None = None,
                paths: list[str] | None = None,
                cwd: str | None = None,
                envs: dict[str, str] | None = None,
                timeout: int | None = 30) -> CommandResult
```

Reset the current HEAD.

<a id="wrenn._git.AsyncGit.restore" />

#### restore

```python theme={null}
async def restore(paths: list[str],
                  *,
                  staged: bool = False,
                  worktree: bool = False,
                  source: str | None = None,
                  cwd: str | None = None,
                  envs: dict[str, str] | None = None,
                  timeout: int | None = 30) -> CommandResult
```

Restore working-tree files or unstage changes.

<a id="wrenn._git.AsyncGit.set_config" />

#### set\_config

```python theme={null}
async def set_config(key: str,
                     value: str,
                     *,
                     scope: str = "local",
                     cwd: str | None = None,
                     envs: dict[str, str] | None = None,
                     timeout: int | None = 30) -> CommandResult
```

Set a git config value.

<a id="wrenn._git.AsyncGit.get_config" />

#### get\_config

```python theme={null}
async def get_config(key: str,
                     *,
                     scope: str = "local",
                     cwd: str | None = None,
                     envs: dict[str, str] | None = None,
                     timeout: int | None = 30) -> str | None
```

Get a git config value. Returns `None` if not set.

<a id="wrenn._git.AsyncGit.configure_user" />

#### configure\_user

```python theme={null}
async def configure_user(name: str,
                         email: str,
                         *,
                         scope: str = "global",
                         cwd: str | None = None,
                         envs: dict[str, str] | None = None,
                         timeout: int | None = 30) -> None
```

Configure git user name and email.

<a id="wrenn._git.AsyncGit.dangerously_authenticate" />

#### dangerously\_authenticate

```python theme={null}
async def dangerously_authenticate(username: str,
                                   password: str,
                                   host: str = "github.com",
                                   protocol: str = "https",
                                   *,
                                   cwd: str | None = None,
                                   envs: dict[str, str] | None = None,
                                   timeout: int | None = 30) -> None
```

Persist git credentials via the credential store.

.. warning::

Credentials are written in plain text to the capsule
filesystem.  Prefer per-operation `username`/`password`
parameters instead.
