JeCabrera commited on
Commit
56a81a0
·
verified ·
1 Parent(s): 2d78253

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +129 -100
app.py CHANGED
@@ -1,132 +1,161 @@
 
 
 
1
  import os
2
  import time
3
  import uuid
4
  from typing import List, Tuple, Optional, Union
5
- from PIL import Image
6
  import google.generativeai as genai
7
  import gradio as gr
 
8
  from dotenv import load_dotenv
9
 
10
  # Cargar las variables de entorno desde el archivo .env
11
  load_dotenv()
12
- API_KEY = os.getenv("GOOGLE_API_KEY")
13
-
14
- if not API_KEY:
15
- raise ValueError("La clave de API 'GOOGLE_API_KEY' no está configurada en el archivo .env")
16
-
17
- # Configuración del modelo Gemini
18
- genai.configure(api_key=API_KEY)
19
- generation_config = {
20
- "temperature": 0.7,
21
- "top_p": 0.9,
22
- "top_k": 40,
23
- "max_output_tokens": 8192,
24
- "response_mime_type": "text/plain",
25
- }
26
-
27
- model = genai.GenerativeModel(
28
- model_name="gemini-1.5-flash",
29
- generation_config=generation_config,
30
- )
31
 
32
- # Inicializar la sesión de chat
33
- chat = model.start_chat(history=[])
 
 
 
 
 
 
34
 
35
- # Constantes para el manejo de imágenes
36
  IMAGE_CACHE_DIRECTORY = "/tmp"
37
  IMAGE_WIDTH = 512
38
  CHAT_HISTORY = List[Tuple[Optional[Union[Tuple[str], str]], Optional[str]]]
39
 
40
- # Función para preprocesar una imagen
41
  def preprocess_image(image: Image.Image) -> Optional[Image.Image]:
42
- """Redimensiona una imagen manteniendo la relación de aspecto."""
43
  if image:
44
  image_height = int(image.height * IMAGE_WIDTH / image.width)
45
  return image.resize((IMAGE_WIDTH, image_height))
46
 
47
- # Función para almacenar una imagen en caché
48
  def cache_pil_image(image: Image.Image) -> str:
49
- """Guarda la imagen como archivo JPEG en un directorio temporal."""
50
  image_filename = f"{uuid.uuid4()}.jpeg"
51
  os.makedirs(IMAGE_CACHE_DIRECTORY, exist_ok=True)
52
  image_path = os.path.join(IMAGE_CACHE_DIRECTORY, image_filename)
53
  image.save(image_path, "JPEG")
54
  return image_path
55
 
56
- # Función para transformar el historial de Gradio al formato de Gemini
57
- def transform_history(history):
58
- """Transforma el historial del formato de Gradio al formato que Gemini espera."""
59
- new_history = []
60
- for chat in history:
61
- if chat[0]: # Mensaje del usuario
62
- new_history.append({"parts": [{"text": chat[0]}], "role": "user"})
63
- if chat[1]: # Respuesta del modelo
64
- new_history.append({"parts": [{"text": chat[1]}], "role": "model"})
65
- return new_history
66
-
67
- # Función principal para manejar las respuestas del chat
68
- def response(message, history):
69
- """Maneja la interacción multimodal y envía texto e imágenes al modelo."""
70
- global chat
71
-
72
- # Transformar el historial al formato esperado por Gemini
73
- chat.history = transform_history(history)
74
-
75
- # Obtener el texto del mensaje y las imágenes cargadas
76
- text_prompt = message["text"]
77
- files = message["files"]
78
-
79
- # Procesar imágenes cargadas
80
- image_prompts = []
81
- if files:
82
- for file in files:
83
- image = Image.open(file).convert('RGB')
84
- image_preview = preprocess_image(image)
85
- if image_preview:
86
- # Guardar la imagen y obtener la ruta
87
- image_path = cache_pil_image(image)
88
- # Leer la imagen en formato binario para enviarla como Blob
89
- with open(image_path, "rb") as img_file:
90
- img_data = img_file.read()
91
- # Crear un diccionario con los datos binarios y su tipo MIME
92
- image_prompt = {
93
- "mime_type": "image/jpeg",
94
- "data": img_data
95
- }
96
- image_prompts.append(image_prompt)
97
-
98
- # Asegurarse de que el texto y las imágenes estén en el formato correcto
99
- prompts = []
100
-
101
  if text_prompt:
102
- # Crear un bloque con la parte de texto para el modelo
103
- prompts.append({"parts": [{"text": text_prompt}], "role": "user"})
104
-
105
- if image_prompts:
106
- # Añadir las imágenes si existen
107
- prompts.extend(image_prompts)
108
-
109
- # Enviar el mensaje al modelo
110
- response = chat.send_message(prompts)
111
- response.resolve()
112
-
113
- # Generar respuesta carácter por carácter para una experiencia más fluida
114
- for i in range(len(response.text)):
115
- time.sleep(0.01)
116
- yield response.text[: i + 1]
117
-
118
- # Crear la interfaz de usuario
119
- demo = gr.ChatInterface(
120
- response,
121
- examples=[{"text": "Describe the image:", "files": []}],
122
- multimodal=True,
123
- textbox=gr.MultimodalTextbox(
124
- file_count="multiple",
125
- file_types=["image"],
126
- sources=["upload", "microphone"],
127
- ),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
128
  )
129
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
130
  # Lanzar la aplicación
131
- if __name__ == "__main__":
132
- demo.launch(debug=True, show_error=True)
 
1
+ TITLE = """<h1 align="center">Gemini Playground ✨</h1>"""
2
+ SUBTITLE = """<h2 align="center">Play with Gemini Pro and Gemini Pro Vision</h2>"""
3
+
4
  import os
5
  import time
6
  import uuid
7
  from typing import List, Tuple, Optional, Union
 
8
  import google.generativeai as genai
9
  import gradio as gr
10
+ from PIL import Image
11
  from dotenv import load_dotenv
12
 
13
  # Cargar las variables de entorno desde el archivo .env
14
  load_dotenv()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15
 
16
+ print("google-generativeai:", genai.__version__)
17
+
18
+ # Obtener la clave de la API de las variables de entorno
19
+ GOOGLE_API_KEY = os.getenv("GOOGLE_API_KEY")
20
+
21
+ # Verificar que la clave de la API esté configurada
22
+ if not GOOGLE_API_KEY:
23
+ raise ValueError("GOOGLE_API_KEY is not set in environment variables.")
24
 
 
25
  IMAGE_CACHE_DIRECTORY = "/tmp"
26
  IMAGE_WIDTH = 512
27
  CHAT_HISTORY = List[Tuple[Optional[Union[Tuple[str], str]], Optional[str]]]
28
 
 
29
  def preprocess_image(image: Image.Image) -> Optional[Image.Image]:
 
30
  if image:
31
  image_height = int(image.height * IMAGE_WIDTH / image.width)
32
  return image.resize((IMAGE_WIDTH, image_height))
33
 
 
34
  def cache_pil_image(image: Image.Image) -> str:
 
35
  image_filename = f"{uuid.uuid4()}.jpeg"
36
  os.makedirs(IMAGE_CACHE_DIRECTORY, exist_ok=True)
37
  image_path = os.path.join(IMAGE_CACHE_DIRECTORY, image_filename)
38
  image.save(image_path, "JPEG")
39
  return image_path
40
 
41
+ def upload(files: Optional[List[str]], chatbot: CHAT_HISTORY) -> CHAT_HISTORY:
42
+ for file in files:
43
+ image = Image.open(file).convert('RGB')
44
+ image_preview = preprocess_image(image)
45
+ if image_preview:
46
+ gr.Image(image_preview).render()
47
+ image_path = cache_pil_image(image)
48
+ chatbot.append(((image_path,), None))
49
+ return chatbot
50
+
51
+ def user(text_prompt: str, chatbot: CHAT_HISTORY):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
  if text_prompt:
53
+ chatbot.append((text_prompt, None))
54
+ return "", chatbot
55
+
56
+ def bot(
57
+ files: Optional[List[str]],
58
+ model_choice: str,
59
+ system_instruction: Optional[str], # Sistema de instrucciones opcional
60
+ chatbot: CHAT_HISTORY
61
+ ):
62
+ if not GOOGLE_API_KEY:
63
+ raise ValueError("GOOGLE_API_KEY is not set.")
64
+
65
+ genai.configure(api_key=GOOGLE_API_KEY)
66
+ generation_config = genai.types.GenerationConfig(
67
+ temperature=0.7,
68
+ max_output_tokens=8192,
69
+ top_k=10,
70
+ top_p=0.9
71
+ )
72
+
73
+ # Usar el valor por defecto para system_instruction si está vacío
74
+ if not system_instruction:
75
+ system_instruction = "1" # O puedes poner un valor predeterminado como "No system instruction provided."
76
+
77
+ text_prompt = [chatbot[-1][0]] if chatbot and chatbot[-1][0] and isinstance(chatbot[-1][0], str) else []
78
+ image_prompt = [preprocess_image(Image.open(file).convert('RGB')) for file in files] if files else []
79
+
80
+ model = genai.GenerativeModel(
81
+ model_name=model_choice,
82
+ generation_config=generation_config,
83
+ system_instruction=system_instruction # Usar el valor por defecto si está vacío
84
+ )
85
+
86
+ response = model.generate_content(text_prompt + image_prompt, stream=True, generation_config=generation_config)
87
+
88
+ chatbot[-1][1] = ""
89
+ for chunk in response:
90
+ for i in range(0, len(chunk.text), 10):
91
+ section = chunk.text[i:i + 10]
92
+ chatbot[-1][1] += section
93
+ time.sleep(0.01)
94
+ yield chatbot
95
+
96
+ # Componente para el acordeón que contiene el cuadro de texto para la instrucción del sistema
97
+ system_instruction_component = gr.Textbox(
98
+ placeholder="Enter system instruction...",
99
+ show_label=True,
100
+ scale=8
101
  )
102
 
103
+ # Definir los componentes de entrada y salida
104
+ chatbot_component = gr.Chatbot(label='Gemini', bubble_full_width=False, scale=2, height=300)
105
+ text_prompt_component = gr.Textbox(placeholder="Message...", show_label=False, autofocus=True, scale=8)
106
+ upload_button_component = gr.UploadButton(label="Upload Images", file_count="multiple", file_types=["image"], scale=1)
107
+ run_button_component = gr.Button(value="Run", variant="primary", scale=1)
108
+ model_choice_component = gr.Dropdown(
109
+ choices=["gemini-1.5-flash", "gemini-2.0-flash-exp", "gemini-1.5-pro"],
110
+ value="gemini-1.5-flash",
111
+ label="Select Model",
112
+ scale=2
113
+ )
114
+
115
+ user_inputs = [text_prompt_component, chatbot_component]
116
+ bot_inputs = [upload_button_component, model_choice_component, system_instruction_component, chatbot_component]
117
+
118
+ # Definir la interfaz de usuario
119
+ with gr.Blocks() as demo:
120
+ gr.HTML(TITLE)
121
+ gr.HTML(SUBTITLE)
122
+ with gr.Column():
123
+ # Campo de selección de modelo arriba
124
+ model_choice_component.render()
125
+ chatbot_component.render()
126
+ with gr.Row():
127
+ text_prompt_component.render()
128
+ upload_button_component.render()
129
+ run_button_component.render()
130
+
131
+ # Crear el acordeón para la instrucción del sistema al final
132
+ with gr.Accordion("System Instruction", open=False): # Acordeón cerrado por defecto
133
+ system_instruction_component.render()
134
+
135
+ run_button_component.click(
136
+ fn=user,
137
+ inputs=user_inputs,
138
+ outputs=[text_prompt_component, chatbot_component],
139
+ queue=False
140
+ ).then(
141
+ fn=bot, inputs=bot_inputs, outputs=[chatbot_component],
142
+ )
143
+
144
+ text_prompt_component.submit(
145
+ fn=user,
146
+ inputs=user_inputs,
147
+ outputs=[text_prompt_component, chatbot_component],
148
+ queue=False
149
+ ).then(
150
+ fn=bot, inputs=bot_inputs, outputs=[chatbot_component],
151
+ )
152
+
153
+ upload_button_component.upload(
154
+ fn=upload,
155
+ inputs=[upload_button_component, chatbot_component],
156
+ outputs=[chatbot_component],
157
+ queue=False
158
+ )
159
+
160
  # Lanzar la aplicación
161
+ demo.queue(max_size=99).launch(debug=False, show_error=True)