Spaces:
Sleeping
Sleeping
File size: 3,841 Bytes
72c8410 | 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 106 107 108 109 110 111 112 113 114 115 116 117 | """Chargement et traitement des données FAQ à partir des fichiers CSV."""
import logging
from pathlib import Path
from typing import List, Tuple
import pandas as pd
logger = logging.getLogger(__name__)
class FAQEntry:
"""Représentation d'une entrée FAQ."""
def __init__(self, formulation: str, theme: str, response: str) -> None:
"""
Initialiser une entrée FAQ.
Args:
formulation: La question de la FAQ
theme: Le thème/catégorie de la FAQ
response: La réponse associée
"""
self.formulation: str = formulation
self.theme: str = theme
self.response: str = response
def load_faq_data(
formulations_path: str,
responses_path: str,
delimiter: str = ";"
) -> List[FAQEntry]:
"""
Charger et fusionner les données FAQ à partir de deux fichiers CSV.
Les fichiers sont joints via la colonne 'theme'.
Args:
formulations_path: Chemin vers faq_formulations.csv (colonnes: formulation, theme)
responses_path: Chemin vers faq_responses.csv (colonnes: theme, response)
delimiter: Délimiteur du CSV (par défaut: ";")
Returns:
Liste d'objets FAQEntry contenant formulation, theme et réponse
Raises:
FileNotFoundError: Si un fichier CSV n'existe pas
ValueError: Si les fichiers sont vides ou mal formés
"""
# Vérifier existence des fichiers
if not Path(formulations_path).exists():
raise FileNotFoundError(f"Fichier non trouvé: {formulations_path}")
if not Path(responses_path).exists():
raise FileNotFoundError(f"Fichier non trouvé: {responses_path}")
try:
# Charger les CSV
logger.info(f"Chargement formulations depuis: {formulations_path}")
df_formulations: pd.DataFrame = pd.read_csv(
formulations_path,
delimiter=delimiter,
encoding="utf-8"
)
logger.info(f"Chargement réponses depuis: {responses_path}")
df_responses: pd.DataFrame = pd.read_csv(
responses_path,
delimiter=delimiter,
encoding="utf-8"
)
# Valider les colonnes
required_cols_form = {"formulation", "theme"}
required_cols_resp = {"theme", "response"}
if not required_cols_form.issubset(df_formulations.columns):
raise ValueError(
f"Colonnes manquantes dans formulations. Attendu: {required_cols_form}, "
f"Trouvé: {set(df_formulations.columns)}"
)
if not required_cols_resp.issubset(df_responses.columns):
raise ValueError(
f"Colonnes manquantes dans réponses. Attendu: {required_cols_resp}, "
f"Trouvé: {set(df_responses.columns)}"
)
# Joindre les dataframes sur la colonne 'theme'
logger.info("Fusion des données par theme...")
df_merged: pd.DataFrame = df_formulations.merge(
df_responses,
on="theme",
how="inner"
)
if df_merged.empty:
raise ValueError("Aucune correspondance trouvée entre formulations et réponses")
# Créer les objets FAQEntry
faq_entries: List[FAQEntry] = [
FAQEntry(
formulation=row["formulation"].strip(),
theme=row["theme"].strip(),
response=row["response"].strip()
)
for _, row in df_merged.iterrows()
]
logger.info(f"✓ {len(faq_entries)} entrées FAQ chargées avec succès")
return faq_entries
except pd.errors.ParserError as e:
raise ValueError(f"Erreur lors du parsing du CSV: {e}")
except Exception as e:
logger.error(f"Erreur lors du chargement des FAQ: {e}")
raise
|