import pickle import pandas as pd import os import logging from typing import Dict, List, Optional import numpy as np # Chemins des fichiers DATA_DIR = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'data') EMBEDDINGS_PATH = os.path.join(DATA_DIR, 'embeddings_azure_50d.pkl') CLICKS_PATH = os.path.join(DATA_DIR, 'clicks_sample.csv') # Cache global _embeddings_cache: Optional[np.ndarray] = None _user_data_cache: Optional[Dict[int, List[int]]] = None def _load_pickle_file(file_path: str) -> np.ndarray: """Charge un fichier pickle.""" with open(file_path, 'rb') as f: return pickle.load(f) def _load_csv_file(file_path: str) -> pd.DataFrame: """Charge un fichier CSV.""" return pd.read_csv(file_path) def _process_clicks_data(clicks_df: pd.DataFrame) -> Dict[int, List[int]]: """Convertit le DataFrame en dictionnaire user->articles.""" user_data = {} for _, row in clicks_df.iterrows(): user_id = int(row['user_id']) article_id = int(row['click_article_id']) if user_id not in user_data: user_data[user_id] = [] user_data[user_id].append(article_id) return user_data def load_embeddings() -> np.ndarray: """Charge les embeddings avec cache.""" global _embeddings_cache if _embeddings_cache is None: try: _embeddings_cache = _load_pickle_file(EMBEDDINGS_PATH) logging.info(f"Embeddings loaded: {_embeddings_cache.shape}") except Exception as e: logging.error(f"Error loading embeddings: {str(e)}") raise return _embeddings_cache def load_user_data() -> Dict[int, List[int]]: """Charge les données utilisateur avec cache.""" global _user_data_cache if _user_data_cache is None: try: clicks_df = _load_csv_file(CLICKS_PATH) _user_data_cache = _process_clicks_data(clicks_df) logging.info(f"User data loaded: {len(_user_data_cache)} users") except Exception as e: logging.error(f"Error loading user data: {str(e)}") raise return _user_data_cache def get_user_articles(user_id: int) -> Optional[List[int]]: """Récupère les articles d'un utilisateur.""" user_data = load_user_data() return user_data.get(user_id) def check_data_files() -> bool: """Vérifie que tous les fichiers de données existent.""" files_to_check = [EMBEDDINGS_PATH, CLICKS_PATH] for file_path in files_to_check: if not os.path.exists(file_path): logging.error(f"Missing data file: {file_path}") return False return True def get_available_users() -> List[int]: """Retourne la liste de tous les user_ids disponibles.""" user_data = load_user_data() return list(user_data.keys())