feat: implement client architecture and sandbox environment

Introduces the core Wrenn client and a dedicated sandbox execution
environment. This includes automated model generation and a custom
exception hierarchy to support robust integration.

- Add `WrennClient` in `src/wrenn/client.py` for API interaction.
- Implement `Sandbox` in `src/wrenn/sandbox.py` for isolated execution.
- Add Pydantic/model support via `_generated.py`.
- Define project-specific error types in `exceptions.py`.
- Include AGENTS.md documentation for specialized logic.
- Add comprehensive unit and integration tests.
- Update build system (Makefile, uv.lock, pyproject.toml) and LICENSE.
This commit is contained in:
Tasnim Kabir Sadik
2026-04-10 22:24:50 +06:00
parent 4e02061bc9
commit f51a962fff
15 changed files with 3099 additions and 14 deletions

53
src/wrenn/exceptions.py Normal file
View File

@ -0,0 +1,53 @@
from __future__ import annotations
class WrennError(Exception):
"""Base exception for all Wrenn SDK errors."""
def __init__(self, code: str, message: str, status_code: int) -> None:
self.code = code
self.message = message
self.status_code = status_code
super().__init__(message)
class WrennValidationError(WrennError):
"""400 — Invalid request parameters."""
class WrennAuthenticationError(WrennError):
"""401 — Invalid or missing authentication."""
class WrennForbiddenError(WrennError):
"""403 — Authenticated but not authorized."""
class WrennNotFoundError(WrennError):
"""404 — Resource not found."""
class WrennConflictError(WrennError):
"""409 — State conflict (e.g. invalid_state)."""
class WrennHostHasSandboxesError(WrennConflictError):
"""409 — Host still has running sandboxes."""
def __init__(
self, code: str, message: str, status_code: int, sandbox_ids: list[str]
) -> None:
self.sandbox_ids = sandbox_ids
super().__init__(code, message, status_code)
class WrennHostUnavailableError(WrennError):
"""503 — No suitable host available."""
class WrennAgentError(WrennError):
"""502 — Host agent returned an error."""
class WrennInternalError(WrennError):
"""500 — Unexpected server error."""