Skip to content

Commit a9d9555

Browse files
igoochvicentefb
andauthored
Fixes agent sandbox python connection failure when using runtime=runsc (#159)
* Fixes agent sandbox python connection failure when using runtime=runsc * Updates READMEs * the client accepts api url for internal traffic and devs, namespace isolation and retries * added back _start_and_wait_for_port_forward for dev mode updated README * Updates the Readme Breaks out the Gateway Resources from the Router resources --------- Co-authored-by: Vicente Ferrara <[email protected]>
1 parent 2332dd1 commit a9d9555

File tree

13 files changed

+882
-146
lines changed

13 files changed

+882
-146
lines changed

.gitignore

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,8 @@ bin/
77
.netlify
88
# Added by goreleaser init:
99
dist/
10-
release_assets/
10+
release_assets/
11+
12+
# Temporary folders
13+
tmp/
14+
temp/
Lines changed: 99 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,92 +1,137 @@
11
# Agentic Sandbox Client Python
22

3-
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.
3+
This Python client provides a simple, high-level interface for creating and interacting with
4+
sandboxes managed by the Agent Sandbox controller. It's designed to be used as a context manager,
5+
ensuring that sandbox resources are properly created and cleaned up.
46

5-
## Usage
7+
It supports a **scalable, cloud-native architecture** using Kubernetes Gateways and a specialized
8+
Router, while maintaining a convenient **Developer Mode** for local testing.
69

7-
### Prerequisites
10+
## Architecture
811

9-
- A running Kubernetes cluster (e.g., `kind`).
10-
- The Agent Sandbox controller must be deployed with the extensions feature enabled.
11-
- A `SandboxTemplate` resource must be created in the cluster.
12-
- The `kubectl` command-line tool must be installed and configured to connect to your cluster.
12+
The client operates in two modes:
1313

14-
### Installation
14+
1. **Production (Gateway Mode):** Traffic flows from the Client -> Cloud Load Balancer (Gateway)
15+
-> Router Service -> Sandbox Pod. This supports high-scale deployments.
16+
2. **Development (Tunnel Mode):** Traffic flows from Localhost -> `kubectl port-forward` -> Router
17+
Service -> Sandbox Pod. This requires no public IP and works on Kind/Minikube.
18+
3. **Advanced / Internal Mode**: The client connects directly to a provided api_url, bypassing
19+
discovery. This is useful for in-cluster communication or when connecting through a custom domain.
20+
21+
## Prerequisites
22+
23+
- A running Kubernetes cluster.
24+
- The **Agent Sandbox Controller** installed.
25+
- `kubectl` installed and configured locally.
26+
27+
## Setup: Deploying the Router
28+
29+
Before using the client, you must deploy the `sandbox-router`. This is a one-time setup.
30+
31+
1. **Build and Push the Router Image:**
32+
33+
For both Gateway Mode and Tunnel mode, follow the instructions in [sandbox_router](sandbox_router/README.md)
34+
to build, push, and apply the router image and resources.
35+
36+
2. **Create a Sandbox Template:**
37+
38+
Ensure a `SandboxTemplate` exists in your target namespace. The [test_client.py](test_client.py)
39+
uses the [python-runtime-sandbox](../../../examples/python-runtime-sandbox/) image.
1540

16-
1. **Create a virtual environment:**
1741
```bash
18-
python3 -m venv .venv
42+
kubectl apply -f python-sandbox-template.yaml
1943
```
20-
2. **Activate the virtual environment:**
44+
45+
## Installation
46+
47+
1. **Create a virtual environment:**
48+
2149
```bash
50+
python3 -m venv .venv
2251
source .venv/bin/activate
2352
```
24-
3. **Option 1: Install from source via git:**
25-
```bash
26-
# Replace "main" with a specific version tag (e.g., "v0.1.0") from
27-
# https://github.com/kubernetes-sigs/agent-sandbox/releases to pin a version tag.
28-
export VERSION="main"
2953

30-
pip install "git+https://github.com/kubernetes-sigs/agent-sandbox.git@${VERSION}#subdirectory=clients/python/agentic-sandbox-client"
31-
```
32-
4. **Option 2: Install from source in editable mode:**
54+
2. **Install the package:**
3355
```bash
34-
git clone https://github.com/kubernetes-sigs/agent-sandbox.git
35-
cd agent-sandbox/clients/agentic-sandbox-client-python
36-
cd ~/path_to_venv
3756
pip install -e .
3857
```
3958

40-
### Example:
59+
## Usage Examples
60+
61+
### 1. Production Mode (GKE Gateway)
62+
63+
Use this when running against a real cluster with a public Gateway IP. The client automatically
64+
discovers the Gateway.
4165

4266
```python
4367
from agentic_sandbox import SandboxClient
4468
45-
with SandboxClient(template_name="sandbox-python-template", namespace="default") as sandbox:
46-
result = sandbox.run("echo 'Hello, World!'")
47-
print(result.stdout)
69+
# Connect via the GKE Gateway
70+
with SandboxClient(
71+
template_name="python-sandbox-template",
72+
gateway_name="external-http-gateway", # Name of the Gateway resource
73+
namespace="default"
74+
) as sandbox:
75+
print(sandbox.run("echo 'Hello from Cloud!'").stdout)
4876
```
4977

50-
## How It Works
78+
### 2. Developer Mode (Local Tunnel)
5179

52-
The `SandboxClient` client automates the entire lifecycle of a temporary sandbox environment:
80+
Use this for local development or CI. If you omit `gateway_name`, the client automatically opens a
81+
secure tunnel to the Router Service using `kubectl`.
5382

54-
1. **Initialization (`with SandboxClient(...)`):** The client is initialized with the name of the `SandboxTemplate` you want to use and the namespace where the resources should be created:
83+
```python
84+
from agentic_sandbox import SandboxClient
5585
56-
- **`template_name` (str):** The name of the `SandboxTemplate` resource to use for creating the sandbox.
57-
- **`namespace` (str, optional):** The Kubernetes namespace to create the `SandboxClaim` in. Defaults to "default".
58-
- When you create a `SandboxClient` instance within a `with` block, it initiates the process of creating a sandbox.
59-
2. **Claim Creation:** It creates a `SandboxClaim` Kubernetes resource. This claim tells the agent-sandbox controller to provision a new sandbox using a predefined `SandboxTemplate`.
60-
3. **Waiting for Readiness:** The client watches the Kubernetes API for the corresponding `Sandbox` resource to be created and become "Ready". This indicates that the pod is running and the server inside is active.
61-
4. **Port Forwarding:** Once the sandbox pod is ready, the client automatically starts a `kubectl port-forward` process in the background. This creates a secure tunnel from your local machine to the sandbox pod, allowing you to communicate with the server running inside.
62-
5. **Interaction:** The `SandboxClient` object provides three main methods to interact with the running sandbox:
63-
* `run(command)`: Executes a shell command inside the sandbox.
64-
* `write(path, content)`: Uploads a file to the sandbox.
65-
* `read(path)`: Downloads a file from the sandbox.
66-
6. **Cleanup (`__exit__`):** When the `with` block is exited (either normally or due to an error), the client automatically cleans up all resources. It terminates the `kubectl port-forward` process and deletes the `SandboxClaim`, which in turn causes the controller to delete the `Sandbox` pod.
86+
# Automatically tunnels to svc/sandbox-router-svc
87+
with SandboxClient(
88+
template_name="python-sandbox-template",
89+
namespace="dev"
90+
) as sandbox:
91+
print(sandbox.run("echo 'Hello from Local!'").stdout)
92+
```
6793

94+
### 3. Advanced / Internal Mode
6895

69-
## How to Test the Client
96+
Use `api_url` to bypass discovery entirely. Useful for:
7097

71-
A test script, `test_client.py`, is included to verify the client's functionality.
72-
You should see output indicating that the tests for command execution and file operations have passed.
98+
- **Internal Agents:** Running inside the cluster (connect via K8s DNS).
99+
- **Custom Domains:** Connecting via HTTPS (e.g., `https://sandbox.acme.com`).
73100

74-
## Packaging and Installation
101+
```python
102+
with SandboxClient(
103+
template_name="python-sandbox-template",
104+
# Connect directly to a URL
105+
api_url="[http://sandbox-router-svc.default.svc.cluster.local:8080](http://sandbox-router-svc.default.svc.cluster.local:8080)",
106+
namespace="dev"
107+
) as sandbox:
108+
sandbox.run("ls -la")
109+
```
75110

76-
This client is configured as a standard Python package using `pyproject.toml`.
111+
### 4. Custom Ports
77112

78-
### Prerequisites
113+
If your sandbox runtime listens on a port other than 8888 (e.g., a Node.js app on 3000), specify `server_port`.
79114

80-
- Python 3.7+
81-
- `pip`
82-
- `build` (install with `pip install build`)
115+
```python
116+
with SandboxClient(
117+
template_name="node-sandbox-template",
118+
server_port=3000
119+
) as sandbox:
120+
# ...
121+
```
83122

84-
### Building the Package
123+
## Testing
85124

86-
To build the package from the source, navigate to the `agentic-sandbox-client` directory and run the following command:
125+
A test script is included to verify the full lifecycle (Creation -> Execution -> File I/O -> Cleanup).
87126

88-
```bash
89-
python -m build
127+
### Run in Dev Mode:
128+
129+
```
130+
python test_client.py --namespace default
90131
```
91132
92-
This will create a `dist` directory containing the packaged distributables: a `.whl` (wheel) file and a `.tar.gz` (source archive).
133+
### Run in Production Mode:
134+
135+
```
136+
python test_client.py --gateway-name external-http-gateway
137+
```

0 commit comments

Comments
 (0)