JeCabrera commited on
Commit
03a628f
·
verified ·
1 Parent(s): 4ad1ff2

Update app.py

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