import json import datetime import requests from typing import Dict, List, Any, Optional, Union, Tuple class RAG: """ Classe pour l'intégration avec l'API RAG (Retrieval Augmented Generation) Cette classe ne dépend pas de la classe LLM et fonctionne de manière autonome """ def __init__(self): """ Initialisation des attributs de RAG """ # Attributs publics constants (transformés en attributs d'instance) self.sessionID: str = "" # Attributs privés self._reqRAG: requests.Session = requests.Session() self._taContenu: Dict[str, Any] = {} self._m_sChatID: str = "" self._mn_Question: int = 0 # Initialisation par défaut self._reqRAG.headers["Authorization"] = "Bearer ragflow-c4YTNkMzcwZDM1ODExZWZiODA2MDI0Mm" self._reqRAG.headers["Content-Type"] = "application/json" def _urlBase(self) -> str: """ Retourne l'URL de base de l'API RAG """ return "http://10.103.0.100/api/v1/chats/" def _chatID(self) -> str: """ Retourne l'ID de chat actuel ou un ID par défaut """ if self._m_sChatID: return self._m_sChatID else: return "ffb1058ed4b811ef8a900242ac120003" def _set_chatID(self, valeur: str) -> None: """ Définit l'ID de chat """ self._m_sChatID = valeur def _Contenu(self) -> str: """ Sérialise le contenu en JSON """ return json.dumps(self._taContenu) def _urlChat(self) -> str: """ Retourne l'URL complète pour le chat """ return f"{self._urlBase()}{self._chatID()}/" def __del__(self): """ Destructeur - supprime la session de chat si nécessaire """ # Équivalent de: SI mn_Question = 0 OU EnModeTest() ALORS supprimeSessionChat() if self._mn_Question == 0: self._supprimeSessionChat() def _creeSessionChat(self) -> Tuple[bool, str]: """ Crée une nouvelle session de chat Retourne un tuple (succès, message) """ self._taContenu.clear() # Préparation de la requête - sans utiliser l'attribut url directement req_url = f"{self._urlChat()}sessions" # Nom de la session basé sur la date et l'heure actuelles current_datetime = datetime.datetime.now().strftime("%Y%m%d_%H%M%S") self._taContenu["name"] = current_datetime try: response = self._reqRAG.post( url=req_url, json=self._taContenu ) data = json.loads(response.text) if data.get("code") == 0: self.sessionID = data["data"]["id"] return True, self._formateReponse(data["data"]["messages"][0]["content"]) else: return False, self._formateReponse(data.get("message", "Erreur inconnue")) except Exception as e: return False, self._formateReponse(str(e)) def Chat(self, question: str) -> str: """ Envoie une question au chat RAG """ # Crée une session si nécessaire if not self.sessionID: success, response = self._creeSessionChat() if not success: return self._formateReponse(response) # Incrémente le compteur de questions self._mn_Question += 1 # Prépare la requête self._taContenu.clear() self._taContenu["question"] = question self._taContenu["stream"] = False self._taContenu["session_id"] = self.sessionID try: response = self._reqRAG.post( url=self._urlChat() + "completions", json=self._taContenu ) data = json.loads(response.text) if data.get("code") == 0: return self._formateReponse(data["data"]["answer"]) else: return self._formateReponse(data.get("message", "Erreur inconnue")) except Exception as e: return self._formateReponse(str(e)) def _formateReponse(self, reponse: str) -> str: """ Formate la réponse en HTML """ # Conversion en HTML avec style personnalisé html = f"""
{reponse}
""" return html @staticmethod def formateQuestion(question: str) -> str: """ Formate la question en HTML """ # Conversion en HTML avec style personnalisé html = f"""
{question}
""" return html def _supprimeSessionChat(self) -> str: """ Supprime la session de chat actuelle """ if not self.sessionID: return "Aucune session à supprimer" self._taContenu.clear() self._taContenu["ids"] = [self.sessionID] try: response = self._reqRAG.delete( url=self._urlChat() + "/sessions", json=self._taContenu ) data = json.loads(response.text) if data.get("code") == 0: return "OK" else: return data.get("message", "Erreur inconnue") except Exception as e: return str(e)