Metadata-Version: 2.4
Name: quicktane
Version: 0.1.0
Summary: Python SDK for QuickTane — run code in isolated, ephemeral cloud sandboxes.
Project-URL: Homepage, https://quicktane.com
Project-URL: Documentation, https://quicktane.com/docs
Project-URL: Repository, https://github.com/quicktane/SDK-Python
Project-URL: Changelog, https://quicktane.com/docs/changelog
Author: QuickTane
License-Expression: MIT
License-File: LICENSE
Keywords: ai-agents,code-execution,code-interpreter,gvisor,sandbox
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Typing :: Typed
Requires-Python: >=3.9
Requires-Dist: httpx>=0.27
Provides-Extra: dev
Requires-Dist: pytest>=8; extra == 'dev'
Requires-Dist: ruff>=0.6; extra == 'dev'
Description-Content-Type: text/markdown

# QuickTane Python SDK

Run code in isolated, ephemeral cloud sandboxes ([QuickTane](https://quicktane.com)) — one API call.

```bash
pip install quicktane
```

## Quickstart

```python
from quicktane import QuickTane

qt = QuickTane("sk_live_...")           # or set QUICKTANE_API_KEY

run = qt.run_and_wait("print('hello from the sandbox')", language="python")

print(run.status)      # "completed"
print(run.output)      # "hello from the sandbox\n"
print(run.exit_code)   # 0
```

Supported languages: `python`, `node`.

## Fire-and-forget + webhooks

Instead of waiting, queue the run and let a webhook notify you when it finishes:

```python
run = qt.run("print(2 + 2)", language="python")
print(run.run_id, run.status)   # 42 running

# later, or fetch on demand:
run = qt.get_run(42)
```

Register a webhook endpoint in your dashboard, then verify deliveries:

```python
from quicktane import verify_signature

# in your webhook handler — use the RAW request body
if not verify_signature(raw_body, request.headers["X-QuickTane-Signature"], signing_secret):
    abort(400)
```

## Interactive sessions

Run many commands in one live sandbox — file and process state persist between calls:

```python
sbx = qt.create_sandbox("python")            # waits until ready

sbx.files.write("app.py", "print('hello from a session')")
result = sbx.exec(command="python app.py")
print(result.stdout, result.ok)              # "hello from a session\n" True

# state persists across execs:
sbx.exec(command="pip install requests")
sbx.exec("import requests; print(requests.__version__)")

sbx.kill()

# or auto-kill with a context manager:
with qt.create_sandbox("node") as sbx:
    print(sbx.exec("console.log(2 + 2)").stdout)
```

## Configuration

| | |
| --- | --- |
| `QuickTane(api_key, base_url=..., timeout=...)` | client; `api_key` falls back to `QUICKTANE_API_KEY` |
| `QUICKTANE_BASE_URL` | override the API base (e.g. `http://localhost:8000` for local dev) |

## Errors

All errors subclass `quicktane.QuickTaneError`:

`AuthenticationError` (401/403), `NotFoundError` (404), `ValidationError` (422),
`RateLimitError` (429), `APIError` (other). Each carries `.status_code` and `.body`.

## Development

```bash
pip install -e '.[dev]'
pytest
```

MIT licensed.
