mirror of
https://github.com/azaion/detections.git
synced 2026-04-23 04:56:31 +00:00
4.2 KiB
4.2 KiB
Module: main
Purpose
FastAPI application entry point — exposes HTTP API for object detection on images and video media, health checks, and Server-Sent Events (SSE) streaming of detection results.
Public Interface
API Endpoints
| Method | Path | Description |
|---|---|---|
| GET | /health |
Returns AI engine availability status |
| POST | /detect |
Single image detection (multipart file upload) |
| POST | /detect/{media_id} |
Start async detection on media from loader service |
| GET | /detect/stream |
SSE stream of detection events |
DTOs (Pydantic Models)
| Model | Fields | Description |
|---|---|---|
DetectionDto |
centerX, centerY, width, height, classNum, label, confidence | Single detection result |
DetectionEvent |
annotations (list[DetectionDto]), mediaId, mediaStatus, mediaPercent | SSE event payload |
HealthResponse |
status, aiAvailability, errorMessage | Health check response |
AIConfigDto |
frame_period_recognition, frame_recognition_seconds, probability_threshold, tracking_*, model_batch_size, big_image_tile_overlap_percent, altitude, focal_length, sensor_width, paths | Configuration input for media detection |
Class: TokenManager
| Method | Signature | Description |
|---|---|---|
__init__ |
(str access_token, str refresh_token) |
Stores tokens |
get_valid_token |
() -> str |
Returns access_token; auto-refreshes if expiring within 60s |
Internal Logic
/health
Returns HealthResponse with status="healthy" always. aiAvailability reflects the engine's AIAvailabilityStatus. On exception, returns aiAvailability="None".
/detect (single image)
- Reads uploaded file bytes
- Parses optional JSON config
- Runs
inference.detect_single_imagein ThreadPoolExecutor (max 2 workers) - Returns list of DetectionDto
Error mapping: RuntimeError("not available") → 503, RuntimeError → 422, ValueError → 400.
/detect/{media_id} (async media)
- Checks for duplicate active detection (409 if already running)
- Extracts auth tokens from Authorization header and x-refresh-token header
- Creates
asyncio.Taskfor background detection - Detection runs
inference.run_detectin ThreadPoolExecutor - Callbacks push
DetectionEventto all SSE queues - If auth token present, also POSTs annotations to the Annotations service
- Returns immediately:
{"status": "started", "mediaId": media_id}
/detect/stream (SSE)
- Creates asyncio.Queue per client (maxsize=100)
- Yields
data: {json}\n\nSSE format - Cleans up queue on disconnect
Token Management
- Decodes JWT exp claim from base64 payload (no signature verification)
- Auto-refreshes via POST to
{ANNOTATIONS_URL}/auth/refreshwhen within 60s of expiry
Annotations Service Integration
- POST to
{ANNOTATIONS_URL}/annotationswith:mediaId,source: 0,videoTime(formatted from ms),detections(list of dto dicts)- Optional base64-encoded
image - Bearer token in Authorization header
Dependencies
- External:
asyncio,base64,json,os,time,concurrent.futures,typing,requests,fastapi,pydantic - Internal:
inference(lazy import),constants_inf(label lookup),loader_http_client(client instantiation)
Consumers
None (entry point).
Data Models
DetectionDto,DetectionEvent,HealthResponse,AIConfigDto— Pydantic models for APITokenManager— JWT token lifecycle
Configuration
| Env Var | Default | Description |
|---|---|---|
LOADER_URL |
http://loader:8080 |
Loader service base URL |
ANNOTATIONS_URL |
http://annotations:8080 |
Annotations service base URL |
External Integrations
| Service | Protocol | Purpose |
|---|---|---|
| Loader | HTTP (via LoaderHttpClient) | Model loading |
| Annotations | HTTP POST | Auth refresh (/auth/refresh), annotation posting (/annotations) |
Security
- Bearer token from request headers, refreshed via Annotations service
- JWT exp decoded (base64, no signature verification) — token validation is not performed locally
- No CORS configuration
- No rate limiting
- No input validation on media_id path parameter beyond string type
Tests
None found.