Mariam-france / app.py
Docfile's picture
Update app.py
eda0c9b verified
raw
history blame
7.03 kB
from flask import Flask, render_template, request, Response
from google import genai
from google.genai import types
import os
import logging
import json
def load_prompt():
return " fais une dissertation "
# Configuration du logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s'
)
app = Flask(__name__)
# Configuration du client Gemini
token = os.environ.get("TOKEN")
client = genai.Client(api_key=token)
# Configuration par défaut
default_generation_config = types.GenerateContentConfig(
temperature=1,
max_output_tokens=8192
)
STANDARD_MODEL_NAME = "gemini-2.5-flash"
DEEPTHINK_MODEL_NAME = "gemini-2.5-pro"
@app.route('/')
def index():
logging.info("Page index demandée.")
return render_template('index.html')
@app.route('/api/francais', methods=['POST','GET'])
def gpt_francais():
# FIX: The frontend uses EventSource which sends a GET request.
# Data must be read from `request.args` (query string) instead of `request.form`.
logging.info(f"Requête {request.method} reçue sur /api/francais")
french_prompt = request.args.get('sujet', '').strip()
choix = request.args.get('choix', '').strip()
style = request.args.get('style', '').strip()
use_deepthink = request.args.get('use_deepthink', 'false').lower() == 'true'
logging.info(f"Données reçues : sujet='{french_prompt[:50]}', choix='{choix}', style='{style}', deepthink={use_deepthink}")
if not french_prompt:
logging.warning("Sujet vide, retour erreur.")
return Response(f"data: {json.dumps({'type': 'error', 'content': 'Erreur: Le sujet ne peut pas être vide.'})}\n\n",
mimetype='text/event-stream'), 400
model_to_use = DEEPTHINK_MODEL_NAME if use_deepthink else STANDARD_MODEL_NAME
logging.info(f"Modèle utilisé : {model_to_use}")
try:
system_instruction = load_prompt()
except Exception as e:
logging.exception("Erreur lors du chargement du prompt système.")
system_instruction = "Tu es un assistant spécialisé en français."
user_prompt = f"Sujet: {french_prompt}\nType: {choix}\nStyle: {style}"
config = types.GenerateContentConfig(
system_instruction=system_instruction,
temperature=1,
max_output_tokens=8192
)
if use_deepthink:
config.thinking_config = types.ThinkingConfig(include_thoughts=True)
def generate_stream():
try:
logging.info("Démarrage du streaming de génération...")
thoughts = ""
answer = ""
for chunk in client.models.generate_content_stream(
model=model_to_use,
contents=[user_prompt],
config=config
):
for part in chunk.candidates[0].content.parts:
if not part.text:
continue
elif hasattr(part, 'thought') and part.thought:
if not thoughts:
logging.info("Premiers éléments de réflexion envoyés.")
yield f"data: {json.dumps({'type': 'thoughts_start'})}\n\n"
thoughts += part.text
yield f"data: {json.dumps({'type': 'thought', 'content': part.text})}\n\n"
else:
if not answer:
logging.info("Premiers éléments de réponse envoyés.")
yield f"data: {json.dumps({'type': 'answer_start'})}\n\n"
answer += part.text
yield f"data: {json.dumps({'type': 'answer', 'content': part.text})}\n\n"
logging.info("Fin du streaming de génération.")
yield f"data: {json.dumps({'type': 'done'})}\n\n"
except Exception:
logging.exception("Erreur pendant la génération de contenu.")
yield f"data: {json.dumps({'type': 'error', 'content': 'Erreur serveur pendant la génération.'})}\n\n"
return Response(generate_stream(), mimetype='text/event-stream')
@app.route('/api/etude-texte', methods=['POST','GET'])
def gpt_francais_cc():
logging.info("Requête POST reçue sur /api/etude-texte")
if 'images' not in request.files:
logging.warning("Aucun fichier image reçu.")
return Response(f"data: {json.dumps({'type': 'error', 'content': 'Aucun fichier image envoyé.'})}\n\n",
mimetype='text/event-stream'), 400
images = request.files.getlist('images')
if not images or not images[0].filename:
logging.warning("Liste d'images vide.")
return Response(f"data: {json.dumps({'type': 'error', 'content': 'Aucune image sélectionnée.'})}\n\n",
mimetype='text/event-stream'), 400
def generate_image_analysis():
try:
logging.info(f"Nombre d'images reçues : {len(images)}")
try:
system_instruction = load_prompt()
except Exception:
logging.exception("Erreur lors du chargement du prompt système pour analyse texte.")
system_instruction = "Tu es un assistant spécialisé dans l'analyse de textes et de documents."
content = ["Réponds aux questions présentes dans les images."]
for img in images:
if img.filename:
logging.info(f"Traitement image : {img.filename}")
img_data = img.read()
img_part = types.Part.from_bytes(
data=img_data,
mime_type=img.content_type or 'image/jpeg'
)
content.append(img_part)
config = types.GenerateContentConfig(
system_instruction=system_instruction,
temperature=0.7,
max_output_tokens=4096
)
logging.info("Démarrage du streaming d'analyse d'image...")
for chunk in client.models.generate_content_stream(
model=STANDARD_MODEL_NAME,
contents=content,
config=config
):
for part in chunk.candidates[0].content.parts:
if part.text:
yield f"data: {json.dumps({'type': 'content', 'content': part.text})}\n\n"
logging.info("Fin du streaming d'analyse d'image.")
# Note: The original code was missing a final "done" signal here.
yield f"data: {json.dumps({'type': 'done'})}\n\n"
except Exception:
logging.exception("Erreur pendant l'analyse d'image.")
yield f"data: {json.dumps({'type': 'error', 'content': 'Erreur serveur pendant l\\'analyse de l\\'image.'})}\n\n"
return Response(generate_image_analysis(), mimetype='text/event-stream')
if __name__ == '__main__':
logging.info("Démarrage du serveur Flask avec Gemini SDK...")
app.run(debug=True)