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

5.5 KiB

HTTP API

1. High-Level Overview

Purpose: FastAPI application that exposes HTTP endpoints for health monitoring, user authentication, encrypted resource loading/uploading, and a background Docker image unlock workflow.

Architectural Pattern: Thin controller — delegates all business logic to Resource Management (03) and binary_split.

Upstream dependencies: Core Models (01) — UnlockState enum; Resource Management (03) — ApiClient, binary_split functions

Downstream consumers: None — this is the system entry point, consumed by external HTTP clients.

2. Internal Interfaces

Interface: Module-level Functions

Function Input Output Description
get_api_client ApiClient Lazy singleton accessor
_run_unlock str email, str password Background task: full unlock flow

3. External API Specification

Endpoint Method Auth Rate Limit Description
/health GET Public Liveness probe
/status GET Public Auth status + model cache dir
/login POST Public Set user credentials
/load/{filename} POST Implicit Download + decrypt resource
/upload/{filename} POST Implicit Encrypt + upload resource (big/small)
/unlock POST Public Start background Docker unlock
/unlock/status GET Public Poll unlock workflow progress

"Implicit" auth = credentials must have been set via /login first; enforced by ApiClient's auto-login on token absence.

Request/Response Schemas

POST /login

// Request
{"email": "user@example.com", "password": "secret"}
// Response 200
{"status": "ok"}
// Response 401
{"detail": "error message"}

POST /load/{filename}

// Request
{"filename": "model.bin", "folder": "models"}
// Response 200 — binary octet-stream
// Response 500
{"detail": "error message"}

POST /upload/{filename}

// Request — multipart/form-data
data: <file>
folder: "models" (form field, default "models")
// Response 200
{"status": "ok"}

POST /unlock

// Request
{"email": "user@example.com", "password": "secret"}
// Response 200
{"state": "authenticating"}
// Response 404
{"detail": "Encrypted archive not found"}

GET /unlock/status

// Response 200
{"state": "decrypting", "error": null}

4. Data Access Patterns

Caching Strategy

Data Cache Type TTL Invalidation
ApiClient In-memory singleton Process life Never
unlock_state Module global Until next unlock State machine transition

5. Implementation Details

State Management: Module-level globals (api_client, unlock_state, unlock_error) protected by threading.Lock for unlock state mutations.

Key Dependencies:

Library Version Purpose
fastapi latest HTTP framework
uvicorn latest ASGI server
pydantic (via fastapi) Request/response models
python-multipart latest File upload support

Error Handling Strategy:

  • /login — catches all exceptions, returns 401
  • /load, /upload — catches all exceptions, returns 500
  • /unlock — checks preconditions (archive exists, not already in progress), then delegates to background task
  • Background task (_run_unlock) catches all exceptions, sets unlock_state = error with error message

6. Extensions and Helpers

None.

7. Caveats & Edge Cases

Known limitations:

  • No authentication middleware — endpoints rely on prior /login call having set credentials on the singleton
  • get_api_client() uses a global without locking — race on first concurrent access
  • /load/{filename} has a path parameter filename but also takes req.filename from the body — the path param is unused
  • _run_unlock silently ignores OSError when removing tar file (acceptable cleanup behavior)

Potential race conditions:

  • unlock_state mutations are lock-protected, but api_client singleton creation is not
  • Concurrent /unlock calls: the lock check prevents duplicate starts, but there's a small TOCTOU window between the check and the background_tasks.add_task call

Performance bottlenecks:

  • /load and /upload are synchronous — large files block the worker thread
  • _run_unlock runs as a background task (single thread) — only one unlock can run at a time

8. Dependency Graph

Must be implemented after: Core Models (01), Resource Management (03)

Can be implemented in parallel with: —

Blocks: — (entry point)

9. Logging Strategy

No direct logging in this component — all logging is handled by downstream components via constants.log() / constants.logerror().

Log format: N/A (delegates)

Log storage: N/A (delegates)