import logging from flask import Flask, render_template, request, jsonify, session from google import genai import os from datetime import datetime import uuid import io import httpx # Configuration du logging logging.basicConfig( level=logging.DEBUG, format="%(asctime)s [%(levelname)s] %(message)s", datefmt="%Y-%m-%d %H:%M:%S" ) app = Flask(__name__) app.secret_key = os.urandom(24) # Requis pour utiliser les sessions Flask # Configuration de l'API Gemini (idéalement à déplacer dans un fichier de configuration) # os.environ["GOOGLE_API_KEY"] = "VOTRE_GEMINI_API_KEY" client = genai.Client(api_key=os.environ.get("GOOGLE_API_KEY", "GEMINI_API_KEY")) # URL du PDF à analyser (fixe dans cette version) PDF_URL = "http://www.ddl.cnrs.fr/projets/clhass/PageWeb/ressources/fang.pdf" # Variable globale pour stocker le fichier PDF une fois téléchargé pdf_file = None def load_pdf(): """Télécharge et prépare le fichier PDF pour l'analyse""" global pdf_file if pdf_file is None: try: logging.info(f"Début du téléchargement du PDF depuis {PDF_URL}") response = httpx.get(PDF_URL) response.raise_for_status() pdf_content = response.content pdf_io = io.BytesIO(pdf_content) logging.info("Téléchargement réussi. Envoi du PDF à l'API Gemini...") # Télécharger le fichier via l'API Gemini pdf_file = client.files.upload( file=pdf_io, config=dict(mime_type='application/pdf') ) logging.info("PDF téléchargé et préparé avec succès par Gemini!") except Exception as e: logging.error(f"Erreur lors du téléchargement ou de la préparation du PDF: {str(e)}") raise else: logging.debug("PDF déjà chargé, utilisation du cache.") return pdf_file @app.route('/') def index(): # Créer un ID de session unique s'il n'existe pas déjà if 'session_id' not in session: session['session_id'] = str(uuid.uuid4()) logging.info(f"Nouvelle session créée avec l'ID : {session['session_id']}") else: logging.debug(f"Session existante détectée : {session['session_id']}") # Précharger le PDF au démarrage de l'application try: load_pdf() except Exception as e: error_msg = f"Erreur de chargement du PDF: {str(e)}" logging.error(error_msg) return render_template('index.html', error=error_msg) logging.info("Chargement de la page d'accueil réussi.") return render_template('index.html', pdf_url=PDF_URL) @app.route('/chat', methods=['POST']) def chat(): data = request.json user_message = data.get('message', '') logging.info(f"Message utilisateur reçu: {user_message}") # Récupérer ou créer une session de chat pour cet utilisateur session_id = session.get('session_id') chat_session = get_or_create_chat_session(session_id) logging.debug(f"Session de chat pour l'ID {session_id}: {chat_session}") try: # S'assurer que le PDF est chargé pdf_document = load_pdf() logging.debug("PDF document récupéré pour le traitement du chat.") # Construire le prompt pour Gemini avec référence au PDF prompt = f"En vous basant sur le contenu du PDF sur la langue fang, veuillez répondre à: {user_message}" logging.info(f"Prompt construit pour Gemini: {prompt}") # Envoyer le message à Gemini avec le PDF comme contexte et obtenir la réponse logging.info("Envoi du prompt à Gemini...") response = client.models.generate_content( model="gemini-2.0-pro-exp-02-05", contents=[pdf_document, prompt] ) logging.info("Réponse reçue de Gemini.") # Ajouter cette paire question/réponse à l'historique local if not hasattr(app, 'chat_histories'): app.chat_histories = {} logging.debug("Création de l'historique global des chats.") if session_id not in app.chat_histories: app.chat_histories[session_id] = [] logging.debug(f"Création d'un historique de chat pour la session {session_id}.") timestamp = datetime.now().strftime("%H:%M") app.chat_histories[session_id].append({ 'role': 'user', 'content': user_message, 'timestamp': timestamp }) logging.debug("Message utilisateur ajouté à l'historique du chat.") app.chat_histories[session_id].append({ 'role': 'model', 'content': response.text, 'timestamp': timestamp }) logging.debug("Réponse du modèle ajoutée à l'historique du chat.") # Formater l'historique pour l'interface history = app.chat_histories[session_id] logging.info("Historique du chat formaté et prêt à être envoyé.") return jsonify({ 'response': response.text, 'history': history }) except Exception as e: logging.error(f"Erreur lors du traitement du chat: {str(e)}") return jsonify({'error': str(e)}), 500 def get_or_create_chat_session(session_id): """ Récupère une session de chat existante ou en crée une nouvelle. Dans une application réelle, vous pourriez stocker cela dans une base de données. """ if not hasattr(app, 'chat_sessions'): app.chat_sessions = {} logging.debug("Création du dictionnaire global des sessions de chat.") if session_id not in app.chat_sessions: logging.info(f"Aucune session de chat existante pour {session_id}. Création d'une nouvelle session.") app.chat_sessions[session_id] = client.chats.create(model="gemini-2.0-flash") else: logging.debug(f"Session de chat existante retrouvée pour {session_id}.") return app.chat_sessions[session_id] @app.route('/reset', methods=['POST']) def reset_chat(): """Réinitialise la session de chat actuelle""" session_id = session.get('session_id') logging.info(f"Réinitialisation de la session de chat pour {session_id}") # Réinitialiser l'historique stocké if hasattr(app, 'chat_histories') and session_id in app.chat_histories: app.chat_histories[session_id] = [] logging.debug("Historique de chat réinitialisé.") # Réinitialiser la session de chat if hasattr(app, 'chat_sessions') and session_id in app.chat_sessions: app.chat_sessions[session_id] = client.chats.create(model="gemini-2.0-flash") logging.debug("Session de chat réinitialisée dans le dictionnaire des sessions.") return jsonify({'status': 'success'}) if __name__ == '__main__': logging.info("Démarrage de l'application Flask avec le mode debug activé.") app.run(debug=True)