Livrare LOT 1 - Didi
This commit is contained in:
commit
5380c3fc63
990 changed files with 133308 additions and 0 deletions
260
ai_platform/modules/forensic_features/docs/API.md
Normal file
260
ai_platform/modules/forensic_features/docs/API.md
Normal file
|
|
@ -0,0 +1,260 @@
|
|||
# API Reference
|
||||
|
||||
Toate endpoint-urile, parametrii, status codes, exemple curl.
|
||||
|
||||
## Base URL
|
||||
|
||||
```
|
||||
http://localhost:8080
|
||||
```
|
||||
|
||||
## Endpoints
|
||||
|
||||
### `POST /api/forensic-evidence`
|
||||
|
||||
**Singurul endpoint care contează în practică.** Upload un video/imagine,
|
||||
primește înapoi evidence formatat pentru LLM.
|
||||
|
||||
#### Request
|
||||
|
||||
Content-Type: `multipart/form-data`
|
||||
|
||||
| Field | Type | Required | Default | Description |
|
||||
|-----------------|----------|----------|---------|-------------|
|
||||
| `video` | file | DA | — | Fișier video sau imagine (mp4, mov, avi, mkv, webm, jpg, jpeg, png). Max 2 GB. |
|
||||
| `modules` | string | NU | toate | CSV de module IDs ("m25,m27,m28"). Default rulează toate cele 5. |
|
||||
| `encode_images` | string | NU | "1" | "1" → atașează data URLs base64; "0" → doar paths absolute pe disk |
|
||||
| `every_n_frames`| int | NU | adaptiv | Pas extracție cadre. None → orchestrator alege bazat pe durata video |
|
||||
| `async_mode` | string | NU | "0" | "1" → returnează 202 cu job_id; "0" → blochează până la rezultat |
|
||||
|
||||
#### Response
|
||||
|
||||
**Sync mode (default) — 200 OK** — JSON cu schema completă (vezi [CONTRACT.md](CONTRACT.md)):
|
||||
|
||||
```jsonc
|
||||
{
|
||||
"video_path": "video.mp4",
|
||||
"n_frames_extracted": 64,
|
||||
"every_n_frames_used": 3,
|
||||
"auto_skipped": ["m26 (no audio track)"],
|
||||
"modules_run": ["m25", "m27", "m28", "m29"],
|
||||
"execution_time_ms": 48432.0,
|
||||
|
||||
"fusion": {
|
||||
"score": 0.67,
|
||||
"label": "FAKE",
|
||||
"confidence": 0.78,
|
||||
"n_contributing": 4,
|
||||
"n_no_signal": 0,
|
||||
"disagreement": 0.005,
|
||||
"contributions": {"m25": 0.09, "m27": 0.23, "m28": 0.24, "m29": 0.11}
|
||||
},
|
||||
|
||||
"explanation": [
|
||||
"Verdict forensic: FAKE (score=0.67, confidence=0.78, din 4 detectoare active)",
|
||||
"Top contributors: m28 INCERT, m27 FAKE, m25 INCERT"
|
||||
],
|
||||
|
||||
"modules": {
|
||||
"m25": { ... schema completă CONTRACT.md ... },
|
||||
"m27": { ... },
|
||||
"m28": { ... },
|
||||
"m29": { ... }
|
||||
},
|
||||
|
||||
"evidence_text": "FORENSIC EVIDENCE (objective measurements...)\n\n[m25 ...] score=...\n...",
|
||||
|
||||
"images": [
|
||||
{
|
||||
"name": "m25_pulse_signal.png",
|
||||
"tool_id": "m25",
|
||||
"abs_path": "/app/data/results/{job_id}/images/m25_pulse_signal.png",
|
||||
"size_bytes": 69384,
|
||||
"data_url": "data:image/png;base64,iVBORw0KG..." // dacă encode_images=1
|
||||
},
|
||||
// ... 8-15 imagini total
|
||||
],
|
||||
|
||||
"summary": {
|
||||
"overall_score": 0.67,
|
||||
"overall_label": "FAKE",
|
||||
"overall_confidence": 0.78,
|
||||
"n_modules_run": 4,
|
||||
"n_modules_signal": 4,
|
||||
"disagreement": 0.005
|
||||
},
|
||||
|
||||
"instruction_for_llm": "HOW TO USE FORENSIC EVIDENCE ABOVE:\n...",
|
||||
|
||||
"errors": []
|
||||
}
|
||||
```
|
||||
|
||||
**Async mode (`async_mode=1`) — 202 Accepted**:
|
||||
|
||||
```json
|
||||
{
|
||||
"job_id": "abc123def456789a",
|
||||
"status": "queued",
|
||||
"modules": ["m25", "m26", "m27", "m28", "m29"]
|
||||
}
|
||||
```
|
||||
|
||||
Apoi polling pe `/api/status/{job_id}` și preluare cu `/api/result/{job_id}`.
|
||||
|
||||
#### Error codes
|
||||
|
||||
| Code | Cauza |
|
||||
|------|-------|
|
||||
| 400 | Câmp `video` lipsește, tip fișier nesuportat, sau modul necunoscut |
|
||||
| 500 | Eroare în pipeline (vezi mesaj eroare în body) |
|
||||
|
||||
#### Examples
|
||||
|
||||
**Sync, toate modulele**:
|
||||
```bash
|
||||
curl -X POST http://localhost:8080/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 \
|
||||
-F "video=@image.jpg" \
|
||||
-F "modules=m27,m28" \
|
||||
-F "encode_images=0"
|
||||
```
|
||||
|
||||
**Async, polling**:
|
||||
```bash
|
||||
# Submit
|
||||
JOB=$(curl -s -X POST http://localhost:8080/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 \
|
||||
| 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
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `GET /api/forensic-modules`
|
||||
|
||||
Listează modulele disponibile, pentru introspection.
|
||||
|
||||
```bash
|
||||
curl http://localhost:8080/api/forensic-modules
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"available_modules": [
|
||||
{"id": "m25", "input_type": "overview_frames",
|
||||
"import_path": "tools.m25_physiology.physiology", "function": "run"},
|
||||
{"id": "m26", "input_type": "video_path",
|
||||
"import_path": "tools.m26_audio.audio", "function": "run"},
|
||||
{"id": "m27", "input_type": "overview_frames",
|
||||
"import_path": "tools.m27_ai_detector.ai_detector", "function": "run"},
|
||||
{"id": "m28", "input_type": "overview_frames",
|
||||
"import_path": "tools.m28_forgery_heatmap.forgery_heatmap", "function": "run"},
|
||||
{"id": "m29", "input_type": "overview_frames",
|
||||
"import_path": "tools.m29_lighting.lighting", "function": "run"}
|
||||
],
|
||||
"default": ["m25", "m26", "m27", "m28", "m29"]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `GET /api/status/{job_id}`
|
||||
|
||||
Polling pentru cereri async. Returns 200 cu status string.
|
||||
|
||||
```bash
|
||||
curl http://localhost:8080/api/status/abc123def456789a
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"job_id": "abc123def456789a",
|
||||
"status": "running",
|
||||
"progress": "Running forensic modules m25-m29..."
|
||||
}
|
||||
```
|
||||
|
||||
Status values: `queued`, `running`, `done`, `error`.
|
||||
|
||||
Error code 404 dacă job_id nu există.
|
||||
|
||||
---
|
||||
|
||||
### `GET /api/result/{job_id}`
|
||||
|
||||
Preluare rezultat job async. Comportament:
|
||||
|
||||
| Job status | Răspuns |
|
||||
|------------|--------------------------------------------|
|
||||
| `queued` sau `running` | 202 cu status + progress |
|
||||
| `done` | 200 cu rezultatul complet (același ca sync)|
|
||||
| `error` | 500 cu mesajul de eroare |
|
||||
|
||||
```bash
|
||||
curl http://localhost:8080/api/result/abc123def456789a
|
||||
```
|
||||
|
||||
Error code 404 dacă job_id nu există.
|
||||
|
||||
---
|
||||
|
||||
### `GET /health`
|
||||
|
||||
Healthcheck pentru Docker / load balancer / monitoring.
|
||||
|
||||
```bash
|
||||
curl http://localhost:8080/health
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"status": "ok",
|
||||
"service": "forensic-features",
|
||||
"modules": ["m25", "m26", "m27", "m28", "m29"]
|
||||
}
|
||||
```
|
||||
|
||||
## Notes
|
||||
|
||||
### Limita upload
|
||||
|
||||
`client_max_size=2 * 1024**3` = **2 GB** per request. Pe video >2GB,
|
||||
preprocesezi cu ffmpeg înainte de upload.
|
||||
|
||||
### Concurența
|
||||
|
||||
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
|
||||
persistent (Redis recomandat).
|
||||
|
||||
### CORS
|
||||
|
||||
Activat default cu `*` pentru orice origine. Pentru producție public,
|
||||
restrictionează în `api.py:build_app()`.
|
||||
|
||||
### Rate limiting
|
||||
|
||||
**NU există**. Pentru producție public, pune un reverse proxy
|
||||
(nginx, Traefik) în față cu rate limiting.
|
||||
|
||||
### Auth
|
||||
|
||||
**NU există**. Endpoint-urile sunt deschise. Pentru producție, integrează cu
|
||||
sistemul tău de auth via reverse proxy sau adaugă middleware.
|
||||
Loading…
Add table
Add a link
Reference in a new issue