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

# Box Types

> Python SDK box types and configuration

BoxLite provides several specialized box types, each designed for specific use cases. All box types support both async context managers (`async with`) and explicit lifecycle management.

## SimpleBox

Context manager for basic command execution with automatic cleanup.

```python theme={null}
from boxlite import SimpleBox
```

### Constructor

```python theme={null}
SimpleBox(
    image: str = None,
    rootfs_path: str = None,
    memory_mib: int = None,
    cpus: int = None,
    runtime: Boxlite = None,
    name: str = None,
    auto_remove: bool = True,
    reuse_existing: bool = False,
    **kwargs
)
```

| Parameter        | Type      | Default        | Description                                                                            |
| ---------------- | --------- | -------------- | -------------------------------------------------------------------------------------- |
| `image`          | `str`     | None           | Container image to use (e.g., `"python:slim"`)                                         |
| `rootfs_path`    | `str`     | None           | Path to local OCI layout directory (alternative to `image`)                            |
| `memory_mib`     | `int`     | System default | Memory limit in MiB                                                                    |
| `cpus`           | `int`     | System default | Number of CPU cores                                                                    |
| `runtime`        | `Boxlite` | Global default | Runtime instance                                                                       |
| `name`           | `str`     | None           | Optional unique name                                                                   |
| `auto_remove`    | `bool`    | `True`         | Remove box when stopped                                                                |
| `reuse_existing` | `bool`    | `False`        | If `True` and a box with the given `name` exists, reuse it instead of raising an error |
| `**kwargs`       |           |                | Additional options: `env`, `volumes`, `ports`, `working_dir`                           |

<Note>
  Either `image` or `rootfs_path` must be provided. If both are given, `rootfs_path` takes precedence.
</Note>

### Properties

| Property  | Type           | Description                                                                                   |
| --------- | -------------- | --------------------------------------------------------------------------------------------- |
| `id`      | `str`          | Box ID (raises if not started)                                                                |
| `created` | `bool \| None` | `True` if newly created, `False` if reused (via `reuse_existing`). `None` if not started yet. |

### Methods

| Method       | Signature                                                                                            | Description                                     |
| ------------ | ---------------------------------------------------------------------------------------------------- | ----------------------------------------------- |
| `start()`    | `() -> Self`                                                                                         | Explicitly start the box (async)                |
| `exec()`     | `(cmd, *args, env=None) -> ExecResult`                                                               | Execute command and wait (async)                |
| `info()`     | `() -> BoxInfo`                                                                                      | Get box metadata                                |
| `shutdown()` | `() -> None`                                                                                         | Shutdown and release resources                  |
| `copy_in()`  | `(host_path, container_dest, *, overwrite=True, follow_symlinks=False, include_parent=True) -> None` | Copy files from host into the container (async) |
| `copy_out()` | `(container_src, host_dest, *, overwrite=True, follow_symlinks=False, include_parent=True) -> None`  | Copy files from container to host (async)       |

### Example

```python theme={null}
async with SimpleBox(image="python:slim") as box:
    result = await box.exec("python", "-c", "print('Hello!')")
    print(result.stdout)   # "Hello!\n"
    print(result.exit_code)  # 0
```

## CodeBox

Specialized box for Python code execution with package management.

```python theme={null}
from boxlite import CodeBox
```

### Constructor

```python theme={null}
CodeBox(
    image: str = "python:slim",
    memory_mib: int = None,
    cpus: int = None,
    runtime: Boxlite = None,
    **kwargs
)
```

### Methods

| Method               | Signature                                 | Description                        |
| -------------------- | ----------------------------------------- | ---------------------------------- |
| `run()`              | `(code: str, timeout: int = None) -> str` | Execute Python code (async)        |
| `run_script()`       | `(script_path: str) -> str`               | Execute Python script file (async) |
| `install_package()`  | `(package: str) -> str`                   | Install package with pip (async)   |
| `install_packages()` | `(*packages: str) -> str`                 | Install multiple packages (async)  |

### Example

```python theme={null}
async with CodeBox() as cb:
    # Install packages
    await cb.install_package("requests")

    # Run code
    result = await cb.run("""
import requests
print(requests.get('https://api.github.com/zen').text)
""")
    print(result)
```

## BrowserBox

Box configured for browser automation with Chrome DevTools Protocol.

```python theme={null}
from boxlite import BrowserBox, BrowserBoxOptions
```

### `BrowserBoxOptions`

| Field     | Type  | Default      | Description                                         |
| --------- | ----- | ------------ | --------------------------------------------------- |
| `browser` | `str` | `"chromium"` | Browser type: `"chromium"`, `"firefox"`, `"webkit"` |
| `memory`  | `int` | `2048`       | Memory in MiB                                       |
| `cpu`     | `int` | `2`          | Number of CPU cores                                 |

### Default image

All browser types use a single Playwright image: `mcr.microsoft.com/playwright:v1.58.0-jammy`

The Playwright Server listens on port **3000**. The CDP endpoint (for Puppeteer) is on port **9222**.

### Properties

| Property  | Type  | Description                                                 |
| --------- | ----- | ----------------------------------------------------------- |
| `browser` | `str` | The browser type (`"chromium"`, `"firefox"`, or `"webkit"`) |

### Methods

| Method                  | Signature                        | Description                                                                                |
| ----------------------- | -------------------------------- | ------------------------------------------------------------------------------------------ |
| `endpoint()`            | `(timeout: int = 60) -> str`     | Get CDP endpoint URL for Puppeteer (async)                                                 |
| `playwright_endpoint()` | `(timeout: int = 60) -> str`     | Get WebSocket endpoint URL for Playwright (async)                                          |
| `connect()`             | `(timeout: int = 60) -> Browser` | Connect and return a Playwright Browser instance (async). Requires `playwright` installed. |

### Example

```python theme={null}
from boxlite import BrowserBox, BrowserBoxOptions

opts = BrowserBoxOptions(browser="chromium", memory=4096)
async with BrowserBox(opts) as browser:
    # Option 1: Use with Playwright (recommended)
    pw_browser = await browser.connect()
    page = await pw_browser.new_page()
    await page.goto("https://example.com")

    # Option 2: Get endpoints manually
    ws = await browser.playwright_endpoint()   # "ws://localhost:3000/"
    cdp = await browser.endpoint()             # "ws://localhost:3000/..."
```

## ComputerBox

Box with full desktop environment and GUI automation capabilities. Uses the `lscr.io/linuxserver/webtop:ubuntu-xfce` image by default.

```python theme={null}
from boxlite import ComputerBox
```

### Constructor

```python theme={null}
ComputerBox(
    cpu: int = 2,
    memory: int = 2048,
    gui_http_port: int = 3000,
    gui_https_port: int = 3001,
    runtime: Boxlite = None,
    **kwargs
)
```

### Mouse Methods

| Method              | Signature                                  | Description                              |
| ------------------- | ------------------------------------------ | ---------------------------------------- |
| `mouse_move()`      | `(x: int, y: int) -> None`                 | Move cursor to coordinates (async)       |
| `left_click()`      | `() -> None`                               | Left click at current position (async)   |
| `right_click()`     | `() -> None`                               | Right click at current position (async)  |
| `middle_click()`    | `() -> None`                               | Middle click at current position (async) |
| `double_click()`    | `() -> None`                               | Double left click (async)                |
| `triple_click()`    | `() -> None`                               | Triple left click (async)                |
| `left_click_drag()` | `(start_x, start_y, end_x, end_y) -> None` | Drag from start to end (async)           |
| `cursor_position()` | `() -> Tuple[int, int]`                    | Get current cursor (x, y) (async)        |

### Keyboard Methods

| Method   | Signature             | Description                          |
| -------- | --------------------- | ------------------------------------ |
| `type()` | `(text: str) -> None` | Type text characters (async)         |
| `key()`  | `(text: str) -> None` | Press key or key combination (async) |

#### Key Syntax Reference

The `key()` method uses **xdotool key syntax**:

| Key           | Syntax                              |
| ------------- | ----------------------------------- |
| Enter         | `Return`                            |
| Tab           | `Tab`                               |
| Escape        | `Escape`                            |
| Backspace     | `BackSpace`                         |
| Delete        | `Delete`                            |
| Arrow keys    | `Up`, `Down`, `Left`, `Right`       |
| Function keys | `F1`, `F2`, ... `F12`               |
| Modifiers     | `ctrl`, `alt`, `shift`, `super`     |
| Combinations  | `ctrl+c`, `ctrl+shift+s`, `alt+Tab` |

**Examples:**

```python theme={null}
await computer.key("Return")        # Press Enter
await computer.key("ctrl+c")        # Copy
await computer.key("ctrl+shift+s")  # Save As
await computer.key("alt+Tab")       # Switch window
await computer.key("ctrl+a Delete") # Select all and delete
```

### Display Methods

| Method               | Signature                             | Description                    |
| -------------------- | ------------------------------------- | ------------------------------ |
| `wait_until_ready()` | `(timeout: int = 60) -> None`         | Wait for desktop ready (async) |
| `screenshot()`       | `() -> dict`                          | Capture screen (async)         |
| `scroll()`           | `(x, y, direction, amount=3) -> None` | Scroll at position (async)     |
| `get_screen_size()`  | `() -> Tuple[int, int]`               | Get screen dimensions (async)  |

#### Screenshot Return Format

```python theme={null}
{
    "data": str,    # Base64-encoded PNG
    "width": int,   # 1024 (default)
    "height": int,  # 768 (default)
    "format": str   # "png"
}
```

#### Scroll Directions

| Direction | Description  |
| --------- | ------------ |
| `"up"`    | Scroll up    |
| `"down"`  | Scroll down  |
| `"left"`  | Scroll left  |
| `"right"` | Scroll right |

### Example

```python theme={null}
async with ComputerBox() as desktop:
    await desktop.wait_until_ready()

    # Take screenshot
    screenshot = await desktop.screenshot()

    # Mouse interaction
    await desktop.mouse_move(100, 200)
    await desktop.left_click()

    # Type text
    await desktop.type("Hello, World!")
    await desktop.key("Return")

    # Get screen size
    width, height = await desktop.get_screen_size()
```

## InteractiveBox

Box for interactive terminal sessions with PTY support.

```python theme={null}
from boxlite import InteractiveBox
```

### Constructor

```python theme={null}
InteractiveBox(
    image: str,
    shell: str = "/bin/sh",
    tty: bool = None,
    memory_mib: int = None,
    cpus: int = None,
    runtime: Boxlite = None,
    name: str = None,
    auto_remove: bool = True,
    **kwargs
)
```

| Parameter     | Type           | Default        | Description                                                  |
| ------------- | -------------- | -------------- | ------------------------------------------------------------ |
| `image`       | `str`          | Required       | Container image                                              |
| `shell`       | `str`          | `"/bin/sh"`    | Shell to run                                                 |
| `tty`         | `bool \| None` | `None`         | TTY mode (see below)                                         |
| `memory_mib`  | `int`          | System default | Memory limit in MiB                                          |
| `cpus`        | `int`          | System default | Number of CPU cores                                          |
| `runtime`     | `Boxlite`      | Global default | Runtime instance                                             |
| `name`        | `str`          | None           | Optional unique name                                         |
| `auto_remove` | `bool`         | `True`         | Remove box when stopped                                      |
| `**kwargs`    |                |                | Additional options: `env`, `volumes`, `ports`, `working_dir` |

#### TTY Mode

| Value   | Behavior                                 |
| ------- | ---------------------------------------- |
| `None`  | Auto-detect from `sys.stdin.isatty()`    |
| `True`  | Force TTY mode with I/O forwarding       |
| `False` | No I/O forwarding (programmatic control) |

### Methods

| Method   | Signature    | Description                    |
| -------- | ------------ | ------------------------------ |
| `wait()` | `() -> None` | Wait for shell to exit (async) |

### Example

```python theme={null}
# Interactive shell session
async with InteractiveBox(image="alpine:latest") as box:
    # You're now in an interactive shell
    # Type commands, see output in real-time
    # Type "exit" to close
    await box.wait()
```

## BoxOptions

Configuration options shared across all box types. See [BoxOptions reference](/reference/index#boxoptions-parameters) for the full specification.

| Field          | Type                          | Default   | Description                                              |
| -------------- | ----------------------------- | --------- | -------------------------------------------------------- |
| `image`        | `str`                         | Required  | OCI image URI (e.g., `"python:slim"`, `"alpine:latest"`) |
| `cpus`         | `int`                         | `1`       | Number of CPU cores (1 to host CPU count)                |
| `memory_mib`   | `int`                         | `2048`    | Memory limit in MiB (128-65536)                          |
| `disk_size_gb` | `int \| None`                 | `None`    | Persistent disk size in GB (None = ephemeral)            |
| `working_dir`  | `str`                         | `"/root"` | Working directory inside container                       |
| `env`          | `List[Tuple[str, str]]`       | `[]`      | Environment variables as (key, value) pairs              |
| `volumes`      | `List[Tuple[str, str, bool]]` | `[]`      | Volume mounts as (host\_path, guest\_path, read\_only)   |
| `ports`        | `List[Tuple[int, int, str]]`  | `[]`      | Port forwarding as (host\_port, guest\_port, protocol)   |
| `auto_remove`  | `bool`                        | `True`    | Auto cleanup when stopped                                |
| `detach`       | `bool`                        | `False`   | Survive parent process exit                              |

## BoxInfo

Metadata about a box, returned by `box.info()` and `runtime.list()`.

| Field        | Type          | Description                                           |
| ------------ | ------------- | ----------------------------------------------------- |
| `id`         | `str`         | Unique box identifier (ULID)                          |
| `name`       | `str \| None` | Optional user-assigned name                           |
| `status`     | `str`         | Current status: `"running"`, `"stopped"`, `"created"` |
| `created_at` | `datetime`    | Creation timestamp                                    |
| `pid`        | `int \| None` | Process ID (if running)                               |
| `image`      | `str`         | OCI image used                                        |
| `cpus`       | `int`         | Allocated CPU cores                                   |
| `memory_mib` | `int`         | Allocated memory in MiB                               |

## BoxStateInfo

Detailed state information for a box.

| Value      | Description                     |
| ---------- | ------------------------------- |
| `Created`  | Box created but not yet started |
| `Starting` | Box is initializing             |
| `Running`  | Box is running and ready        |
| `Stopping` | Box is shutting down            |
| `Stopped`  | Box is stopped                  |
| `Failed`   | Box encountered an error        |

## See Also

* [Python SDK Overview](/reference/python/index) - Runtime management, installation, sync API
* [Execution](/reference/python/execution) - Command execution, streaming I/O
* [Errors & Metrics](/reference/python/errors-metrics) - Exception hierarchy, metrics classes
