Ajoute un logging JSON structure (meme convention que LoggerService cote apps/api) a services/tech-step-intent-service : chaque appel POST /v1/process journalise locale/texte en entree et entites/intent/score en sortie, chaque POST /v1/train journalise les uid entraines et les compteurs resultants. Chatter interne de spaCy mis a WARNING pour ne pas noyer ces lignes. Bug trouve et corrige en verifiant les octets bruts d'un log reel (pas juste son affichage terminal) : l'encodage par defaut de sys.stdout sur Windows produisait de vrais octets UTF-8 invalides pour tout texte accentue journalise (le francais des etapes de recette) — corrige par sys.stdout.reconfigure(encoding="utf-8") au demarrage. LOG_LEVEL configurable (INFO par defaut), documente dans le README du service et .env.example. Verifie : 30/30 pytest (3 nouveaux tests sur le formateur JSON), smoke test HTTP reel confirmant au niveau des octets que les caracteres accentues sont preserves, lint complet du monorepo. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
58 lines
2.1 KiB
Python
58 lines
2.1 KiB
Python
"""`POST /v1/train` — appelé par `apps/api` (`IntentServiceClient.train`,
|
|
`TechStepClassifierService._train`) une fois par locale à chaque warm-up
|
|
serveur, avec l'intégralité de `TECH_STEP_TRAINING_DATA` filtrée pour cette
|
|
locale. Voir `LocalePipeline.train` pour ce que "reconstruit à neuf" signifie
|
|
concrètement.
|
|
"""
|
|
|
|
import logging
|
|
|
|
from fastapi import APIRouter, Depends, HTTPException, status
|
|
|
|
from ..locale_pipeline import TrainEntry, UnsupportedLocaleError
|
|
from ..pipeline_registry import registry
|
|
from ..schemas import TrainRequest, TrainResponse
|
|
from ..security import require_valid_secret
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
router = APIRouter(dependencies=[Depends(require_valid_secret)])
|
|
|
|
|
|
@router.post("/v1/train", response_model=TrainResponse)
|
|
def train(request: TrainRequest) -> TrainResponse:
|
|
entries = [
|
|
TrainEntry(uid=entry.uid, synonyms=entry.synonyms, utterances=entry.utterances)
|
|
for entry in request.entries
|
|
]
|
|
|
|
logger.info(
|
|
"tech-step NLP train starting",
|
|
extra={"locale": request.locale, "uids": [entry.uid for entry in entries]},
|
|
)
|
|
try:
|
|
label_count, utterance_count, synonym_count = registry.train(request.locale, entries)
|
|
except UnsupportedLocaleError as err:
|
|
logger.warning("tech-step NLP train rejected", extra={"locale": request.locale, "error": str(err)})
|
|
# 422, pas 500 : une locale non supportée dans une requête de
|
|
# `apps/api` est une erreur de configuration/version-skew entre les
|
|
# deux services (voir le contrat documenté dans le plan de
|
|
# migration), pas un échec inattendu du service lui-même.
|
|
raise HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail=str(err)) from err
|
|
|
|
logger.info(
|
|
"tech-step NLP train done",
|
|
extra={
|
|
"locale": request.locale,
|
|
"labelCount": label_count,
|
|
"utteranceCount": utterance_count,
|
|
"synonymCount": synonym_count,
|
|
},
|
|
)
|
|
|
|
return TrainResponse(
|
|
locale=request.locale,
|
|
label_count=label_count,
|
|
utterance_count=utterance_count,
|
|
synonym_count=synonym_count,
|
|
)
|