fix(core): charger gazetteer médicaments edsnlp depuis data/ (torch-free) + log si absent
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -256,24 +256,62 @@ except ImportError:
|
||||
APP_VERSION = "0.11.0-mvp" # incrémenter avant rebuild release
|
||||
|
||||
|
||||
# Gazetteer médicaments extrait de edsnlp/resources/drugs.json et versionné dans
|
||||
# le dépôt (data/edsnlp/drugs.json). Lu EN PREMIER au runtime pour rester complet
|
||||
# dans le build Windows torch-free (Plan 3), où edsnlp — qui importe torch en dur —
|
||||
# n'est pas disponible. En mode frozen, __file__ pointe vers _MEIPASS, donc ce
|
||||
# chemin résout le fichier embarqué (cf _load_bdpm_medication_names).
|
||||
_EDSNLP_DRUGS_DATA_PATH = Path(__file__).parent / "data" / "edsnlp" / "drugs.json"
|
||||
|
||||
|
||||
def _parse_edsnlp_drugs_json(path: Path) -> set:
|
||||
"""Parse un drugs.json edsnlp (code ATC → liste de noms).
|
||||
|
||||
Retourne le set des noms mono-mot de longueur >= 4, en minuscules.
|
||||
Parsing IDENTIQUE à l'historique (garantie de non-régression du gazetteer)."""
|
||||
import json as _json
|
||||
|
||||
data = _json.loads(path.read_text(encoding="utf-8"))
|
||||
result = set()
|
||||
for _code, names in data.items():
|
||||
for name in names:
|
||||
if " " not in name and len(name) >= 4:
|
||||
result.add(name.lower())
|
||||
return result
|
||||
|
||||
|
||||
def _load_edsnlp_drug_names() -> set:
|
||||
"""Charge les noms de médicaments mono-mot depuis edsnlp/resources/drugs.json.
|
||||
Retourne un set lowercase. Fallback silencieux si edsnlp absent."""
|
||||
"""Charge les noms de médicaments mono-mot pour la whitelist anti-faux-positif.
|
||||
|
||||
Ordre de résolution (torch-free) :
|
||||
1. data/edsnlp/drugs.json (fichier versionné, 0 dépendance edsnlp/torch) ;
|
||||
2. fallback : package edsnlp (BASE_DIR/resources/drugs.json), comportement
|
||||
historique en mode dev ;
|
||||
3. échec total → log.warning explicite + set() (dégradation rendue visible).
|
||||
|
||||
Retourne un set lowercase."""
|
||||
# 1. Fichier data versionné (disponible aussi en frozen torch-free).
|
||||
try:
|
||||
if _EDSNLP_DRUGS_DATA_PATH.exists():
|
||||
return _parse_edsnlp_drugs_json(_EDSNLP_DRUGS_DATA_PATH)
|
||||
except Exception as exc: # fichier corrompu → on tente le fallback
|
||||
log.debug("Lecture %s échouée : %s", _EDSNLP_DRUGS_DATA_PATH, exc)
|
||||
|
||||
# 2. Fallback package edsnlp (dev).
|
||||
try:
|
||||
import edsnlp as _edsnlp
|
||||
drugs_path = _edsnlp.BASE_DIR / "resources" / "drugs.json"
|
||||
if not drugs_path.exists():
|
||||
return set()
|
||||
import json as _json
|
||||
data = _json.loads(drugs_path.read_text(encoding="utf-8"))
|
||||
result = set()
|
||||
for _code, names in data.items():
|
||||
for name in names:
|
||||
if " " not in name and len(name) >= 4:
|
||||
result.add(name.lower())
|
||||
return result
|
||||
except Exception:
|
||||
return set()
|
||||
if drugs_path.exists():
|
||||
return _parse_edsnlp_drugs_json(drugs_path)
|
||||
except Exception as exc:
|
||||
log.debug("Fallback package edsnlp indisponible : %s", exc)
|
||||
|
||||
# 3. Échec total : rendre la dégradation visible (risque de sur-masquage).
|
||||
log.warning(
|
||||
"Gazetteer médicaments edsnlp indisponible (ni data/edsnlp/drugs.json "
|
||||
"ni package edsnlp) — whitelist médicaments réduite, risque de sur-masquage"
|
||||
)
|
||||
return set()
|
||||
|
||||
|
||||
def _load_bdpm_medication_names() -> set:
|
||||
|
||||
Reference in New Issue
Block a user