Spaces:
Sleeping
Sleeping
from flask import Flask, render_template, request, jsonify | |
import os | |
import tempfile | |
from PIL import Image | |
from google import genai | |
from google.genai import types | |
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 | |
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 | |
return genai.Client(api_key=api_key) | |
client = init_gemini() | |
# 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 faire une analyse de texte en espagnol 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 texto en espa帽ol: | |
1. Presentaci贸n del documento | |
- Autor y contexto hist贸rico | |
- Naturaleza del texto (literario, period铆stico, discurso, etc.) | |
- Tema principal | |
2. An谩lisis de la estructura | |
- Divisi贸n en partes l贸gicas | |
- Identificaci贸n de la organizaci贸n de las ideas | |
3. An谩lisis del contenido | |
- Ideas principales y secundarias | |
- Intenci贸n del autor | |
- Recursos ling眉铆sticos utilizados | |
- Vocabulario y campo sem谩ntico | |
4. Conclusi贸n | |
- S铆ntesis del an谩lisis | |
- Aportaci贸n personal | |
- Relevancia del texto en su contexto | |
Por favor, analiza este texto seg煤n la metodolog铆a indicada, proporcionando el an谩lisis completo en espa帽ol y su traducci贸n al franc茅s. | |
""" | |
def generate_response(file_path, file_type): | |
"""Generate response using Gemini API based on file type""" | |
try: | |
if not client: | |
return "Error: Google API key not configured properly." | |
if file_type == 'image': | |
image_data = Image.open(file_path) | |
response = client.models.generate_content( | |
model="gemini-2.5-flash-preview-04-17", | |
contents=[image_data, ICONOGRAPHIC_PROMPT], | |
config=types.GenerateContentConfig( | |
thinking_config=types.ThinkingConfig( | |
thinking_budget=8000 | |
) | |
), | |
) | |
return response.candidates[0].content.parts[0].text.strip() | |
elif file_type == 'text': | |
with open(file_path, 'r', encoding='utf-8') as f: | |
text_content = f.read() | |
response = client.models.generate_content( | |
model="gemini-2.5-flash-preview-04-17", | |
contents=[text_content, TEXT_PROMPT], | |
config=types.GenerateContentConfig( | |
thinking_config=types.ThinkingConfig( | |
thinking_budget=8000 | |
) | |
), | |
) | |
return response.candidates[0].content.parts[0].text.strip() | |
except Exception as e: | |
print(f"Error generating response: ") | |
return f"Error durante el an谩lisis: " | |
def index(): | |
return render_template('index.html') | |
def upload_file(): | |
if 'file' not in request.files: | |
return jsonify({'error': 'No file part'}), 400 | |
file = request.files['file'] | |
file_type = request.form.get('fileType', 'image') | |
if file.filename == '': | |
return jsonify({'error': 'No selected file'}), 400 | |
if file: | |
# Generate a unique filename | |
filename = f"{uuid.uuid4()}_{file.filename}" | |
file_path = os.path.join(app.config['UPLOAD_FOLDER'], filename) | |
file.save(file_path) | |
# Generate analysis | |
analysis = generate_response(file_path, file_type) | |
return jsonify({ | |
'success': True, | |
'file_url': f"/static/uploads/{filename}", | |
'analysis': analysis | |
}) | |
if __name__ == '__main__': | |
app.run(debug=True) |