05 — Vue runtime¶
Deux séquences clés : génération du dataset (préalable, batch) et consommation par la vitrine (chemin chaud, runtime de l'API).
Séquence A — Génération du dataset enrichi (batch)¶
Exécutée via make dataset (ou python scripts/generate_dataset.py). Reproductible
via la seed unique 42.
sequenceDiagram
autonumber
participant CLI as scripts/generate_dataset.py
participant Seeds as data/skills + data/seed
participant Gen as TraceGenerationService
participant Enr as EnrichmentService
participant FS as data/generated/
CLI->>Seeds: load skills + resources
CLI->>Gen: generate(ScenarioConfig(n=100, seed=42))
Gen-->>Gen: tirer 4 archetypes + jitter σ=0.10
Gen-->>Gen: échantillonnage stratifié par domaine
Gen-->>CLI: 100 learners + 5800 LearningTrace
CLI->>FS: traces.jsonl (xAPI direct)
CLI->>Enr: enrich(trace) pour chaque
Enr-->>CLI: EnrichedTrace (+ skills résolues)
CLI->>FS: enriched.jsonl
CLI->>FS: learners.jsonl (ground truth, archetype inclus)
Variante — via le LRC réel (échantillon)¶
Si l'opérateur passe --via-lrc=http://localhost:8080, le script ajoute :
sequenceDiagram
autonumber
participant CLI as generate_dataset.py
participant Enc as CsvTraceEncoder
participant LRC as "LRC (HTTP)"
participant FS as data/generated/
CLI->>CLI: pick (Léa + 1/archetype) — 4 apprenants, 199 traces
CLI->>Enc: encode chaque trace en ligne CSV "Mathia"
CLI->>FS: sample_mathia.csv
CLI->>LRC: POST /convert_custom (multipart)
LRC-->>CLI: stream JSONL xAPI (199 statements)
CLI->>FS: traces_via_lrc.jsonl
Voir How-to — ingest via LRC et ADR 006.
Séquence B — Boot de l'API (lifespan)¶
Au démarrage de uvicorn ... --factory, avant que le serveur accepte la première
requête :
sequenceDiagram
autonumber
participant U as uvicorn
participant APP as "create_app()"
participant LIFE as lifespan
participant FS as data/generated/
participant Prof as LearnerProfileBuilder
participant Clu as ClusteringService
participant ST as SentenceTransformers
participant Reco as RecommendationService
U->>APP: instancie FastAPI
APP->>LIFE: enter
LIFE->>FS: load skills, resources, learners, enriched
LIFE->>Prof: build_all → 100 profils
LIFE->>Clu: fit (k_min=2, k_max=8, seed=42)
Clu-->>LIFE: k=4, silhouette=0.309, assignations
LIFE->>ST: charger MiniLM multilingue (≈ 5-15 s au 1er boot)
LIFE->>Reco: instancier + embed 33 ressources
loop pour chaque profil
LIFE->>Reco: recommend(top_n=10)
end
LIFE-->>APP: PreloadedState sur app.state
APP-->>U: prêt à servir
Coût total : ~5 s en chaud, ~25 s au tout premier boot (download du modèle ST). Les requêtes HTTP ne touchent jamais sklearn ni le modèle ST.
Séquence C — Visualisation pour Léa (chemin chaud)¶
L'utilisateur sélectionne « Léa Martin » dans la vitrine Streamlit.
sequenceDiagram
autonumber
participant Browser
participant ST as Vitrine Streamlit
participant API as API FastAPI
participant State as PreloadedState
Browser->>ST: ouvre /, navigue "Apprenant"
ST->>API: GET /learners
API->>State: list[Learner]
State-->>API: 100 entrées
API-->>ST: JSON
ST->>ST: cache (@st.cache_data, ttl=300)
Note over ST: Léa sélectionnée par défaut
par En parallèle
ST->>API: GET /profile/{lea_id}
ST->>API: GET /clusters/assignment/{lea_id}
ST->>API: GET /clusters
ST->>API: GET /recommend/{lea_id}?n=5
end
API->>State: lookup direct (aucun calcul)
State-->>API: profil + assignation + cluster meta + recos préchargées
API-->>ST: JSON
ST-->>Browser: rendu — profil + cluster + 5 recos avec explication
Les 4 appels sont parallélisés par le navigateur (HTTP/2 ou pipelining), et chacun est caché par Streamlit côté front. Temps d'affichage perçu : < 200 ms après le 1er load.