Metadata-Version: 2.4
Name: qbox-sh
Version: 1.0.1
Summary: Python SDK for qbox.sh — self-hosted Firecracker code sandboxes
Project-URL: Homepage, https://qbox.sh
Project-URL: Documentation, https://qbox.sh/docs/python-sdk
Project-URL: Repository, https://github.com/utibeabasi6/qbox
Project-URL: Issues, https://github.com/utibeabasi6/qbox/issues
Author-email: "qbox.sh" <hello@qbox.sh>
License-Expression: Apache-2.0
License-File: LICENSE
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
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: Typing :: Typed
Requires-Python: >=3.9
Requires-Dist: httpx<1.0,>=0.27.0
Requires-Dist: pydantic<3.0,>=2.0
Requires-Dist: pyyaml>=6.0
Requires-Dist: rich>=13.7.0
Requires-Dist: typer>=0.12.0
Requires-Dist: typing-extensions>=4.7.0
Provides-Extra: dev
Requires-Dist: mypy>=1.8; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.21; extra == 'dev'
Requires-Dist: pytest>=7.0; extra == 'dev'
Requires-Dist: respx>=0.21; extra == 'dev'
Requires-Dist: ruff>=0.4.0; extra == 'dev'
Requires-Dist: websockets>=12.0; extra == 'dev'
Provides-Extra: shell
Requires-Dist: websockets>=12.0; extra == 'shell'
Description-Content-Type: text/markdown

# qbox — Python SDK

The official Python SDK for [qbox.sh](https://qbox.sh), the self-hosted
Firecracker code-sandbox platform. Mirrors the e2b `Sandbox` shape so migration
is mostly a one-line import change.

```bash
pip install qbox-sh
```

```python
import qbox

with qbox.Sandbox.create(template="python-ml") as sandbox:
    result = sandbox.run_code("import pandas as pd; pd.DataFrame({'a':[1,2,3]}).describe()")
    print(result.text)
```

## Authentication

The SDK reads `QBOX_API_KEY` and `QBOX_BASE_URL` from the environment, or you can
pass them explicitly / via `qbox.configure(...)`:

```bash
export QBOX_API_KEY=qbox_...
export QBOX_BASE_URL=https://qbox.your-company.internal   # self-hosted
```

```python
qbox.configure(api_key="qbox_...", base_url="https://qbox.acme.internal")
```

## What's included

- **`Sandbox`** — `create` / `connect` / `list` / `get_info` / `set_timeout` / `kill`, context manager
- **`sandbox.commands`** — `run` (foreground + `background=True`), `run_argv`, `list`, `connect`, `kill`; `CommandHandle` streams output
- **`sandbox.files`** — `read` / `write` / `append` / `list` / `stat` / `exists` / `remove` / `rename` / `mkdir` / `download` / `upload`
- **`sandbox.run_code` / `run_code_stream` / `code_contexts`** — the code interpreter (rich outputs: text/html/png/json)
- **`sandbox.shell()`** — interactive PTY (install `qbox[shell]`)
- **`qbox.Templates`** — read-only `list` / `get`
- **Typed errors** for every path, env/global/explicit config, transient-only retry, `py.typed`

```python
import qbox

with qbox.Sandbox.create(template="python-ml") as sandbox:
    sandbox.files.write("/tmp/data.csv", "a,b\n1,2\n")
    out = sandbox.run_code("import pandas as pd; pd.read_csv('/tmp/data.csv').sum().to_dict()")
    print(out.text)
    proc = sandbox.commands.run("python --version")
    print(proc.stdout)
```

Async (`qbox.AsyncSandbox`) is planned for v1.1.

## CLI

`pip install qbox-sh` also installs the `qbox` command (operators may prefer
`pipx install qbox-sh`). It wraps the SDK and adds multi-profile config, rich
output, and operator commands.

```bash
qbox auth login                         # set base URL + API key (saved to ~/.config/qbox/config.yaml)
qbox doctor                             # end-to-end deployment check
qbox sandboxes create python-ml         # → sb_018f… (prints the id; scriptable)
qbox sandboxes run-code sb_018f -e "print(6*7)"
qbox sandboxes exec sb_018f -- pytest -q
qbox sandboxes files cp ./script.py sb_018f:/tmp/script.py
qbox sandboxes ssh sb_018f              # interactive PTY (needs qbox[shell])
qbox sandboxes kill sb_018f -y
```

Operator surface: `qbox hosts list|drain|cordon|uncordon`, `qbox api-keys
create|list|revoke|rotate`, `qbox audit logs`, `qbox templates create|list|delete`.

Output: human tables/prose in a TTY, JSON when piped; force with `-o json|yaml|table|prose`.
Multi-profile via `--profile`/`QBOX_PROFILE`. Exit codes are documented (0 ok, 2
usage, 3 auth, 4 not-found, 5 transient, 6 conflict, 10 declined, 124 timeout).

## Development

```bash
pip install -e ".[dev]"
make test        # unit tests
make typecheck   # mypy --strict
make lint        # ruff
```
