Spaces:
Sleeping
Sleeping
File size: 4,468 Bytes
b510add 6cd05a0 b510add 6cd05a0 b510add 3020394 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 | # API (`app/main.py`)
## `POST /analyze`
### Requête (`multipart/form-data`)
| Champ | Type | Requis | Description |
|---|---|---|---|
| `image` | fichier | oui | photo du terminal de pompe (jpeg/png/bmp/webp/tiff) |
| `fuel_price` | float | non | prix du litre configuré côté YELY — fait autorité sur celui lu à l'écran |
| `driver_id` | string | non | identifiant chauffeur (issu du scan QR côté YELY) |
| `pompiste_id` | string | non | identifiant pompiste |
| `station_id` | string | non | identifiant station |
Volontairement **pas** de paramètres techniques (seuil de confiance OCR,
activer/désactiver la détection d'écran...) — contrairement au prototype
précédent, ce endpoint n'expose que les champs métier attendus par le
cahier des charges.
### Réponse (`200`)
Voir `README.md` pour un exemple complet. Tous les champs correspondent
au §13 du cahier des charges — voir `docs/POSTPROCESS_RULES.md` pour le
détail du calcul de chaque valeur, `docs/ARCHITECTURE.md` pour le
pipeline complet.
### Erreurs
| Statut | Cas |
|---|---|
| `400` | type d'image non supporté, ou fichier illisible |
| `500` | erreur interne inattendue pendant le traitement (journalisée dans `logs/api.log` avec la stack trace complète) |
## Chargement du modèle
Le CRNN est chargé **une seule fois** au premier appel (singleton
`_get_model()`), pas à chaque requête — le chargement prend 30-90s sur CPU.
Conséquence pratique : **ne pas lancer `uvicorn --reload` en usage normal**,
chaque rechargement de code redémarre le worker et donc le modèle.
## CORS
`ALLOWED_ORIGINS` (variable d'environnement, origines séparées par des
virgules) contrôle quels domaines peuvent appeler l'API depuis un
navigateur — nécessaire car le frontend (Netlify) et l'API (Hugging Face
Spaces) sont sur des domaines différents. Par défaut `"*"` (permissif,
adapté à une démo) ; à restreindre au domaine Netlify réel en production.
## Journalisation
Chaque appel écrit une ligne JSON dans `logs/api.log` : requête (sans
l'image elle-même) + réponse complète. C'est la base du suivi de
performance — voir `docs/MONITORING.md`.
## Traçabilité
Chaque photo reçue est sauvegardée dans `photos/<transaction_id>.jpg`
et référencée dans la réponse (`photo_reference`) — nécessaire pour
qu'un contrôle a posteriori (station, YELY) puisse revérifier une
transaction contestée, et c'est aussi la matière première de la boucle
d'apprentissage continu (`docs/MONITORING.md`).
## `POST /feedback`
Correction a posteriori d'une transaction déjà traitée par `/analyze` —
voir `docs/MONITORING.md` pour le fonctionnement complet de la boucle
d'apprentissage continu.
| Champ | Type | Requis | Description |
|---|---|---|---|
| `photo_reference` | string | oui | valeur renvoyée par `/analyze` (doit exister dans `photos/`) |
| `corrected_prix` | float | non* | montant réellement correct |
| `corrected_volume` | float | non* | volume réellement correct |
| `corrected_prix_litre` | float | non* | prix du litre réellement correct |
| `corrected_by` | string | non | identifiant de qui corrige (pompiste/station) |
\* au moins un des trois champs `corrected_*` est requis.
Réponses : `200` (`{"success": true, "feedback_id": "..."}`), `404` si
`photo_reference` ne correspond à aucune photo connue, `400` si aucune
correction n'est fournie.
## `GET /metrics`
Aperçu agrégé des performances observées en production, calculé à la volée
à partir de `logs/api.log` (pas de paramètre, pas d'état en mémoire) :
`total_requests`, `success_rate`, `avg_confidence_score`, `blocking_causes`,
`image_quality_distribution`. Voir `docs/MONITORING.md`.
## `GET /failures`
Les `limit` (défaut 20) dernières transactions bloquées (`success=false`),
les plus récentes en premier — alimente la section « Requêtes échouées » de
`web/stats.html`. Chaque élément : `photo_reference`, `message`,
`image_quality`, `detected_liters`, `detected_amount`, `fuel_price`,
`confidence_score`, `transaction_datetime`.
## `GET /photos/{photo_reference}`
Ressert l'image sauvegardée par `/analyze` sous ce `photo_reference` (sert
l'affichage dans le tableau de bord et le formulaire de correction). `404`
si la référence est inconnue. `photo_reference` est assaini côté serveur
(`Path(...).name`) avant résolution sous `PHOTOS_DIR` — aucune traversée de
répertoire possible même si la valeur contient `../`.
|