LOT 1 - Optimizare script build -Instalare mono comanda
This commit is contained in:
parent
5380c3fc63
commit
42ff22bf85
127 changed files with 16163 additions and 532 deletions
|
|
@ -1,7 +1,7 @@
|
|||
# Copy to .env and adjust. Read automatically by docker compose.
|
||||
|
||||
# Port pe care expune API-ul pe host
|
||||
API_PORT=8080
|
||||
# Port pe care expune API-ul pe host (containerul ascultă intern pe 8080)
|
||||
API_PORT=8085
|
||||
|
||||
# Opțional: activează HF AI detector în m27 (Organika/sdxl-detector).
|
||||
# Default 0 — testat empiric, regresie pe video out-of-distribution.
|
||||
|
|
|
|||
|
|
@ -56,12 +56,12 @@ Output: text formatat + 12-15 imagini PNG base64 + scoruri raw structurate.
|
|||
# Build și pornește container
|
||||
docker compose up -d
|
||||
|
||||
# Verifică
|
||||
curl http://localhost:8080/health
|
||||
curl http://localhost:8080/api/forensic-modules
|
||||
# Verifică (8085 = portul host; containerul expune intern 8080)
|
||||
curl http://localhost:8085/health
|
||||
curl http://localhost:8085/api/forensic-modules
|
||||
|
||||
# Test end-to-end
|
||||
curl -X POST http://localhost:8080/api/forensic-evidence \
|
||||
curl -X POST http://localhost:8085/api/forensic-evidence \
|
||||
-F "video=@test_video.mp4" \
|
||||
-F "encode_images=1"
|
||||
```
|
||||
|
|
@ -99,7 +99,7 @@ forensic_features/
|
|||
├── .env.example
|
||||
├── requirements.txt # Lean: numpy, scipy, opencv, mediapipe, aiohttp
|
||||
│
|
||||
├── api.py # REST API (270 linii, doar 5 endpoints)
|
||||
├── api.py # REST API (418 linii, 6 endpoints — inclusiv /metrics)
|
||||
├── preprocessing.py # Frame extraction prin ffmpeg
|
||||
├── face_landmarker.task # MediaPipe model (~3.6 MB)
|
||||
│
|
||||
|
|
|
|||
|
|
@ -5,9 +5,12 @@ Toate endpoint-urile, parametrii, status codes, exemple curl.
|
|||
## Base URL
|
||||
|
||||
```
|
||||
http://localhost:8080
|
||||
http://localhost:8085
|
||||
```
|
||||
|
||||
> `8085` este portul publicat pe host. În interiorul containerului serviciul
|
||||
> ascultă pe `8080` (vezi `docker-compose.yml`: `127.0.0.1:${API_PORT:-8085}:8080`).
|
||||
|
||||
## Endpoints
|
||||
|
||||
### `POST /api/forensic-evidence`
|
||||
|
|
@ -113,13 +116,13 @@ Apoi polling pe `/api/status/{job_id}` și preluare cu `/api/result/{job_id}`.
|
|||
|
||||
**Sync, toate modulele**:
|
||||
```bash
|
||||
curl -X POST http://localhost:8080/api/forensic-evidence \
|
||||
curl -X POST http://localhost:8085/api/forensic-evidence \
|
||||
-F "video=@suspicious_video.mp4"
|
||||
```
|
||||
|
||||
**Sync, doar 2 module + fără base64 (mai rapid)**:
|
||||
```bash
|
||||
curl -X POST http://localhost:8080/api/forensic-evidence \
|
||||
curl -X POST http://localhost:8085/api/forensic-evidence \
|
||||
-F "video=@image.jpg" \
|
||||
-F "modules=m27,m28" \
|
||||
-F "encode_images=0"
|
||||
|
|
@ -128,18 +131,18 @@ curl -X POST http://localhost:8080/api/forensic-evidence \
|
|||
**Async, polling**:
|
||||
```bash
|
||||
# Submit
|
||||
JOB=$(curl -s -X POST http://localhost:8080/api/forensic-evidence \
|
||||
JOB=$(curl -s -X POST http://localhost:8085/api/forensic-evidence \
|
||||
-F "video=@long_video.mp4" -F "async_mode=1" \
|
||||
| python -c "import sys,json; print(json.load(sys.stdin)['job_id'])")
|
||||
|
||||
# Wait
|
||||
while [ "$(curl -s http://localhost:8080/api/status/$JOB \
|
||||
while [ "$(curl -s http://localhost:8085/api/status/$JOB \
|
||||
| python -c "import sys,json; print(json.load(sys.stdin)['status'])")" != "done" ]; do
|
||||
sleep 5
|
||||
done
|
||||
|
||||
# Get result
|
||||
curl http://localhost:8080/api/result/$JOB | jq .summary
|
||||
curl http://localhost:8085/api/result/$JOB | jq .summary
|
||||
```
|
||||
|
||||
---
|
||||
|
|
@ -149,7 +152,7 @@ curl http://localhost:8080/api/result/$JOB | jq .summary
|
|||
Listează modulele disponibile, pentru introspection.
|
||||
|
||||
```bash
|
||||
curl http://localhost:8080/api/forensic-modules
|
||||
curl http://localhost:8085/api/forensic-modules
|
||||
```
|
||||
|
||||
```json
|
||||
|
|
@ -177,7 +180,7 @@ curl http://localhost:8080/api/forensic-modules
|
|||
Polling pentru cereri async. Returns 200 cu status string.
|
||||
|
||||
```bash
|
||||
curl http://localhost:8080/api/status/abc123def456789a
|
||||
curl http://localhost:8085/api/status/abc123def456789a
|
||||
```
|
||||
|
||||
```json
|
||||
|
|
@ -205,7 +208,7 @@ Preluare rezultat job async. Comportament:
|
|||
| `error` | 500 cu mesajul de eroare |
|
||||
|
||||
```bash
|
||||
curl http://localhost:8080/api/result/abc123def456789a
|
||||
curl http://localhost:8085/api/result/abc123def456789a
|
||||
```
|
||||
|
||||
Error code 404 dacă job_id nu există.
|
||||
|
|
@ -217,7 +220,7 @@ Error code 404 dacă job_id nu există.
|
|||
Healthcheck pentru Docker / load balancer / monitoring.
|
||||
|
||||
```bash
|
||||
curl http://localhost:8080/health
|
||||
curl http://localhost:8085/health
|
||||
```
|
||||
|
||||
```json
|
||||
|
|
@ -228,6 +231,20 @@ curl http://localhost:8080/health
|
|||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `GET /metrics`
|
||||
|
||||
Expune metrici Prometheus (contor + histogramă durată per rută) pentru
|
||||
monitoring. Format text Prometheus.
|
||||
|
||||
```bash
|
||||
curl http://localhost:8085/metrics
|
||||
```
|
||||
|
||||
Returnează `503` cu `prometheus_client not installed` dacă dependența opțională
|
||||
`prometheus_client` nu e instalată.
|
||||
|
||||
## Notes
|
||||
|
||||
### Limita upload
|
||||
|
|
@ -241,7 +258,7 @@ Job store este **in-memory** (Python dict). Asta înseamnă:
|
|||
- Joburile se pierd la restart container
|
||||
- Multi-replica fără sticky sessions = nu funcționează
|
||||
|
||||
Pentru producție serioasă, înlocuiește `_jobs` din `api.py:30` cu un store
|
||||
Pentru producție serioasă, înlocuiește `_jobs` din `api.py:46` cu un store
|
||||
persistent (Redis recomandat).
|
||||
|
||||
### CORS
|
||||
|
|
|
|||
|
|
@ -75,13 +75,13 @@ LLM-ul integrează totul și decide singur. **Noi nu decidem nimic.**
|
|||
|
||||
Pentru `POST /api/forensic-evidence` cu un video:
|
||||
|
||||
### 1. Upload + validare (api.py:106-180)
|
||||
### 1. Upload + validare (api.py:152-211, în `handle_forensic_evidence`)
|
||||
- Multipart streaming în chunks 64KB (nu buffer tot fișierul)
|
||||
- Validare extensie: mp4/mov/avi/mkv/webm/jpg/png
|
||||
- Asignare `job_id` UUID hex 16 chars
|
||||
- Salvare temporară la `/app/data/inference/{job_id}/`
|
||||
|
||||
### 2. Orchestrator setup (forensic/orchestrator.py:75-110)
|
||||
### 2. Orchestrator setup (forensic/orchestrator.py:220-270, în `run_forensic_pipeline`)
|
||||
- **Adaptive `every_n_frames`** bazat pe durata video:
|
||||
- < 5s → every_n=1 (toate cadrele)
|
||||
- < 30s → every_n=3 (~10 fps efectiv)
|
||||
|
|
@ -91,7 +91,7 @@ Pentru `POST /api/forensic-evidence` cu un video:
|
|||
- Extracție cadre cu ffmpeg via `preprocessing.extract_frames()`
|
||||
- Scriere `_meta.json` cu fps efectiv (m25 îl folosește pentru rPPG)
|
||||
|
||||
### 3. Rulare module (forensic/orchestrator.py:120-145)
|
||||
### 3. Rulare module (forensic/orchestrator.py:283-296, via `_run_single_module` la :77)
|
||||
Fiecare modul rulează **secvențial** (default), izolat în try/except:
|
||||
- Crash într-un modul NU oprește restul
|
||||
- Modulul eșuat returnează `empty_response()` cu primary_score=None
|
||||
|
|
@ -117,7 +117,7 @@ Construiește:
|
|||
- **summary** — obiect cu scoruri agregate pentru parsing programatic
|
||||
- **instruction_for_llm** — text fix care explică LLM-ului cum să folosească datele
|
||||
|
||||
### 6. Răspuns (api.py:225-265)
|
||||
### 6. Răspuns (api.py:235-256, ramura sync din `handle_forensic_evidence`)
|
||||
- Sync (default): JSON imediat
|
||||
- Async (`async_mode=1`): 202 cu job_id, polling pe `/api/status/{id}`
|
||||
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ import requests
|
|||
import base64
|
||||
from pathlib import Path
|
||||
|
||||
FORENSIC_API = "http://localhost:8080"
|
||||
FORENSIC_API = "http://localhost:8085"
|
||||
QWEN_API = "http://your-qwen-host:14011/v1/chat/completions"
|
||||
|
||||
def analyze_video(video_path: str, your_typologies: list[str]) -> dict:
|
||||
|
|
@ -97,7 +97,7 @@ def analyze_video(video_path: str, your_typologies: list[str]) -> dict:
|
|||
|
||||
# ── Pas 4: Apelează LLM-ul tău ───────────────────────────────────
|
||||
qwen_payload = {
|
||||
"model": "Qwen3.5-397B-A17B",
|
||||
"model": "qwen3.5",
|
||||
"messages": [
|
||||
{"role": "system", "content": "Ești analist forensic. Răspunzi în JSON valid."},
|
||||
{"role": "user", "content": content},
|
||||
|
|
@ -138,7 +138,7 @@ async function analyzeWithForensic(videoFile) {
|
|||
fd.append("video", videoFile);
|
||||
fd.append("encode_images", "1");
|
||||
|
||||
const forensicResp = await fetch("http://localhost:8080/api/forensic-evidence", {
|
||||
const forensicResp = await fetch("http://localhost:8085/api/forensic-evidence", {
|
||||
method: "POST",
|
||||
body: fd,
|
||||
});
|
||||
|
|
@ -351,10 +351,10 @@ else:
|
|||
|
||||
```bash
|
||||
# Verifică serviciu
|
||||
curl http://localhost:8080/health
|
||||
curl http://localhost:8085/health
|
||||
|
||||
# Test cu un video real
|
||||
curl -X POST http://localhost:8080/api/forensic-evidence \
|
||||
curl -X POST http://localhost:8085/api/forensic-evidence \
|
||||
-F "video=@your_test_video.mp4" \
|
||||
-o response.json
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue