"""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