mirror of
https://github.com/azaion/detections.git
synced 2026-04-22 10:46:31 +00:00
[AZ-172] Update documentation for distributed architecture, add Update Docs step to workflow
- Update module docs: main, inference, ai_config, loader_http_client - Add new module doc: media_hash - Update component docs: inference_pipeline, api - Update system-flows (F2, F3) and data_parameters - Add Task Mode to document skill for incremental doc updates - Insert Step 11 (Update Docs) in existing-code flow, renumber 11-13 to 12-14 Made-with: Cursor
This commit is contained in:
@@ -5,8 +5,8 @@
|
||||
| # | Flow Name | Trigger | Primary Components | Criticality |
|
||||
|---|-----------|---------|-------------------|-------------|
|
||||
| F1 | Health Check | Client GET /health | API, Inference Pipeline | High |
|
||||
| F2 | Single Image Detection | Client POST /detect | API, Inference Pipeline, Engines, Domain | High |
|
||||
| F3 | Media Detection (Async) | Client POST /detect/{media_id} | API, Inference Pipeline, Engines, Domain, Loader, Annotations | High |
|
||||
| F2 | Upload Detection (Image/Video) | Client POST /detect | API, Inference Pipeline, Engines, Domain, Annotations | High |
|
||||
| F3 | Media Detection (Async, DB-Driven) | Client POST /detect/{media_id} | API, Inference Pipeline, Engines, Domain, Annotations | High |
|
||||
| F4 | SSE Event Streaming | Client GET /detect/stream | API | Medium |
|
||||
| F5 | Engine Initialization | First detection request | Inference Pipeline, Engines, Loader | High |
|
||||
| F6 | TensorRT Background Conversion | No pre-built TensorRT engine | Inference Pipeline, Engines, Loader | Medium |
|
||||
@@ -16,8 +16,8 @@
|
||||
| Flow | Depends On | Shares Data With |
|
||||
|------|-----------|-----------------|
|
||||
| F1 | F5 (for meaningful status) | — |
|
||||
| F2 | F5 (engine must be ready) | — |
|
||||
| F3 | F5 (engine must be ready) | F4 (via SSE event queues) |
|
||||
| F2 | F5 (engine must be ready) | Annotations (media lifecycle) |
|
||||
| F3 | F5 (engine must be ready) | F4 (via SSE event queues), Annotations (settings, media lifecycle) |
|
||||
| F4 | — | F3 (receives events) |
|
||||
| F5 | — | F6 (triggers conversion if needed) |
|
||||
| F6 | F5 (triggered by init failure) | F5 (provides converted bytes) |
|
||||
@@ -55,11 +55,11 @@ sequenceDiagram
|
||||
|
||||
---
|
||||
|
||||
## Flow F2: Single Image Detection
|
||||
## Flow F2: Upload Detection (Image or Video)
|
||||
|
||||
### Description
|
||||
|
||||
Client uploads an image file and optionally provides config. The service runs inference synchronously (via ThreadPoolExecutor) and returns detection results.
|
||||
Client uploads a media file (image or video) and optionally provides config and auth tokens. The service detects the media kind, manages the media lifecycle (hashing, storage, record creation, status tracking), runs inference synchronously (via ThreadPoolExecutor), and returns detection results.
|
||||
|
||||
### Sequence Diagram
|
||||
|
||||
@@ -67,19 +67,40 @@ Client uploads an image file and optionally provides config. The service runs in
|
||||
sequenceDiagram
|
||||
participant Client
|
||||
participant API as main.py
|
||||
participant HASH as media_hash
|
||||
participant ANN as Annotations Service
|
||||
participant INF as Inference
|
||||
participant ENG as Engine (ONNX/TRT)
|
||||
participant CONST as constants_inf
|
||||
|
||||
Client->>API: POST /detect (file + config?)
|
||||
API->>API: Read image bytes, parse config
|
||||
API->>INF: detect_single_image(bytes, config_dict)
|
||||
Client->>API: POST /detect (file + config? + auth?)
|
||||
API->>API: Read bytes, detect kind (image/video)
|
||||
API->>API: Validate image data (cv2.imdecode)
|
||||
|
||||
opt Authenticated user
|
||||
API->>HASH: compute_media_content_hash(bytes)
|
||||
HASH-->>API: content_hash
|
||||
API->>API: Persist file to VIDEOS_DIR/IMAGES_DIR
|
||||
API->>ANN: POST /api/media (create record)
|
||||
API->>ANN: PUT /api/media/{id}/status (AI_PROCESSING)
|
||||
end
|
||||
|
||||
alt Image
|
||||
API->>INF: run_detect_image(bytes, ai_config, name, callback)
|
||||
else Video
|
||||
API->>INF: run_detect_video(bytes, ai_config, name, path, callback)
|
||||
end
|
||||
|
||||
INF->>INF: init_ai() (idempotent)
|
||||
INF->>INF: cv2.imdecode → preprocess
|
||||
INF->>ENG: run(input_blob)
|
||||
INF->>ENG: process_frames(batch)
|
||||
ENG-->>INF: raw output
|
||||
INF->>INF: postprocess → filter by threshold → remove overlaps
|
||||
INF-->>API: list[Detection]
|
||||
INF->>INF: postprocess → filter → callbacks
|
||||
INF-->>API: results via callback
|
||||
|
||||
opt Authenticated user
|
||||
API->>ANN: PUT /api/media/{id}/status (AI_PROCESSED)
|
||||
end
|
||||
|
||||
API->>CONST: annotations_dict[cls].name (label lookup)
|
||||
API-->>Client: list[DetectionDto]
|
||||
```
|
||||
@@ -88,18 +109,20 @@ sequenceDiagram
|
||||
|
||||
| Error | Where | Detection | Recovery |
|
||||
|-------|-------|-----------|----------|
|
||||
| Empty image | API | len(bytes)==0 | 400 Bad Request |
|
||||
| Invalid image data | imdecode | frame is None | 400 ValueError |
|
||||
| Empty upload | API | len(bytes)==0 | 400 Bad Request |
|
||||
| Invalid image data | cv2.imdecode | returns None | 400 Bad Request |
|
||||
| Unrecognized format | _detect_upload_kind | cv2+PyAV probe fails | 400 Bad Request |
|
||||
| Engine not available | init_ai | engine is None | 503 Service Unavailable |
|
||||
| Inference failure | run/postprocess | RuntimeError | 422 Unprocessable Entity |
|
||||
| Media record failure | _post_media_record | exception caught | Silently continues |
|
||||
|
||||
---
|
||||
|
||||
## Flow F3: Media Detection (Async)
|
||||
## Flow F3: Media Detection (Async, DB-Driven)
|
||||
|
||||
### Description
|
||||
|
||||
Client triggers detection on media files (images/video) available via the Loader service. Processing runs asynchronously. Results are streamed via SSE (F4) and optionally posted to the Annotations service.
|
||||
Client triggers detection on a media file resolved from the Annotations service. AI settings are fetched from the user's DB profile and merged with client overrides. Processing runs asynchronously. Results are streamed via SSE (F4) and optionally posted to the Annotations service. Media status is tracked throughout.
|
||||
|
||||
### Sequence Diagram
|
||||
|
||||
@@ -107,37 +130,41 @@ Client triggers detection on media files (images/video) available via the Loader
|
||||
sequenceDiagram
|
||||
participant Client
|
||||
participant API as main.py
|
||||
participant ANN as Annotations Service
|
||||
participant INF as Inference
|
||||
participant ENG as Engine
|
||||
participant LDR as Loader Service
|
||||
participant ANN as Annotations Service
|
||||
participant SSE as SSE Queues
|
||||
|
||||
Client->>API: POST /detect/{media_id} (config + auth headers)
|
||||
Client->>API: POST /detect/{media_id} (config? + auth headers)
|
||||
API->>API: Check _active_detections (duplicate guard)
|
||||
API->>ANN: GET /api/users/{user_id}/ai-settings
|
||||
ANN-->>API: AI settings (merged with overrides)
|
||||
API->>ANN: GET /api/media/{media_id}
|
||||
ANN-->>API: media path
|
||||
API-->>Client: {"status": "started"}
|
||||
|
||||
Note over API: asyncio.Task created
|
||||
|
||||
API->>INF: run_detect(config, on_annotation, on_status)
|
||||
loop For each media file
|
||||
INF->>INF: Read/decode media (cv2)
|
||||
INF->>INF: Preprocess (tile/batch)
|
||||
INF->>ENG: run(input_blob)
|
||||
ENG-->>INF: raw output
|
||||
INF->>INF: Postprocess + validate
|
||||
API->>API: Read file bytes from resolved path
|
||||
API->>ANN: PUT /api/media/{id}/status (AI_PROCESSING)
|
||||
|
||||
opt Valid annotation found
|
||||
INF->>API: on_annotation(annotation, percent)
|
||||
API->>SSE: DetectionEvent → all queues
|
||||
opt Auth token present
|
||||
API->>ANN: POST /annotations (detections + image)
|
||||
end
|
||||
alt Video file
|
||||
API->>INF: run_detect_video(bytes, config, name, path, callbacks)
|
||||
else Image file
|
||||
API->>INF: run_detect_image(bytes, config, name, callbacks)
|
||||
end
|
||||
|
||||
loop For each valid annotation
|
||||
INF->>API: on_annotation(annotation, percent)
|
||||
API->>SSE: DetectionEvent → all queues
|
||||
opt Auth token present
|
||||
API->>ANN: POST /annotations (detections + image)
|
||||
end
|
||||
end
|
||||
|
||||
INF->>API: on_status(media_name, count)
|
||||
API->>SSE: DetectionEvent(status=AIProcessed, percent=100)
|
||||
API->>ANN: PUT /api/media/{id}/status (AI_PROCESSED)
|
||||
```
|
||||
|
||||
### Data Flow
|
||||
@@ -145,12 +172,16 @@ sequenceDiagram
|
||||
| Step | From | To | Data | Format |
|
||||
|------|------|----|------|--------|
|
||||
| 1 | Client | API | media_id, config, auth tokens | HTTP POST JSON + headers |
|
||||
| 2 | API | Inference | config_dict, callbacks | Python dict + callables |
|
||||
| 3 | Inference | Engine | preprocessed batch | numpy ndarray |
|
||||
| 4 | Engine | Inference | raw detections | numpy ndarray |
|
||||
| 5 | Inference | API (callback) | Annotation + percent | Python objects |
|
||||
| 6 | API | SSE clients | DetectionEvent | SSE JSON stream |
|
||||
| 7 | API | Annotations Service | CreateAnnotationRequest | HTTP POST JSON |
|
||||
| 2 | API | Annotations | user AI settings request | HTTP GET |
|
||||
| 3 | API | Annotations | media path request | HTTP GET |
|
||||
| 4 | API | Annotations | media status update (AI_PROCESSING) | HTTP PUT JSON |
|
||||
| 5 | API | Inference | file bytes, config, callbacks | bytes + AIRecognitionConfig + callables |
|
||||
| 6 | Inference | Engine | preprocessed batch | numpy ndarray |
|
||||
| 7 | Engine | Inference | raw detections | numpy ndarray |
|
||||
| 8 | Inference | API (callback) | Annotation + percent | Python objects |
|
||||
| 9 | API | SSE clients | DetectionEvent | SSE JSON stream |
|
||||
| 10 | API | Annotations Service | CreateAnnotationRequest | HTTP POST JSON |
|
||||
| 11 | API | Annotations | media status update (AI_PROCESSED) | HTTP PUT JSON |
|
||||
|
||||
**Step 7 — Annotations POST detail:**
|
||||
|
||||
|
||||
Reference in New Issue
Block a user