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

# GMI Sandbox SDK Usage

> Install, configure, and use the GMI Sandbox Python SDK.

# GMI Sandbox SDK Usage

## Install

```bash theme={null}
python -m pip install gmi-sandbox-sdk
```

## Configure

Use environment variables or pass values directly.

To get an API key, log in to `https://console.gmicloud.ai/`, click **API keys**, select **compute**, and click **Create API key**.

```bash theme={null}
export GMI_SANDBOX_API_KEY="your-api-key"
```

`GMI_SANDBOX_IDC_NAME` is optional. Leave it unset to use your organization's default IDC. Set it only when you want requests to target a non-default IDC:

```bash theme={null}
export GMI_SANDBOX_IDC_NAME="gmi-sandbox-us"
```

## Create a client

```python theme={null}
from sandbox_sdk import SandboxClient

client = SandboxClient()
```

You can also pass credentials explicitly:

```python theme={null}
client = SandboxClient(
    api_key="your-api-key",
)
```

## Create and use a sandbox

```python theme={null}
sandbox = client.sandboxes.create(
    template_id="template-id",
)

sandbox.connect()
result = sandbox.commands.run("echo hello", wait=True)
print(result.stdout)

sandbox.files.write("/tmp/hello.txt", "hello")
print(sandbox.files.read("/tmp/hello.txt").decode())

sandbox.delete()
```

If you already have a sandbox ID:

```python theme={null}
sandbox = client.sandboxes.get("sandbox-id")
sandbox.connect()
```

## Files

```python theme={null}
sandbox.files.read("/tmp/a.txt")
sandbox.files.write("/tmp/a.txt", "hello")
sandbox.files.write("/tmp/a.bin", b"binary-data")
sandbox.files.upload("./local.txt", "/workspace/local.txt")
sandbox.files.download("/workspace/output.txt", "./output.txt")
```

`download()` returns bytes and can also write to a destination path.

## Commands

```python theme={null}
execution = sandbox.commands.run(
    "python --version",
    cwd="/workspace",
    envs={"PYTHONUNBUFFERED": "1"},
    wait=True,
    wait_timeout_seconds=25,
)

print(execution.status)
print(execution.exit_code)
print(execution.stdout)
print(execution.stderr)
```

You can refresh or cancel a running execution:

```python theme={null}
execution.refresh()
execution.cancel()
```

## Templates

```python theme={null}
template = client.templates.get("template-id")
template.update(name="new-name")
template.delete()

builds = template.builds()
build = template.build("build-id")
logs = template.build_logs("build-id", offset=0, limit=100)
```

Creating a template requires an idempotency key:

```python theme={null}
template = client.templates.create(
    name="demo",
    resources={"type": "preset", "product": "gmi.sandbox.small"},
    build={"source": {"type": "image", "image": "ubuntu:22.04"}},
    idempotency_key="template-1",
)

print(template.template_id)
template.update(name="new-name")
```

## Product specifications

```python theme={null}
client.product_specifications.list()
client.product_specifications.list(idc_name="gmi-sandbox-us")
```

## Errors

The SDK raises typed exceptions for HTTP failures:

* `BadRequestError`
* `AuthenticationError`
* `PermissionDeniedError`
* `NotFoundError`
* `ConflictError`
* `RateLimitError`
* `ServerError`

Example:

```python theme={null}
from sandbox_sdk import NotFoundError

try:
    client.sandboxes.get("missing")
except NotFoundError:
    print("sandbox not found")
```
