Metadata-Version: 2.5
Name: numen-sandbox-py
Version: 0.19.0
Summary: Python client for the Numen sandbox API
License-Expression: Apache-2.0
License-File: LICENSE
Classifier: Development Status :: 4 - Beta
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.12
Requires-Python: >=3.12
Requires-Dist: grpcio>=1.70.0
Requires-Dist: protobuf>=7.36.2
Description-Content-Type: text/markdown

# numen-sandbox-py

Python client for the Numen sandbox API. **0.x beta.** The API can change
between minor versions.

## Install

```bash
pip install numen-sandbox-py
```

## Credentials

The SDK reads `~/.config/numen/credentials.json`.

## Create and run

`image` is required. `numen/base` is the general platform image.

```python
from numen_sandbox_py import Sandbox

with Sandbox.create(image="numen/base") as sb:
    print(sb.run(["python", "-c", "print(2+2)"]).stdout)
```

The `with` block destroys the sandbox on exit.

If `create` is out of memory, catch `CapacityError`. The message is `capacity exceeded: mem. Retry again in 5 minutes.` Retry that error only. Other `capacity exceeded` reasons are unchanged.

## TypeScript parity

Public `Sandbox` and `Client` methods stay 1:1 with `@keska/numen-sandbox`.
Only casing, sync versus async, and TypeScript `AbortSignal` differ. New
methods ship on Python sync, Python async, and TypeScript together.
Portal-only RPCs such as log archives are not part of that contract.

## Errors

Catch `FileNotFoundError` and the other named classes. `str(err)` is the sentence. `sandbox_id`, `path`, `op`, `op_index`, and `request_id` are attributes. `SandboxError` is only the catch-all. Set `NUMEN_RPC_LOG=1` or `Client(..., debug=True)` to log them.
