Skip to content

feat(ml): export training-ready (GeoJSON / COCO / QuPath) + figement dataset_snapshot #365

Description

@Yanstart

Contexte

Sans export training-ready, le pipeline ML continu ne peut pas
réutiliser les annotations validées. Toute version d'un modèle doit
pouvoir être ré-entraînée à partir d'un dataset figé et
reproductible.

Référence : docs/architecture/ANNOTATION_DATA_MODEL_AUDIT.md — gaps G3 + G11.

Objectif

  1. Endpoint d'export POST /api/v1/datasets/export qui produit un
    dataset training-ready dans plusieurs formats (GeoJSON, COCO,
    QuPath GeoJSON)
  2. Table dataset_snapshots qui fige filter_criteria + contenu
  3. FK ml_models.training_dataset_id → dataset_snapshots.id pour tracer
    quelle version d'un modèle vient de quel dataset

Approche technique proposée

Migration 011_dataset_snapshots.py

CREATE TABLE dataset_snapshots (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id VARCHAR(100) NOT NULL,
    name VARCHAR(200) NOT NULL,
    version VARCHAR(50) NOT NULL,
    filter_criteria JSONB NOT NULL,
    sample_count INTEGER NOT NULL,
    label_distribution JSONB NOT NULL,
    storage_uri TEXT NOT NULL,
    storage_format VARCHAR(20) NOT NULL,
    created_by VARCHAR(200),
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    UNIQUE (tenant_id, name, version)
);

ALTER TABLE ml_models
  ADD COLUMN training_dataset_id UUID REFERENCES dataset_snapshots(id);

Endpoint d'export

@router.post("/datasets/export", response_model=DatasetSnapshotOut)
async def export_dataset(
    name: str,
    version: str,
    filter_criteria: AnnotationFilter,
    format: Literal["geojson", "coco", "qupath_geojson"] = "geojson",
    current_user: CurrentUser = Depends(require_role("ADMIN_TECHNIQUE")),
):
    """Fige un export training-ready + crée un dataset_snapshot."""
    ...

Formats supportés

Format Cas d'usage Sortie
geojson FeatureCollection lisible QGIS / dev .geojson (1 fichier)
coco Compatible Detectron2, MMDetection, torchvision annotations.json + manifest
qupath_geojson Import dans QuPath (power users) .geojson avec metadata QuPath

Stockage

Acceptance criteria (fonctionnel)

  • Migration Alembic 011_* créée et testée
  • Modèle SQLAlchemy DatasetSnapshot créé
  • Endpoint POST /api/v1/datasets/export opérationnel
  • 3 exporters dans services/ml/exporters/ (geojson, coco, qupath_geojson)
  • Endpoint GET /api/v1/datasets (liste) + GET /api/v1/datasets/{id} (détail)
  • Endpoint GET /api/v1/datasets/{id}/download (récupère le fichier figé)
  • ml_models.training_dataset_id ajouté + FK validée
  • Documentation docs/architecture/DATASET_SNAPSHOTS.md

Review checklist (conditions de validation pour le reviewer PR)

Code

  • Tests unitaires : 1 par exporter × 3 cas (vide / single label / multi-label) = 9 tests
  • Tests d'intégration : export → snapshot persisté → download → checksum match
  • Couverture > 75 % sur services/ml/exporters/
  • Validation roundtrip : export COCO → reimport via N4 → même set d'annotations

Reproductibilité

  • Snapshot immuable : un export à T puis modification d'annotations puis re-download retourne les données d'origine
  • filter_criteria re-exécutable : POST avec même filter à T+1 produit un snapshot différent si annotations ont changé

Stockage

  • Garde-fou disk space : refus si projection > N MB (configurable)
  • Chiffrement at-rest si STORAGE_ENCRYPTION_KEY configurée
  • Garbage collection (TTL configurable) — issue séparée ou TODO documenté

Sécurité & tenant

  • Tenant isolation : user du tenant A ne peut PAS exporter annotations du tenant B
  • require_role("ADMIN_TECHNIQUE") ou MEDECIN selon politique (à acter en review)
  • Audit log généré sur chaque export

Documentation

  • Swagger UI : exemples complets de payload
  • docs/architecture/ANNOTATION_DATA_MODEL_AUDIT.md : G3 + G11 marqués RESOLVED

Dépendances

Hors-scope

  • Génération de splits train/val/test (laissé au consommateur)
  • DICOM-SR export (envisageable plus tard)
  • Versioning des exports avec diff (issue séparée)

Références

  • docs/architecture/ANNOTATION_DATA_MODEL_AUDIT.md §3 (G3, G11)
  • COCO format spec
  • QuPath GeoJSON import doc

Metadata

Metadata

Assignees

No one assigned

    Labels

    domain:mlDomaine: Machine Learningpriority:criticalBloquant - A faire immediatementtype:featureNouvelle fonctionnalite

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions