# AGENTS.md ## What this repo is Python SDK for **Wrenn** (microVM code execution platform). Communicates with the Control Plane via REST + WebSockets only — no gRPC. The `envd` and `HostAgentService` are internal to the Go backend and never reachable from this SDK. ## Build & dev commands All commands go through `uv` and the `Makefile`. Never use raw `pip`, `venv`, or `python -m venv`. ```bash make generate # Fetch openapi.yaml → src/wrenn/models/_generated.py make lint # ruff check + ruff format --check on src/ make test # runs ONLY tests/test_client.py make test-integration # runs ALL tests (unit + integration, needs live server) make check # lint + test (test_client.py only) ``` To run all unit tests (not just test_client.py): ```bash uv run pytest tests/test_client.py tests/test_sandbox_features.py tests/test_filesystem_pty.py -v ``` To run a single test: ```bash uv run pytest tests/test_client.py::TestAuth::test_signup -v ``` ## Code generation (CRITICAL) Models in `src/wrenn/models/_generated.py` are generated by `datamodel-codegen` from `api/openapi.yaml`. 1. **Never edit `_generated.py`** — overwritten on next `make generate`. 2. All user-facing models must be re-exported in `src/wrenn/models/__init__.py` via `__all__`. 3. To extend a generated model with custom methods, subclass it (e.g. `Sandbox` in `sandbox.py` subclasses the generated `SandboxModel`). ## Dependency management ```bash uv add # runtime dep uv add --dev # dev dep uv run # run in managed .venv ``` ## Implemented resource namespaces Only these are currently implemented in `client.py`: - **`client.auth`** — `signup`, `login` - **`client.api_keys`** — `create`, `list`, `delete` - **`client.sandboxes`** — `create`, `list`, `get`, `destroy` - **`client.snapshots`** — `create`, `list`, `delete` - **`client.hosts`** — `create`, `list`, `get`, `delete`, `regenerate_token`, `list_tags`, `add_tag`, `remove_tag` Both sync and async variants exist for every resource. ## Architecture notes - **Sync/async parity**: `WrennClient` + `AsyncWrennClient` in `client.py`, using `httpx.Client`/`httpx.AsyncClient`. Async methods on `Sandbox` are prefixed `async_` (e.g. `async_exec`, `async_upload`). - **WebSocket library**: `httpx-ws` (not `websockets`). Used for `exec_stream`, `pty`, and `run_code`. - **Sandbox proxy URL**: `get_url(port)` returns `ws://` or `wss://` scheme. The `http_client` property converts to `http://`/`https://` automatically. - **`Sandbox`** (in `sandbox.py`) is the main developer-facing class — subclasses generated model, adds lifecycle methods (`exec`, `upload`, `download`, `list_dir`, `mkdir`, `remove`, `pty`, `run_code`, `wait_ready`, `pause`, `resume`, `destroy`, `ping`, `metrics`), context manager support, and proxy helpers. - **Error handling**: `handle_response()` in `exceptions.py` maps server error `code` field to typed exceptions (not just HTTP status). All inherit from `WrennError` with `.code`, `.message`, `.status_code`. ## Testing - **HTTP mocking**: `respx` library (not `responses` or `pytest-httpx`). Mock routes with `@respx.mock` decorator or `respx.mock` context manager. - **Async tests**: use `@pytest.mark.asyncio` (backed by `pytest-asyncio`). - **Integration tests**: in `test_integration.py`, require env vars `WRENN_API_KEY` or `WRENN_TOKEN` (plus optional `WRENN_BASE_URL`, `WRENN_TEST_EMAIL`, `WRENN_TEST_PASSWORD`). They are skipped via `@requires_auth` if credentials are absent. - **Fixtures**: test fixtures create `WrennClient(api_key="wrn_test1234567890abcdef12345678")` with context manager cleanup. ## Coding conventions - **Python 3.13+** with modern syntax (`|` unions, `list[str]` generics). - **Strict typing** throughout. `pyright`/`mypy` available but not in CI. - **`ruff`** is the sole linter and formatter. Do not use `black`, `isort`, or `flake8`. - **Google-style docstrings** on all public APIs. - **No comments** unless explicitly asked.