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

# Python SDK

> Install the Declaw Python SDK and connect to the API using ConnectionConfig, synchronous Sandbox, or async AsyncSandbox.

The Declaw Python SDK is available on [PyPI](https://pypi.org/project/declaw/) and supports Python 3.10+.

## Installation

```bash theme={null}
pip install declaw
```

## Environment variables

The SDK reads connection settings from environment variables by default.

```bash theme={null}
export DECLAW_API_KEY="your-api-key"
export DECLAW_DOMAIN="api.declaw.ai"      # or your enterprise on-prem domain
```

## ConnectionConfig

`ConnectionConfig` holds the credentials and endpoint used by every API call. You rarely need to instantiate it directly — `Sandbox.create()` accepts `api_key` and `domain` parameters that build it for you. Use it directly when you need to share connection settings across multiple calls or customise the request timeout.

```python theme={null}
from declaw import ConnectionConfig

config = ConnectionConfig(
    api_key="your-api-key",
    domain="104.198.24.180:8080",
    request_timeout=30.0,
)
```

<ParamField body="api_key" type="str" default="$DECLAW_API_KEY">
  API key sent as the `X-API-Key` header on every request. Defaults to the
  `DECLAW_API_KEY` environment variable.
</ParamField>

<ParamField body="domain" type="str" default="$DECLAW_DOMAIN or api.declaw.ai">
  Hostname of the Declaw API server. Supports `host:port` format. Port is
  parsed from the string and defaults to `443`.
</ParamField>

<ParamField body="port" type="int" default="443">
  Explicit port override. Ignored when `domain` already contains a port.
</ParamField>

<ParamField body="api_url" type="str | None" default="None">
  Full URL override (e.g. `http://localhost:8080`). When set, `domain` and
  `port` are not used to construct the URL.
</ParamField>

<ParamField body="request_timeout" type="float | None" default="None">
  Default per-request timeout in seconds applied to all HTTP calls made with
  this config. Individual methods accept a `request_timeout` parameter that
  overrides this value.
</ParamField>

## Sync vs async

The SDK ships two sandbox classes with identical surface areas:

|                 | `Sandbox`                          | `AsyncSandbox`                                                     |
| --------------- | ---------------------------------- | ------------------------------------------------------------------ |
| Import          | `from declaw import Sandbox`       | `from declaw import AsyncSandbox`                                  |
| Create          | `Sandbox.create(...)`              | `await AsyncSandbox.create(...)`                                   |
| Context manager | `with Sandbox.create(...) as sbx:` | `async with await AsyncSandbox.create(...) as sbx:`                |
| Best for        | Scripts, CLI tools, simple agents  | Concurrent workloads, multiple sandboxes, FastAPI/async frameworks |

Use `AsyncSandbox` whenever you need to manage multiple sandboxes in parallel or you are running inside an async framework such as FastAPI, LangGraph, or asyncio event loops.

## Quick example

<Tabs>
  <Tab title="Synchronous">
    ```python theme={null}
    from declaw import Sandbox

    sbx = Sandbox.create(
        api_key="your-api-key",
        domain="104.198.24.180:8080",
    )
    try:
        result = sbx.commands.run("echo 'hello from Declaw'")
        print(result.stdout)
    finally:
        sbx.kill()
    ```
  </Tab>

  <Tab title="Async">
    ```python theme={null}
    import asyncio
    from declaw import AsyncSandbox

    async def main():
        sbx = await AsyncSandbox.create(
            api_key="your-api-key",
            domain="104.198.24.180:8080",
        )
        async with sbx:
            result = await sbx.commands.run("echo 'hello from Declaw'")
            print(result.stdout)
        await sbx.kill()

    asyncio.run(main())
    ```
  </Tab>
</Tabs>

## What's exported

The top-level `declaw` package re-exports every public class, exception, model, and enum:

```python theme={null}
from declaw import (
    # Connection
    ConnectionConfig,
    # Sandbox
    Sandbox,
    AsyncSandbox,
    # Templates
    Template,
    AsyncTemplate,
    TemplateBase,
    # Security
    SecurityPolicy,
    PIIConfig,
    PIIType,
    RedactionAction,
    InjectionDefenseConfig,
    InjectionAction,
    NetworkPolicy,
    TransformationRule,
    TransformDirection,
    AuditConfig,
    EnvSecurityConfig,
    SecureEnvVar,
    # Models
    SandboxInfo,
    SandboxState,
    SandboxMetrics,
    SandboxQuery,
    SandboxLifecycle,
    SnapshotInfo,
    CommandResult,
    ProcessInfo,
    EntryInfo,
    FileType,
    WriteEntry,
    WriteInfo,
    FilesystemEvent,
    FilesystemEventType,
    # Exceptions
    SandboxException,
    TimeoutException,
    NotFoundException,
    AuthenticationException,
    CommandExitException,
)
```
