Metadata-Version: 2.4
Name: miosa-sandbox
Version: 0.1.0
Summary: DEPRECATED — use `miosa` instead
Project-URL: Homepage, https://miosa.ai
Project-URL: Documentation, https://docs.miosa.ai/sdk/python
Project-URL: Repository, https://github.com/miosa-ai/miosa
Project-URL: Issues, https://github.com/miosa-ai/miosa/issues
Author-email: MIOSA <dev@miosa.ai>
License-Expression: MIT
License-File: LICENSE
Keywords: agents,ai,code-execution,miosa,sandbox,sdk
Classifier: Development Status :: 7 - Inactive
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: >=3.10
Requires-Dist: httpx>=0.27
Provides-Extra: dev
Requires-Dist: mypy>=1.10; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
Requires-Dist: pytest-httpx>=0.30; extra == 'dev'
Requires-Dist: pytest>=8; extra == 'dev'
Requires-Dist: ruff>=0.5; extra == 'dev'
Description-Content-Type: text/markdown

# miosa-sandbox

> ## ⚠️ Deprecated
> This package has been folded into the main MIOSA SDK. Migrate to:
> - **Python:** `pip install miosa` → `from miosa import Miosa; client = Miosa(api_key="msk_..."); sandbox = client.sandboxes.create(...)`
> - **TypeScript:** `npm install @miosa/sdk` → `import { Miosa } from "@miosa/sdk";`
> - **Go:** `go get github.com/miosa-ai/miosa-go` → `client := miosa.NewClient("msk_...")`
>
> See [Migrating from miosa-sandbox](https://miosa.ai/docs/migrating-from-miosa-sandbox/) for full migration guide.
>
> The `miosa-sandbox` package will receive bug fixes for 6 months but no new features. Sunset date: 2026-11-08.

Python SDK for the [MIOSA](https://miosa.ai) Sandbox API.

New work should use `miosa`, where sandboxes are persistent agent workspaces by
default: create or resume by name, write files under `/workspace`, run
installs/tests/builds inside the sandbox, expose previews, snapshot/pause
between sessions, and publish from the sandbox.

## Install

```bash
pip install miosa-sandbox
```

Requires Python 3.10+. The only runtime dependency is `httpx`.

## Quickstart

```python
from miosa_sandbox import MIOSA

client = MIOSA(api_key="mki_...")
sb = client.sandboxes.create(
    image="miosa-sandbox",
    timeout_sec=86_400,
    idle_timeout_sec=1_800,
)
result = sb.exec("python3 -c 'print(1 + 1)'")
print(result.stdout)  # "2\n"
sb.write_file("/workspace/foo.txt", "hello")
print(sb.read_file("/workspace/foo.txt"))  # "hello"
print(sb.snapshots.create("after-hello-world"))
sb.pause()
```

Or with the context manager so cleanup happens even when something throws:

```python
with MIOSA(api_key="mki_...") as client, \
     client.sandboxes.create(image="debian-12-sandbox-v8") as sb:
    result = sb.exec("echo hello")
    print(result.stdout)  # "hello\n"
# sandbox destroyed and HTTP client closed automatically
```

## Async

For agents and servers, use `AsyncMIOSA`:

```python
import asyncio
from miosa_sandbox import AsyncMIOSA

async def main():
    async with AsyncMIOSA(api_key="mki_...") as client:
        sb = await client.sandboxes.create(image="debian-12-sandbox-v8")
        try:
            result = await sb.exec("python3 -c 'print(40 + 2)'")
            print(result.stdout.strip())  # "42"
        finally:
            await sb.destroy()

asyncio.run(main())
```

## Auth

Get an API key from
[app.miosa.ai/settings/api-keys](https://app.miosa.ai/settings/api-keys).
Keys begin with `mki_` (user) or `msk_` (service / CI).

```python
import os
from miosa_sandbox import MIOSA

client = MIOSA(api_key=os.environ["MIOSA_API_KEY"])
```

Keep keys out of source control — use environment variables or a secrets
manager.

## Common patterns

### Execute a command

```python
result = sb.exec("python3 script.py", opts={"timeout_sec": 60})
if result.exit_code != 0:
    raise RuntimeError(result.stderr)
print(result.stdout)
```

### Stream command output

```python
for chunk in sb.exec_stream("python3 long_script.py"):
    if chunk.stream == "stdout":
        print(chunk.data.decode(), end="")
    elif chunk.stream == "stderr":
        import sys
        sys.stderr.write(chunk.data.decode())
    elif chunk.stream == "exit":
        print(f"\n[exit {chunk.exit_code}]")
```

### Upload / download files

```python
from pathlib import Path

# bytes, str, or pathlib.Path all accepted
sb.upload("/workspace/script.py", "print('hello')")
sb.upload("/workspace/data.bin", b"\x00\x01\x02")
sb.upload("/workspace/local.txt", Path("local.txt"))

# Bytes back out
data: bytes = sb.download("/workspace/output.json")
import json
print(json.loads(data))
```

### Subscribe to lifecycle events (async)

```python
async for event in sb.events():
    if event.type == "state_changed":
        print("new state:", event.data["state"])
    elif event.type == "exec_output":
        print(event.data["stream"], event.data["data"])
```

The stream auto-closes when the sandbox reaches `destroyed`.

## Error handling

All SDK errors inherit from `MiosaError` and carry `status_code`, `code`,
and an optional `request_id` for support.

```python
from miosa_sandbox import (
    MiosaError,
    MiosaAuthError,
    MiosaNotFoundError,
    MiosaRateLimitError,
    MiosaTimeoutError,
)

try:
    sb = client.sandboxes.get(some_id)
except MiosaAuthError:
    print("Check your API key")
except MiosaNotFoundError:
    print("Sandbox not found")
except MiosaRateLimitError as err:
    print(f"Rate limited — retry after {err.retry_after}s")
except MiosaTimeoutError:
    print("Request timed out")
except MiosaError as err:
    print(f"[{err.code}] {err}  (request: {err.request_id})")
```

## Client options

```python
client = MIOSA(
    api_key="mki_...",                          # required
    base_url="https://api.miosa.ai/api/v1",     # default
    timeout=30.0,                               # seconds, default 30
    max_retries=3,                              # 429/5xx retries, default 3
)
```

## Available templates

| Template | Description |
| -------- | ----------- |
| `miosa-sandbox` | Stable production alias for the current sandbox image. |
| `debian-12-sandbox-v8` | Debian Bookworm/glibc image with Python, Node, Elixir/Erlang, Go, Rust, Ruby, Java, Postgres, Redis, SQLite, Chromium, and Playwright support. |

## Docs

Full reference: <https://docs.miosa.ai/sdk/python>.

## License

MIT
