Metadata-Version: 2.4
Name: platinum-sdk
Version: 0.1.0
Summary: Platinum Python SDK — client for hardware-isolated sandbox microVMs.
License: MIT
Project-URL: Homepage, https://github.com/kortix-ai/platinum
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: httpx>=0.25
Dynamic: license-file

# platinum-sdk (Python)

Python client for [Platinum](https://github.com/kortix-ai/platinum) — hardware-isolated
sandbox microVMs (one Cloud Hypervisor VM per sandbox, sub-second boots via a warm pool).

> **Not on PyPI yet.** Until the first publish, install from source:
> `pip install -e packages/sdk-py` (the import name is `platinum`).

## Quickstart

```python
from platinum import Platinum

dn = Platinum(token="pt_live_...", api_url="https://api.platinum.dev")
# or: PT_TOKEN / PT_API_URL env vars

sbx = dn.sandboxes.create(template="pt-base", wait_for_running=True)
r = sbx.exec(["uname", "-a"]).check()     # .check() raises on non-zero exit
print(r.stdout)
sbx.delete()
```

Expose a port at create time (URL comes back in the same response):

```python
sbx = dn.sandboxes.create(
    template="pt-base",
    expose=[{"port": 8000, "public": True}],
    wait_for_running=True,
)
print(sbx.exposed_url(8000))
```

## Configuration

| Arg / env | Default | Meaning |
|---|---|---|
| `token` / `PT_TOKEN` | — (required) | API key `pt_live_…`, org-scoped bearer token |
| `api_url` / `PT_API_URL` | `http://127.0.0.1:3000` | Control-plane URL |
| `timeout` | `60.0` | Per-request timeout (seconds) |

Python ≥ 3.9. **Synchronous only** (httpx). No automatic retries — a 429 or a failed
create is surfaced to you, never silently retried. Server-side use only; never ship an
API key into client-side code.

## Surface (at parity with the TypeScript SDK)

The two SDKs expose the same operations — enforced in CI by `verify/sdk-parity.sh`.

| Area | Methods |
|---|---|
| Sandboxes | `sandboxes.create(...)` · `get` · `list` · `rename` · `delete` |
| Lifecycle | `pause` · `resume` · `fork` · `snapshot` · `archive` · `rename` · `backup` · `wait_running` · `refresh` |
| Run | `exec(argv)` · `sh(script)` · `run_code(code, lang)` |
| Networking | `expose(port)` · `unexpose(port)` · `exposed_url(port)` |
| Files (vsock) | `files.read` · `write` · `delete` · `list` · `stat` · `mkdir` |
| Share (virtio-fs) | `share.info` · `list` · `stat` · `get` · `put` · `mkdir` · `delete` |
| Platform | `templates.list()` · `regions.list()` · `health.check()` · `me()` |
| Results | `ExecResult(stdout, stderr, exit_code)` with `.check()` |

Build images declaratively with the `Template` builder (parity with the TS `Template`):

```python
from platinum import Platinum, Template

dn = Platinum()
image = (Template.from_python_image("3.12-slim")
                 .pip_install(["fastapi", "uvicorn"])
                 .workdir("/app"))
sbx = dn.sandboxes.create(image=image, wait_for_running=True, wait_timeout_ms=600_000)
```

## Limits worth knowing

- `exec` is buffered, not streaming — output arrives after the command exits
  (default timeout 30 s via `timeout_ms`).
- The default `pt-base` template is busybox-based — no git/pip/node/`httpd` inside
  (`nc` and `wget` are available); build a template from a real distro image when you
  need tooling.
- Background processes are reaped when their `exec` call returns. To leave a server
  running, daemonize it: `setsid sh -c '<server loop>' >/dev/null 2>&1 < /dev/null &`
  — see `examples/02_expose_service.py`.
- Errors raise `PlatinumError` with `.status` (HTTP status; `0` for non-HTTP failures).

## Examples

Runnable scripts in [`examples/`](./examples):

```sh
pip install -e packages/sdk-py
PT_API_URL=… PT_TOKEN=… python packages/sdk-py/examples/01_create_exec_delete.py
```

## License

MIT
