Spaces:
Sleeping
Sleeping
| """ | |
| Module de chargement des données depuis Hugging Face | |
| """ | |
| import os | |
| import pandas as pd | |
| from datasets import load_dataset | |
| from huggingface_hub import HfApi, hf_hub_download | |
| from config import HF_TOKEN, DATASET_ID, REQUIRED_COLUMNS, MESSAGES | |
| class DataLoader: | |
| """Classe responsable du chargement des données depuis différentes sources""" | |
| def __init__(self): | |
| self.df = None | |
| def load_data(self): | |
| """Charge les données du dataset Hugging Face avec gestion d'erreur robuste""" | |
| try: | |
| print(MESSAGES["loading"]) | |
| print(f"📋 Dataset ID: {DATASET_ID}") | |
| print(f"📋 Token disponible: {'Oui' if HF_TOKEN else 'Non'}") | |
| self.df = None | |
| # 1) Tentative de chargement direct via datasets.load_dataset | |
| try: | |
| print("🔄 Tentative de chargement direct...") | |
| dataset = load_dataset( | |
| DATASET_ID, | |
| split="train", | |
| token=HF_TOKEN, | |
| trust_remote_code=True, | |
| ) | |
| print(f"📊 Dataset chargé: {len(dataset)} exemples") | |
| try: | |
| self.df = dataset.to_pandas() | |
| print("✅ Conversion to_pandas() réussie") | |
| except Exception as pandas_error: | |
| print(f"❌ Erreur to_pandas(): {pandas_error}") | |
| print("🔄 Tentative de conversion manuelle...") | |
| try: | |
| data_list = [] | |
| max_examples = min(len(dataset), 1000) # Limiter pour éviter les problèmes de mémoire | |
| for i, item in enumerate(dataset): | |
| if i >= max_examples: | |
| break | |
| data_list.append(item) | |
| if i < 5: | |
| print(f"📋 Exemple {i}: {list(item.keys())}") | |
| self.df = pd.DataFrame(data_list) | |
| print(f"✅ Conversion manuelle réussie: {len(self.df)} lignes") | |
| except Exception as manual_error: | |
| print(f"❌ Erreur lors de la conversion manuelle: {manual_error}") | |
| self.df = None | |
| except Exception as e: | |
| print(f"❌ Erreur lors du chargement depuis Hugging Face: {str(e)}") | |
| print(f"❌ Type d'erreur: {type(e).__name__}") | |
| # 2) Fallback: récupérer directement les fichiers du repo | |
| try: | |
| fallback_msg = self._fallback_load_from_repo_files() | |
| if self.df is None and fallback_msg: | |
| return f"❌ Erreur lors du chargement du dataset : {str(e)} | Fallback: {fallback_msg}" | |
| except Exception as fallback_error: | |
| print(f"❌ Erreur dans le fallback: {fallback_error}") | |
| # Continue vers le chargement local | |
| # Si on n'a toujours pas de dataframe, arrêter | |
| if self.df is None: | |
| print("⚠️ Aucune méthode de chargement n'a fonctionné") | |
| return MESSAGES["no_data"] | |
| print(f"📊 Données chargées: {len(self.df)} lignes") | |
| print(f"📊 Colonnes disponibles: {list(self.df.columns)}") | |
| # Nettoyage et validation | |
| return self._clean_and_validate_data() | |
| except Exception as e: | |
| print(f"❌ Erreur critique dans load_data: {e}") | |
| import traceback | |
| traceback.print_exc() | |
| return f"❌ Erreur critique lors du chargement: {str(e)}" | |
| def _clean_and_validate_data(self): | |
| """Nettoie et valide les données chargées""" | |
| missing_cols = [col for col in REQUIRED_COLUMNS if col not in self.df.columns] | |
| if missing_cols: | |
| print(f"❌ Colonnes manquantes: {missing_cols}") | |
| self.df = None | |
| return f"❌ Colonnes manquantes: {missing_cols}" | |
| # Nettoyage | |
| initial_len = len(self.df) | |
| self.df = self.df.dropna(subset=REQUIRED_COLUMNS) | |
| print(f"📊 Avant nettoyage: {initial_len} lignes") | |
| print(f"📊 Après nettoyage: {len(self.df)} lignes") | |
| return MESSAGES["success"] | |
| def _fallback_load_from_repo_files(self): | |
| """Fallback pour charger les données en téléchargeant directement les fichiers du repo HF.""" | |
| try: | |
| print("🔄 Tentative de chargement alternatif via fichiers du dépôt Hugging Face...") | |
| api = HfApi() | |
| files = api.list_repo_files(repo_id=DATASET_ID, repo_type="dataset", token=HF_TOKEN) | |
| if not files: | |
| print("❌ Aucun fichier dans le dépôt") | |
| return "Aucun fichier trouvé dans le dépôt." | |
| data_files = [ | |
| f for f in files if f.lower().endswith((".parquet", ".csv", ".tsv", ".json")) | |
| ] | |
| if not data_files: | |
| print("❌ Aucun fichier de données exploitable (csv/tsv/parquet/json)") | |
| return "Aucun fichier exploitable (csv/tsv/parquet/json)." | |
| # Priorité: parquet > csv > tsv > json | |
| for ext in [".parquet", ".csv", ".tsv", ".json"]: | |
| selected = [f for f in data_files if f.lower().endswith(ext)] | |
| if selected: | |
| chosen_ext = ext | |
| selected_files = selected | |
| break | |
| print(f"📂 Fichiers détectés ({chosen_ext}): {selected_files[:5]}{' ...' if len(selected_files) > 5 else ''}") | |
| local_paths = [] | |
| for f in selected_files: | |
| local_path = hf_hub_download( | |
| repo_id=DATASET_ID, | |
| repo_type="dataset", | |
| filename=f, | |
| token=HF_TOKEN, | |
| ) | |
| local_paths.append(local_path) | |
| frames = [] | |
| if chosen_ext == ".parquet": | |
| for p in local_paths: | |
| frames.append(pd.read_parquet(p)) | |
| elif chosen_ext == ".csv": | |
| for p in local_paths: | |
| frames.append(pd.read_csv(p)) | |
| elif chosen_ext == ".tsv": | |
| for p in local_paths: | |
| frames.append(pd.read_csv(p, sep="\t")) | |
| elif chosen_ext == ".json": | |
| for p in local_paths: | |
| try: | |
| frames.append(pd.read_json(p, lines=True)) | |
| except Exception: | |
| frames.append(pd.read_json(p)) | |
| self.df = pd.concat(frames, ignore_index=True) if len(frames) > 1 else frames[0] | |
| print(f"✅ Fallback réussi: {len(self.df)} lignes chargées depuis les fichiers du dépôt") | |
| return None | |
| except Exception as e: | |
| print(f"❌ Fallback échoué: {e}") | |
| # Dernier recours: fichier local d'exemple | |
| return self._load_local_sample() | |
| def _load_local_sample(self): | |
| """Charge un fichier local de secours""" | |
| sample_path = os.path.join(os.path.dirname(__file__), "sample_data.csv") | |
| if os.path.exists(sample_path): | |
| try: | |
| self.df = pd.read_csv(sample_path) | |
| print(f"✅ Chargement du fichier local 'sample_data.csv' ({len(self.df)} lignes)") | |
| return "Chargement via fichier local de secours." | |
| except Exception as e2: | |
| print(f"❌ Échec du chargement du fichier local: {e2}") | |
| return "Aucune source de données disponible." | |
| def get_data(self): | |
| """Retourne les données chargées""" | |
| return self.df | |
| def has_data(self): | |
| """Vérifie si des données sont disponibles""" | |
| return self.df is not None and len(self.df) > 0 | |