File size: 4,226 Bytes
f981512
8d45e13
f981512
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37d0313
 
 
a8002d3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5fb4e1e
37d0313
 
 
 
 
 
 
 
 
 
 
f981512
 
 
37d0313
 
 
 
 
 
f981512
 
37d0313
2792969
4ca591f
f981512
 
 
a8002d3
 
4ca591f
 
 
 
 
 
 
 
 
 
 
b99f3a8
 
 
37d0313
 
a8002d3
37d0313
 
 
 
6936b31
f981512
7f4240c
f981512
 
 
 
 
 
 
 
9a49cc3
 
f981512
 
 
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
import os
import time
import uuid
from typing import List, Tuple, Optional, Union
from PIL import Image
import google.generativeai as genai
import gradio as gr
from dotenv import load_dotenv

# Cargar las variables de entorno desde el archivo .env
load_dotenv()
API_KEY = os.getenv("GOOGLE_API_KEY")

if not API_KEY:
    raise ValueError("La clave de API 'GOOGLE_API_KEY' no est谩 configurada en el archivo .env")

# Configuraci贸n del modelo Gemini
genai.configure(api_key=API_KEY)
generation_config = {
    "temperature": 0.7,
    "top_p": 0.9,
    "top_k": 40,
    "max_output_tokens": 8192,
    "response_mime_type": "text/plain",
}

model = genai.GenerativeModel(
    model_name="gemini-1.5-flash",
    generation_config=generation_config,
)

# Inicializar la sesi贸n de chat
chat = model.start_chat(history=[])

# Constantes para el manejo de im谩genes
IMAGE_CACHE_DIRECTORY = "/tmp"
IMAGE_WIDTH = 512
CHAT_HISTORY = List[Tuple[Optional[Union[Tuple[str], str]], Optional[str]]]

# Funci贸n para preprocesar una imagen
def preprocess_image(image: Image.Image) -> Optional[Image.Image]:
    """Redimensiona una imagen manteniendo la relaci贸n de aspecto."""
    if image:
        image_height = int(image.height * IMAGE_WIDTH / image.width)
        return image.resize((IMAGE_WIDTH, image_height))

# Funci贸n para almacenar una imagen en cach茅
def cache_pil_image(image: Image.Image) -> str:
    """Guarda la imagen como archivo JPEG en un directorio temporal."""
    image_filename = f"{uuid.uuid4()}.jpeg"
    os.makedirs(IMAGE_CACHE_DIRECTORY, exist_ok=True)
    image_path = os.path.join(IMAGE_CACHE_DIRECTORY, image_filename)
    image.save(image_path, "JPEG")
    return image_path

# Funci贸n para transformar el historial de Gradio al formato de Gemini
def transform_history(history):
    """Transforma el historial del formato de Gradio al formato que Gemini espera."""
    new_history = []
    for chat in history:
        if chat[0]:  # Mensaje del usuario
            new_history.append({"parts": [{"text": chat[0]}], "role": "user"})
        if chat[1]:  # Respuesta del modelo
            new_history.append({"parts": [{"text": chat[1]}], "role": "model"})
    return new_history

# Funci贸n principal para manejar las respuestas del chat
def response(message, history):
    """Maneja la interacci贸n multimodal y env铆a texto e im谩genes al modelo."""
    global chat

    # Transformar el historial al formato esperado por Gemini
    chat.history = transform_history(history)

    # Obtener el texto del mensaje y las im谩genes cargadas
    text_prompt = message["text"]
    files = message["files"]

    # Procesar im谩genes cargadas
    image_prompts = [preprocess_image(Image.open(file).convert('RGB')) for file in files] if files else []
    if files:
        for file in files:
            image = Image.open(file).convert('RGB')
            image_preview = preprocess_image(image)
            if image_preview:
                # Guardar la imagen y obtener la ruta
                image_path = cache_pil_image(image)
                # Leer la imagen en formato binario para enviarla como Blob
                with open(image_path, "rb") as img_file:
                    img_data = img_file.read()
                # Crear un diccionario con los datos binarios y su tipo MIME
                image_prompt = {
                    "mime_type": "image/jpeg",
                    "data": img_data
                }
                image_prompts.append(image_prompt)

    # Combinar texto e im谩genes para el modelo
    prompts = [text_prompt] + image_prompts
    response = chat.send_message(prompts)
    response.resolve()

    # Generar respuesta car谩cter por car谩cter para una experiencia m谩s fluida
    for i in range(len(response.text)):
        time.sleep(0.01)
        yield response.text[: i + 1]

# Crear la interfaz de usuario
demo = gr.ChatInterface(
    response,
    examples=[{"text": "Describe the image:", "files": []}],
    multimodal=True,
    textbox=gr.MultimodalTextbox(
        file_count="multiple",
        file_types=["image"],
        sources=["upload", "microphone"],
    ),
)

# Lanzar la aplicaci贸n
if __name__ == "__main__":
    demo.launch(debug=True, show_error=True)