Files
loader/_docs/02_document/modules/main.md
T
Oleksandr Bezdieniezhnykh 4eaf218f09 Quality cleanup refactoring
Made-with: Cursor
2026-04-13 06:21:26 +03:00

5.5 KiB
Raw Blame History

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
_api_client_lock threading.Lock Protects lazy initialization of _api_client (double-checked)
_unlock _UnlockStateHolder Holds unlock workflow state and last error under an inner lock

_UnlockStateHolder

Member Description
get() Returns (state: UnlockState, error: Optional[str]) under lock
set(state, error=None) Sets state and optional error message under lock
state (property) Current UnlockState (read under lock)

Internal Logic

get_api_client()

Double-checked locking: if _api_client is None, acquires _api_client_lock, re-checks, then imports ApiClient and constructs ApiClient(RESOURCE_API_URL) once.

Unlock Workflow (_run_unlock)

Background task (via FastAPI BackgroundTasks) that runs these steps:

  1. Check if Docker images already loaded → if yes, set ready (preserving any prior error from get())
  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. Remove tar file; on OSError, log a warning and continue
  7. Set state to ready with no error (or error on failure)

State and error are updated only through _unlock.set() and read via _unlock.get() / _unlock.state.

/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: UnlockState from unlock_state, get_api_client() (lazy api_client import), binary_split (lazy import in unlock paths)
  • External: os, threading (stdlib), fastapi, pydantic, loguru (logger for tar cleanup warnings)

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 and error are guarded by _UnlockStateHolders lock; API client initialization is guarded by _api_client_lock
  • Lazy imports of Cython modules (api_client, binary_split) to avoid import-time side effects

Tests

No tests found.