Metadata-Version: 2.4
Name: k8s-agent-sandbox
Version: 0.4.2
Summary: A client library to interact with the Agentic Sandbox on Kubernetes.
Project-URL: Homepage, https://github.com/kubernetes-sigs/agent-sandbox
Project-URL: Bug Tracker, https://github.com/kubernetes-sigs/agent-sandbox/issues
Classifier: Programming Language :: Python :: 3
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Operating System :: OS Independent
Requires-Python: >=3.10
Description-Content-Type: text/markdown
Requires-Dist: kubernetes
Requires-Dist: requests
Requires-Dist: pydantic
Provides-Extra: async
Requires-Dist: httpx; extra == "async"
Requires-Dist: kubernetes_asyncio; extra == "async"
Provides-Extra: test
Requires-Dist: pytest; extra == "test"
Requires-Dist: pytest-xdist; extra == "test"
Requires-Dist: pytest-asyncio; extra == "test"
Requires-Dist: httpx; extra == "test"
Requires-Dist: kubernetes_asyncio; extra == "test"
Provides-Extra: tracing
Requires-Dist: opentelemetry-api~=1.39.0; extra == "tracing"
Requires-Dist: opentelemetry-sdk~=1.39.0; extra == "tracing"
Requires-Dist: opentelemetry-exporter-otlp~=1.39.0; extra == "tracing"
Requires-Dist: opentelemetry-instrumentation-requests~=0.60b0; extra == "tracing"

# Agentic Sandbox Client Python

This Python client provides a simple, high-level interface for creating and interacting with
sandboxes managed by the Agent Sandbox controller. It's designed to be used as a context manager,
ensuring that sandbox resources are properly created and cleaned up.

It supports a **scalable, cloud-native architecture** using Kubernetes Gateways and a specialized
Router, while maintaining a convenient **Developer Mode** for local testing.

## Architecture

The client operates in three modes:

1.  **Production (Gateway Mode):** Traffic flows from the Client -> Cloud Load Balancer (Gateway)
    -> Router Service -> Sandbox Pod. This supports high-scale deployments.
2.  **Development (Tunnel Mode):** Traffic flows from Localhost -> `kubectl port-forward` -> Router
    Service -> Sandbox Pod. This requires no public IP and works on Kind/Minikube.
3.  **Advanced / Internal Mode**: The client connects directly to a provided api_url, bypassing
    discovery. This is useful for in-cluster communication or when connecting through a custom domain.

## Prerequisites

- A running Kubernetes cluster.
- The [**Agent Sandbox Controller**](https://github.com/kubernetes-sigs/agent-sandbox?tab=readme-ov-file#installation) installed.
- `kubectl` installed and configured locally.

## Setup: Deploying the Router

Before using the client, you must deploy the `sandbox-router`. This is a one-time setup.

1.  **Build and Push the Router Image:**

    For both Gateway Mode and Tunnel Mode, follow the instructions in [sandbox-router](sandbox-router/README.md)
    to build, push, and apply the router image and resources.

2.  **Create a Sandbox Template:**

    Ensure a `SandboxTemplate` exists in your target namespace. The [test_client.py](test_client.py)
    uses the [python-runtime-sandbox](../../../examples/python-runtime-sandbox/) image.

    ```bash
    kubectl apply -f python-sandbox-template.yaml
    ```

## Installation

1.  **Create a virtual environment:**

    ```bash
    python3 -m venv .venv
    source .venv/bin/activate
    ```

2.  **Install Agent Sandbox Client**
    

    * **Option 1: Install from PyPI (Recommended):**

        The package is available on [PyPI](https://pypi.org/project/k8s-agent-sandbox/) as `k8s-agent-sandbox`.

        ```bash
        pip install k8s-agent-sandbox
        ```

        If you are using [tracing with GCP](GCP.md#tracing-with-open-telemetry-and-google-cloud-trace), install with the optional tracing dependencies:

        ```bash
        pip install "k8s-agent-sandbox[tracing]"
        ```


    * **Option 2: Install from source via git:**

        ```bash
        # Replace "main" with a specific version tag (e.g., "v0.1.0") from
        # https://github.com/kubernetes-sigs/agent-sandbox/releases to pin a version tag.
        export VERSION="main"

        pip install "git+https://github.com/kubernetes-sigs/agent-sandbox.git@${VERSION}#subdirectory=clients/python/agentic-sandbox-client"
        ```

        **Note**: This package uses `setuptools-scm` for dynamic versioning. For Option 2 and Option 3, when installing locally, you may notice the version increment if your local repository has uncommitted changes or is ahead of the last tagged release. This is expected behavior to ensure unique versioning during development.

    * **Option 3: Install from source in editable mode:**

        If you have not already done so, first clone this repository:

        ```bash
        cd ~
        git clone https://github.com/kubernetes-sigs/agent-sandbox.git
        cd agent-sandbox/clients/python/agentic-sandbox-client
        ```

        And then install the agentic-sandbox-client into your activated .venv:

        ```bash
        pip install -e .
        ```

        If you are using [tracing with GCP](GCP.md#tracing-with-open-telemetry-and-google-cloud-trace),
        install with the optional tracing dependencies:

        ```
        pip install -e ".[tracing]"
        ```

## Usage Examples

### 1. Production Mode (GKE Gateway)

Use this when running against a real cluster with a public Gateway IP. The client automatically
discovers the Gateway.

```python
from k8s_agent_sandbox import SandboxClient
from k8s_agent_sandbox.models import SandboxGatewayConnectionConfig

# Connect via the GKE Gateway
client = SandboxClient(
    connection_config=SandboxGatewayConnectionConfig(
        gateway_name="external-http-gateway",  # Name of the Gateway resource
    )
)

sandbox = client.create_sandbox(template="python-sandbox-template", namespace="default")
try:
    print(sandbox.commands.run("echo 'Hello from Cloud!'").stdout)
finally:
    sandbox.terminate()
```

### 2. Developer Mode (Local Tunnel)

Use this for local development or CI. The client automatically opens a secure tunnel to the
Router Service using `kubectl`.

```python
from k8s_agent_sandbox import SandboxClient
from k8s_agent_sandbox.models import SandboxLocalTunnelConnectionConfig

# Automatically tunnels to svc/sandbox-router-svc
client = SandboxClient(
    connection_config=SandboxLocalTunnelConnectionConfig()
)

sandbox = client.create_sandbox(template="python-sandbox-template", namespace="default")
try:
    print(sandbox.commands.run("echo 'Hello from Local!'").stdout)
finally:
    sandbox.terminate()
```

### 3. Advanced / Internal Mode

Use `SandboxDirectConnectionConfig` to bypass discovery entirely. Useful for:

- **Internal Agents:** Running inside the cluster (connect via K8s DNS).
- **Custom Domains:** Connecting via HTTPS (e.g., `https://sandbox.example.com`).

```python
from k8s_agent_sandbox import SandboxClient
from k8s_agent_sandbox.models import SandboxDirectConnectionConfig

client = SandboxClient(
    connection_config=SandboxDirectConnectionConfig(
       api_url="http://sandbox-router-svc.default.svc.cluster.local:8080"
    )
)

sandbox = client.create_sandbox(template="python-sandbox-template", namespace="default")
try:
    sandbox.commands.run("ls -la")
finally:
    sandbox.terminate()
```

### 4. Custom Ports

If your sandbox runtime listens on a port other than 8888 (e.g., a Node.js app on 3000), specify `server_port`.

```python
from k8s_agent_sandbox import SandboxClient
from k8s_agent_sandbox.models import SandboxLocalTunnelConnectionConfig

client = SandboxClient(
    connection_config=SandboxLocalTunnelConnectionConfig(server_port=3000)
)

sandbox = client.create_sandbox(template="node-sandbox-template", namespace="default").
```

### 5. Async Client

For async applications (FastAPI, aiohttp, async agent orchestrators), use the `AsyncSandboxClient`.
Install the async extras first:

```bash
pip install k8s-agent-sandbox[async]
```

The async client requires an explicit connection config — `LocalTunnel` mode is not supported
because it relies on a synchronous `kubectl port-forward` subprocess. Use `DirectConnection` or
`GatewayConnection` instead.

```python
import asyncio
from k8s_agent_sandbox import AsyncSandboxClient
from k8s_agent_sandbox.models import SandboxDirectConnectionConfig

async def main():
    config = SandboxDirectConnectionConfig(
        api_url="http://sandbox-router-svc.default.svc.cluster.local:8080"
    )

    async with AsyncSandboxClient(connection_config=config) as client:
        sandbox = await client.create_sandbox(
            template="python-sandbox-template",
            namespace="default",
        )
        result = await sandbox.commands.run("echo 'Hello from async!'")
        print(result.stdout)

asyncio.run(main())
```

## Testing

A test script is included to verify the full lifecycle (Creation -> Execution -> File I/O -> Cleanup).

### Run in Dev Mode:

```
python test_client.py --namespace default
```

### Run in Production Mode:

```
python test_client.py --gateway-name external-http-gateway
```
