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

100 lines
6.0 KiB
Markdown

# Module: api_client
## Purpose
Central API client that orchestrates authentication, encrypted resource download/upload (using a big/small binary-split scheme), and CDN integration for the Azaion resource API.
## Public Interface
### Classes
#### `ApiClient` (cdef class)
| Attribute | Type | Description |
|-------------|-------------|------------------------------------|
| credentials | Credentials | User email/password |
| user | User | Authenticated user (from JWT) |
| token | str | JWT bearer token |
| cdn_manager | CDNManager | CDN upload/download client |
| api_url | str | Base URL for the resource API |
#### Methods
| Method | Visibility | Signature | Description |
|------------------------------|------------|-------------------------------------------------------------------|--------------------------------------------------------------|
| `__init__` | def | `(self, str api_url)` | Initialize with API base URL |
| `set_credentials_from_dict` | cpdef | `(self, str email, str password)` | Set credentials + initialize CDN from `cdn.yaml` |
| `set_credentials` | cdef | `(self, Credentials credentials)` | Internal: set credentials, lazy-init CDN manager |
| `login` | cdef | `(self)` | POST `/login`, store JWT token |
| `set_token` | cdef | `(self, str token)` | Decode JWT claims → create `User` with role mapping |
| `request` | cdef | `(self, str method, str url, object payload, bint is_stream)` | Authenticated HTTP request with auto-retry on 401/403 |
| `load_bytes` | cdef | `(self, str filename, str folder) -> bytes` | Download + decrypt resource using per-user+hw key |
| `upload_file` | cdef | `(self, str filename, bytes resource, str folder)` | POST multipart upload to `/resources/{folder}`; raises on HTTP error |
| `load_big_file_cdn` | cdef | `(self, str folder, str big_part) -> bytes` | Download large file part from CDN |
| `load_big_small_resource` | cpdef | `(self, str resource_name, str folder) -> bytes` | Reassemble resource from small (API) + big (CDN/local) parts |
| `upload_big_small_resource` | cpdef | `(self, bytes resource, str resource_name, str folder)` | Split-encrypt; CDN upload must succeed or raises; then small part via `upload_file` |
## Internal Logic
### Authentication Flow
1. `set_credentials_from_dict()` → stores credentials, downloads `cdn.yaml` via `load_bytes()` (encrypted), parses YAML, initializes `CDNManager`
2. `login()` → POST `/login` with email/password → receives JWT token → `set_token()` decodes claims (nameid, unique_name, role) → creates `User`
3. `request()` → wraps all authenticated HTTP calls; on 401/403 auto-retries with fresh login
### Big/Small Resource Split (download)
1. Downloads the "small" encrypted part via API (`load_bytes()` with per-user+hw key)
2. Checks if "big" part exists locally (cached file)
3. If local: concatenates small + big, decrypts with shared resource key
4. If decrypt fails (version mismatch): falls through to CDN download
5. If no local: downloads big part from CDN
6. Concatenates small + big, decrypts with shared resource key
### Big/Small Resource Split (upload)
1. Encrypts entire resource with shared resource key
2. Splits: small part = `min(SMALL_SIZE_KB * 1024, 30% of encrypted)`, big part = remainder
3. Calls `cdn_manager.upload` for the big part; raises if upload fails
4. Writes big part to local cache, then uploads small part to API via `upload_file` (non-2xx responses propagate)
### JWT Role Mapping
Maps `role` claim string to `RoleEnum`: ApiAdmin, Admin, ResourceUploader, Validator, Operator, or NONE (default).
## Dependencies
- **Internal**: `constants`, `credentials`, `cdn_manager`, `hardware_service`, `security`, `user`
- **External**: `json`, `os` (stdlib), `jwt` (pyjwt 2.10.1), `requests` (2.32.4), `yaml` (pyyaml 6.0.2)
## Consumers
- `main` — creates `ApiClient` instance; calls `set_credentials_from_dict`, `login`, `load_big_small_resource`, `upload_big_small_resource`; reads `.token`
## Data Models
Uses `Credentials`, `User`, `RoleEnum`, `CDNCredentials`, `CDNManager` from other modules.
## Configuration
| Source | Key | Usage |
|-------------|--------------------|-----------------------------------------|
| `cdn.yaml` | host | CDN endpoint URL |
| `cdn.yaml` | downloader_access_key/secret | CDN read credentials |
| `cdn.yaml` | uploader_access_key/secret | CDN write credentials |
The CDN config file is itself downloaded encrypted from the API on first credential setup.
## External Integrations
- **Azaion Resource API**: `/login`, `/resources/get/{folder}`, `/resources/{folder}` (upload)
- **S3 CDN**: via `CDNManager` for large file parts
## Security
- JWT token stored in memory, decoded without signature verification (`options={"verify_signature": False}`)
- Per-download encryption: resources encrypted with AES-256-CBC using a key derived from user credentials + hardware fingerprint
- Shared resource encryption: big/small split uses a fixed shared key
- Auto-retry on 401/403 re-authenticates transparently
- CDN config is downloaded encrypted, decrypted locally
## Tests
No tests found.