Spaces:
Sleeping
Sleeping
File size: 11,848 Bytes
fa6da61 5ae2d69 fa6da61 5ae2d69 fa6da61 5ae2d69 fa6da61 5ae2d69 fa6da61 5ae2d69 fa6da61 3f90d17 fa6da61 3f90d17 fa6da61 3f90d17 fa6da61 3f90d17 fa6da61 5ae2d69 fa6da61 5ae2d69 fa6da61 5ae2d69 fa6da61 5ae2d69 fa6da61 5ae2d69 fa6da61 5ae2d69 fa6da61 5ae2d69 fa6da61 5ae2d69 fa6da61 5ae2d69 fa6da61 5ae2d69 fa6da61 5ae2d69 fa6da61 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 |
from flask import Flask, render_template, request, jsonify
import os
import tempfile
from PIL import Image # Make sure Pillow is installed: pip install Pillow
from google import genai
from google.genai import types # Important pour thinking_config
import uuid
app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = 'static/uploads'
app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024 # 16 MB max upload
# Ensure upload directory exists
os.makedirs(app.config['UPLOAD_FOLDER'], exist_ok=True)
# Google Gemini API setup (ancienne méthode)
def init_gemini():
api_key = os.environ.get('GOOGLE_API_KEY')
if not api_key:
print("WARNING: GOOGLE_API_KEY environment variable not set")
return None
# Note: genai.configure(api_key=api_key) n'est pas nécessaire si on utilise genai.Client()
# Cependant, cela ne fait pas de mal de le laisser si d'autres parties du code s'y attendent.
# genai.configure(api_key=api_key)
return genai.Client(api_key=api_key) # Retourne une instance du client
client = init_gemini() # Store the client instance
# Prompts for analysis
ICONOGRAPHIC_PROMPT = """
je souhaite faire mon travail d'espagnol qui consiste à de l'analyse de documents iconographique. j'aimerais que tu le phase en respectant scrupuleusement la méthodologie suivante. j'aimerais que tu fasses ce travail en espagnol en donnant également la traduction française
Metodología del comentario de un documento iconográfico
Un documento iconográfico es un documento centrado en una imagen. Puede ser: una foto, un cuadro, una publicidad, un dibujo, un tebeo, una tira dibujada, una caricatura, etc. Su comentario respeta las etapas siguientes: la presentación, la descripción, el análisis y la conclusión.
La presentación
Se trata de resaltar los elementos esenciales para identificar el documento:
El título (si existe)
La naturaleza (si es una foto/dibujo/cuadro, en color o blanco y negro)
El autor (el fotógrafo/el dibujante/el publicista...)
La fuente (si existe)
El tema evocado
La descripción
Se trata de decir lo que vemos.
Dominar el vocabulario relativo a la imagen.
Dominar el vocabulario de la situación en el espacio (arriba, abajo, delante, detrás, etc.)
Conocer la organización interna de la descripción.
¿Qué debemos hacer concretamente?
Determinar el número de planos o términos.
(Ej: La imagen tiene dos planos/tres planos/un plan único)
Hacer la descripción plano por plano y acabar antes de pasar al siguiente si hay más de un plano.
Ej: en el primer plano vemos...
Ordenar la descripción de cada plano ( a la derecha, a la izquierda, arriba, abajo, delante, detrás, en el centro, a lo lejos...
¿Qué se debe describir?
Los protagonistas (los personajes):
Los protagonistas
Sexo, edad (hombre o mujer, joven o adulto)
Las posturas (de pie, sentado, arrodillado, etc.)
Los vestidos (ropas)
Los rasgos físicos (color de pelo, gordo, flaco, etc.)
Los rasgos sicológicos (triste, optimista, activo, pasivo, etc.)
Las actitudes (está riendo, triste, llorando, contento, etc.)
Las acciones (lo que están haciendo)
Los objetos alrededor, los colores (fríos o cálidos), los contrastes...
El análisis
Interpretamos y comentamos los elementos de la descripción para comprender el mensaje del autor.
La interpretación debe apoyarse en la descripción porque no se trata de un comentario libre.
Empleamos fórmulas subjetivas porque expresamos hipótesis e impresiones.
Ej: Cuando examinamos...podemos decir que.../ la postura de..., los vestidos...nos permiten imaginar que.../ lo que nos llama la atención es... porque/ los colores cálidos sugieren que...
La conclusión
Se trata de hacer un balance (resumen) de lo dicho de dar una impresión personal. Así:
Anunciamos la conclusión: para concluir/ en suma/en conclusión... podemos decir que...
Precisamos el medio de expresión utilizado: a través de esta foto/mediante este dibujo...
Anunciamos la intención del autor: el dibujante quiere denunciar/ el fotógrafo pretende criticar/ el pintor quiere relevar, sensibilizar, mostrar.
Dar la impresión personal: esta foto (no) me parece interesante/escandaloso/pertinente.
Justificamos nuestra impresión: porque revela una realidad social/política/cultural...
Un modelo: a través de este cuadro, el pintor quiere denunciar las injusticias sociales en África. El cuadro me parece interesante porque releva un fenómeno social recurrente que incita las autoridades a la responsabilidad. La propia imagen ilustra muy bien el tema de las injusticias entre ricos y ricos...
"""
TEXT_PROMPT = """
Je souhaite que tu m'aides avec mon travail despagnol qui consiste en une analyse de texte. J'aimerais que tu réalises cette analyse en respectant scrupuleusement la méthodologie suivante. J'aimerais que tu fasses ce travail (l'analyse) en espagnol, en fournissant également la traduction française de chaque partie de l'analyse.
Je veux pas un Devoir très long. Fais donc de courte phrase
:"
Et voici le plan :
**I - INTRODUCTION**
* **Titre** (Quel est le titre du texte ?)
* **Nature** (De quelle nature est le texte ? / De quoi s'agit-il ?)
* **Auteur** (Qui l'a écrit ?)
* **Origine** (D'où est-il extrait ?)
* **Date de publication** (Quand a-t-il été écrit/publié ?)
* **Genre** (descriptif...)
* **Idée générale** (De quoi parle-t-il en général ?)
* **Intention de l'auteur** (Dans quel but ? / Quelle est son intention ?)
**II - RÉSUMÉ**
* **Les composantes** (la structure / la subdivision du texte)
(Les parties principales du texte et leurs idées)
* **Le résumé lui-même.**
**III - COMMENTAIRE**
* Se concentrer sur les principaux points d'intérêt issus du résumé.
* Discuter, expliquer et développer les principaux points de vue de l'auteur, les aborder de manière cohérente et logique.
* **Tonalité**
* **Style**
**IV - ÉVALUATION**
* Évaluer la valeur du texte.
* L'intérêt du texte.
* Les leçons que tu en as tirées et l'impact sur ton opinion.
**V - OUVERTURE (ou ÉLARGISSEMENT)**
* **Opinion personnelle** (Donner son avis personnel)
* **Ressentis / Sentiments** (J'ai eu des sentiments mitigés à propos de......... / Ce que j'ai ressenti...)
"""
# Nom du modèle utilisé précédemment
MODEL_NAME = "gemini-2.5-flash-preview-04-17" # Ou le modèle que vous utilisiez
def generate_response(file_path, file_type_option):
"""Generate response using Gemini API based on file type option (ancienne méthode d'appel)"""
try:
if not client: # Vérifie si le client a été initialisé
return "Erreur: Le client Google API n'a pas été configuré correctement."
image_data = Image.open(file_path) # Les deux options utilisent une image comme entrée
prompt_to_use = ""
if file_type_option == 'image': # Méthodologie iconographique
prompt_to_use = ICONOGRAPHIC_PROMPT
elif file_type_option == 'text_method_image_input': # Méthodologie textuelle (avec image en entrée)
prompt_to_use = TEXT_PROMPT
else:
return "Erreur: Type d'analyse non reconnu."
response = client.models.generate_content( # Utilisation de client.models.generate_content
model=MODEL_NAME, # Spécifier le modèle ici
contents=[image_data, prompt_to_use],
config=types.GenerateContentConfig(
thinking_config=types.ThinkingConfig(
thinking_budget=8000 # Conserve la configuration thinking_budget
)
),
)
# Accéder au texte de la réponse comme dans la version originale
if response.candidates and response.candidates[0].content and response.candidates[0].content.parts:
return response.candidates[0].content.parts[0].text.strip()
else:
# Gérer le cas où la réponse n'a pas la structure attendue
print(f"Réponse inattendue de l'API Gemini: {response}")
return "Erreur: La réponse de l'API Gemini n'a pas pu être traitée."
except Exception as e:
print(f"Error generating response: {e}")
# Vous pouvez ajouter une gestion d'erreur plus spécifique ici si nécessaire
if "API_KEY_INVALID" in str(e):
return "Erreur: Clé API Google invalide ou non autorisée."
if "billing account" in str(e).lower():
return "Erreur: Problème de facturation avec le compte Google Cloud. Veuillez vérifier votre compte."
return f"Erreur lors de l'analyse: {str(e)}"
@app.route('/')
def index():
return render_template('index.html')
@app.route('/upload', methods=['POST'])
def upload_file():
if 'file' not in request.files:
return jsonify({'success': False, 'error': 'Aucun fichier reçu'}), 400
file = request.files['file']
# 'fileType' indique maintenant la méthodologie ('image' ou 'text_method_image_input')
file_type_option = request.form.get('fileType', 'image')
if file.filename == '':
return jsonify({'success': False, 'error': 'Aucun fichier sélectionné'}), 400
if file:
# Générer un nom de fichier unique
filename = f"{uuid.uuid4()}_{os.path.splitext(file.filename)[0]}{os.path.splitext(file.filename)[1]}"
file_path = os.path.join(app.config['UPLOAD_FOLDER'], filename)
try:
file.save(file_path)
# S'assurer que le fichier est une image avant de continuer
try:
img_check = Image.open(file_path)
img_check.verify() # Vérifie si c'est une image
img_check.close() # Important de fermer le fichier après vérification
# Réouvrir pour l'envoi à l'API car verify() peut corrompre certains formats
# Image.open(file_path) sera fait dans generate_response
except Exception as img_err:
if os.path.exists(file_path):
os.remove(file_path) # Nettoyer le fichier invalide
print(f"Invalid image file uploaded: {img_err}")
return jsonify({'success': False, 'error': 'Le fichier téléversé n\'est pas une image valide.'}), 400
analysis = generate_response(file_path, file_type_option)
# Vérifier si l'analyse a retourné une erreur
if analysis.startswith("Erreur:"):
# Ne pas supprimer le fichier immédiatement si l'analyse a échoué,
# l'utilisateur pourrait vouloir réessayer ou le voir.
return jsonify({'success': False, 'error': analysis}), 500
return jsonify({
'success': True,
'file_url': f"/static/uploads/{filename}", # Utile si vous voulez que l'utilisateur voie l'image téléversée
'analysis': analysis
})
except Exception as e:
print(f"Error in upload_file: {e}")
if os.path.exists(file_path): # Nettoyer si un fichier a été sauvegardé mais une erreur est survenue
try:
os.remove(file_path)
except Exception as e_rem:
print(f"Could not remove file {file_path}: {e_rem}")
return jsonify({'success': False, 'error': f'Une erreur serveur est survenue: {str(e)}'}), 500
# finally:
# Optionnel : nettoyer le fichier téléversé après traitement.
# if os.path.exists(file_path):
# try:
# os.remove(file_path)
# except Exception as e:
# print(f"Error removing uploaded file {file_path}: {e}")
if __name__ == '__main__':
app.run(debug=True) |