Spaces:
Sleeping
Sleeping
| """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 | |