feat(vision): il worker che espone il runner, versione stampata al build
Container FastAPI separato (Dockerfile.vision, python:3.13-slim) che espone run_graph/engine_version del Task 2 via POST /run e GET /health, cosi' l'immagine del server principale non importa mai VisionSuite. engine_version() ora legge VISION_ENGINE_VERSION se impostata, altrimenti ricade su git rev-parse nel checkout di sviluppo, e non inventa mai un valore: senza nessuna delle due solleva un errore esplicito. Nel container il fallback a git non puo' funzionare (.git del submodule punta fuori dal build context), quindi Dockerfile.vision prende il commit come build arg e lo fissa in ambiente; i compose file lo passano da VISION_ENGINE_VERSION. Nessuna porta pubblicata e nessuna label Traefik sul servizio vision: e' raggiungibile solo dal server, su tmflow-net. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014BBnuACZSCJqXrMYC3LUMU
This commit is contained in:
@@ -403,6 +403,51 @@ uv sync --extra vision --extra dev --python 3.13
|
||||
uv run --python 3.13 --extra vision --extra dev pytest src/vision/tests
|
||||
```
|
||||
|
||||
Lo stesso vale per `src/vision_worker/tests/`, il piccolo servizio FastAPI che
|
||||
espone il runner: dipende da `src.vision.runner` e quindi eredita lo stesso
|
||||
vincolo su Python 3.13.
|
||||
|
||||
```bash
|
||||
uv run --python 3.13 --extra vision --extra dev pytest src/vision_worker/tests
|
||||
```
|
||||
|
||||
### Il worker di visione (`Dockerfile.vision`)
|
||||
|
||||
Il worker gira in un container separato dal server FastAPI principale, così
|
||||
che l'immagine dell'API resti leggera e un aggiornamento di VisionSuite non
|
||||
richieda di riavviare il traffico di produzione. Il container non pubblica
|
||||
porte verso l'esterno: lo raggiunge solo il server, all'indirizzo interno
|
||||
`http://vision:8100` sulla rete `tmflow-net`.
|
||||
|
||||
Ogni misura riporta il commit di VisionSuite che l'ha prodotta
|
||||
(`engine_version`), perché una stazione che misura con un motore diverso da
|
||||
quello atteso deve poter essere identificata. Il container, però, non ha
|
||||
accesso al repository Git del progetto principale — `vendor/visionsuite` è un
|
||||
submodule, e la copia `.git` che lo collega al repository ospitante non
|
||||
viene inclusa nel contesto di build — quindi la versione non può essere
|
||||
scoperta al volo dentro l'immagine. Va invece **stampata al momento del
|
||||
build**, leggendo il commit dalla macchina che esegue `docker compose build`,
|
||||
dove il repository Git è presente per intero:
|
||||
|
||||
```bash
|
||||
VISION_ENGINE_VERSION=$(git -C vendor/visionsuite rev-parse HEAD) \
|
||||
docker compose -f docker-compose.dev.yml build vision
|
||||
```
|
||||
|
||||
La variabile viene passata come build argument (`ARG VISION_ENGINE_VERSION`
|
||||
in `Dockerfile.vision`) e fissata nell'immagine come variabile d'ambiente, in
|
||||
modo che il worker la trovi già pronta a ogni avvio senza doverla ricalcolare.
|
||||
Fuori da un container, in un checkout di sviluppo locale, la stessa funzione
|
||||
ricade su `git rev-parse` se la variabile non è impostata — comodo per
|
||||
lavorare sul runner senza Docker. Ma se un'immagine viene costruita senza
|
||||
passare `VISION_ENGINE_VERSION`, quel ripiego non ha nulla su cui appoggiarsi:
|
||||
il `.git` del submodule non arriva nel contesto di build, e il worker
|
||||
risponde con un errore esplicito su `/health` invece di indovinare una
|
||||
versione o restituire `"unknown"`. La build va quindi sempre lanciata con la
|
||||
variabile impostata, sia in sviluppo sia in produzione, con lo stesso comando
|
||||
mostrato sopra (sostituendo `docker-compose.dev.yml` con `docker-compose.yml`
|
||||
in produzione).
|
||||
|
||||
Stato corrente su `V3.0.0`: **360 pass, 0 fail** (212 backend + 148 frontend).
|
||||
|
||||
Alcuni test frontend non renderizzano niente e leggono i sorgenti, perché guardano
|
||||
@@ -430,6 +475,7 @@ Copia `.env.example` in `.env` e configura:
|
||||
| `CLIENT_SECRET_KEY` | Chiave segreta Flask (sessioni, CSRF) |
|
||||
| `API_SERVER_URL` | URL del backend visto dal client (es. `http://server:8000`) |
|
||||
| `STATION_CODE` | **Per-tablet** — codice stazione (es. `ST-001`). Senza, il client mostra errore configurazione. |
|
||||
| `VISION_WORKER_URL` | Indirizzo interno del worker di visione (default: `http://vision:8100`, mai esposto fuori da `tmflow-net`) |
|
||||
| `UPLOAD_DIR` | Percorso upload file (default: `uploads`, project root) |
|
||||
| `MAX_UPLOAD_SIZE_MB` | Limite dimensione upload (default 50) |
|
||||
| `RATE_LIMIT_LOGIN` | Login req/min/IP (default 5) |
|
||||
|
||||
Reference in New Issue
Block a user