Files
loader/_docs/02_document/modules/main.md
T
Oleksandr Bezdieniezhnykh 8f7deb3fca Add E2E tests, fix bugs
Made-with: Cursor
2026-04-13 05:17:48 +03:00

103 lines
4.6 KiB
Markdown

# Module: main
## Purpose
FastAPI application entry point providing HTTP endpoints for health checks, authentication, encrypted resource loading/uploading, and a multi-step Docker image unlock workflow.
## Public Interface
### FastAPI Application
`app = FastAPI(title="Azaion.Loader")`
### Endpoints
| Method | Path | Request Body | Response | Description |
|--------|------------------|---------------------|----------------------------|----------------------------------------------------|
| GET | `/health` | — | `{"status": "healthy"}` | Liveness probe |
| GET | `/status` | — | `StatusResponse` | Auth status + model cache dir |
| POST | `/login` | `LoginRequest` | `{"status": "ok"}` | Set credentials on API client |
| POST | `/load/{filename}`| `LoadRequest` | binary (octet-stream) | Download + decrypt resource |
| POST | `/upload/{filename}`| multipart (file + folder) | `{"status": "ok"}` | Encrypt + upload resource (big/small split) |
| POST | `/unlock` | `LoginRequest` | `{"state": "..."}` | Start background unlock workflow |
| GET | `/unlock/status` | — | `{"state": "...", "error": ...}` | Poll unlock progress |
### Pydantic Models
| Model | Fields |
|-----------------|----------------------------------------------|
| LoginRequest | email: str, password: str |
| LoadRequest | filename: str, folder: str |
| HealthResponse | status: str |
| StatusResponse | status: str, authenticated: bool, modelCacheDir: str |
### Module-level State
| Name | Type | Description |
|----------------|--------------------|------------------------------------------------|
| api_client | ApiClient or None | Lazy-initialized singleton |
| unlock_state | UnlockState | Current unlock workflow state |
| unlock_error | Optional[str] | Last unlock error message |
| unlock_lock | threading.Lock | Thread safety for unlock state mutations |
## Internal Logic
### `get_api_client()`
Lazy singleton pattern: creates `ApiClient(RESOURCE_API_URL)` on first call.
### Unlock Workflow (`_run_unlock`)
Background task (via FastAPI BackgroundTasks) that runs these steps:
1. Check if Docker images already loaded → if yes, set `ready`
2. Authenticate with API (login)
3. Download key fragment from `/binary-split/key-fragment`
4. Decrypt archive at `IMAGES_PATH``.tar`
5. `docker load` the tar file
6. Clean up tar file
7. Set state to `ready` (or `error` on failure)
State transitions are guarded by `unlock_lock` (threading.Lock).
### `/unlock` Endpoint
- If already `ready` → return immediately
- If already in progress → return current state
- If no encrypted archive found → check if images already loaded; if not, 404
- Otherwise, starts `_run_unlock` as a background task
## Dependencies
- **Internal**: `unlock_state` (UnlockState enum), `api_client` (lazy import), `binary_split` (lazy import)
- **External**: `os`, `threading` (stdlib), `fastapi`, `pydantic`
## Consumers
None — this is the entry point module.
## Data Models
`LoginRequest`, `LoadRequest`, `HealthResponse`, `StatusResponse` (Pydantic models defined inline).
## Configuration
| Env Variable | Default | Description |
|------------------|--------------------------------|--------------------------------|
| RESOURCE_API_URL | `https://api.azaion.com` | Azaion resource API base URL |
| IMAGES_PATH | `/opt/azaion/images.enc` | Path to encrypted Docker images |
| API_VERSION | `latest` | Expected Docker image version tag |
## External Integrations
- **Azaion Resource API**: via `ApiClient` (authenticated resource download/upload)
- **Docker CLI**: via `binary_split` (docker load, image inspect)
- **File system**: encrypted archive at `IMAGES_PATH`
## Security
- Login endpoint returns 401 on auth failure
- All resource endpoints use authenticated API client
- Unlock state is thread-safe via `threading.Lock`
- Lazy imports of Cython modules (`api_client`, `binary_split`) to avoid import-time side effects
## Tests
No tests found.