Danielbrdz commited on
Commit
7ebb33f
·
verified ·
1 Parent(s): 0120543

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +234 -77
app.py CHANGED
@@ -2,6 +2,7 @@ import gradio as gr
2
  import os
3
  import json
4
  import requests
 
5
 
6
  # Configuración de la API de Groq
7
  GROQ_API_KEY = os.environ.get("GROQ_API_KEY")
@@ -14,7 +15,26 @@ MAX_TOKENS = 512
14
  TEMPERATURE = 0.7
15
  TOP_P = 0.95
16
 
17
- def respond(message, history: list[tuple[str, str]]):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
  # Preparar los mensajes en el formato que Groq espera
19
  messages = [{"role": "system", "content": SYSTEM_MESSAGE}]
20
 
@@ -42,111 +62,248 @@ def respond(message, history: list[tuple[str, str]]):
42
  "stream": True
43
  }
44
 
45
- # Realizar la solicitud a la API de Groq con streaming
46
  try:
 
47
  response = requests.post(
48
  GROQ_API_URL,
49
  headers=headers,
50
  json=payload,
51
- stream=True
 
52
  )
53
- response.raise_for_status() # Verificar si la solicitud fue exitosa
54
- except requests.RequestException:
55
- yield "Lo siento, ocurrió un error al procesar tu solicitud."
56
- return
57
 
58
- # Manejar la respuesta en streaming
59
- accumulated_response = ""
60
- for line in response.iter_lines():
61
- if line:
62
- line_text = line.decode('utf-8')
63
- if line_text.startswith("data: "):
64
- data_str = line_text[6:]
65
- if data_str == "[DONE]":
66
- break
67
- try:
68
- data = json.loads(data_str)
69
- if 'choices' in data and len(data['choices']) > 0:
70
- delta = data['choices'][0].get('delta', {})
71
- if 'content' in delta and delta['content']:
72
- token = delta['content']
73
- accumulated_response += token
74
- yield accumulated_response
75
- except json.JSONDecodeError:
76
- continue
77
-
78
- if not accumulated_response:
79
- yield "Lo siento, ocurrió un error al procesar tu solicitud."
80
-
81
- # --- Diseño mejorado ---
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
82
  with gr.Blocks(
83
- theme=gr.themes.Soft(),
84
  css="""
85
  /* Estilos generales para el contenedor */
86
  .gradio-container {
87
  max-width: 100% !important;
88
  margin: 0 auto !important;
89
  padding: 0 !important;
90
- overflow: hidden;
91
  }
92
-
93
  /* Estilos para el chatbot */
94
- .chatbot {
95
- height: calc(100vh - 60px) !important;
96
- overflow-y: auto !important;
97
- border: none !important;
 
 
98
  }
99
-
100
- /* Estilos para los mensajes */
101
- .chatbot .message {
102
- padding: 10px;
103
- border-radius: 10px;
104
- margin-bottom: 10px;
 
 
 
105
  }
106
- .chatbot .message.user {
107
- background-color: #DCF8C6;
108
- align-self: flex-end;
109
- margin-left: 50px;
 
 
 
 
110
  }
111
- .chatbot .message.bot {
112
- background-color: #FFFFFF;
113
- align-self: flex-start;
114
- margin-right: 50px;
 
 
 
 
 
115
  }
116
-
117
- /* Estilos para el input de texto */
118
- .chatInterface .input-container {
119
- padding: 0 !important;
 
 
 
 
 
 
 
 
 
120
  }
121
- .chatInterface .input-container textarea {
122
- border: none !important;
123
- border-radius: 0 !important;
124
- box-shadow: none !important;
125
- padding: 10px;
 
 
 
 
 
 
 
126
  }
127
-
128
- /* Estilos para el botón de envío */
129
- .chatInterface .send-button {
130
- padding: 10px 20px;
131
- font-size: 16px;
 
 
 
 
 
 
 
 
 
132
  }
133
-
134
- /* Media query para pantallas muy pequeñas */
 
 
 
 
 
 
 
 
 
135
  @media (max-width: 600px) {
136
- .chatbot {
137
- height: calc(100vh - 50px) !important;
 
 
 
 
 
138
  }
139
- .chatbot .message.user {
140
- margin-left: 20px;
 
141
  }
142
- .chatbot .message.bot {
143
- margin-right: 20px;
 
 
 
 
 
 
 
144
  }
145
  }
146
  """
147
  ) as demo:
148
- gr.Markdown("# Chatbot Amigable")
149
- gr.ChatInterface(respond)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
150
 
 
151
  if __name__ == "__main__":
152
- demo.launch()
 
 
 
 
 
 
 
2
  import os
3
  import json
4
  import requests
5
+ from typing import Iterator, List, Tuple
6
 
7
  # Configuración de la API de Groq
8
  GROQ_API_KEY = os.environ.get("GROQ_API_KEY")
 
15
  TEMPERATURE = 0.7
16
  TOP_P = 0.95
17
 
18
+ def respond(message: str, history: List[Tuple[str, str]]) -> Iterator[str]:
19
+ """
20
+ Función que maneja la respuesta del chatbot usando la API de Groq.
21
+
22
+ Args:
23
+ message: El mensaje del usuario
24
+ history: Historial de conversación
25
+
26
+ Yields:
27
+ La respuesta del chatbot, token por token
28
+ """
29
+ # Validación de entrada
30
+ if not GROQ_API_KEY:
31
+ yield "Error: No se ha configurado la API key de Groq."
32
+ return
33
+
34
+ if not message.strip():
35
+ yield "Por favor, escribe un mensaje."
36
+ return
37
+
38
  # Preparar los mensajes en el formato que Groq espera
39
  messages = [{"role": "system", "content": SYSTEM_MESSAGE}]
40
 
 
62
  "stream": True
63
  }
64
 
 
65
  try:
66
+ # Realizar la solicitud a la API de Groq con streaming
67
  response = requests.post(
68
  GROQ_API_URL,
69
  headers=headers,
70
  json=payload,
71
+ stream=True,
72
+ timeout=60 # Agregar timeout para evitar colgamientos
73
  )
 
 
 
 
74
 
75
+ # Verificar si la respuesta es exitosa
76
+ response.raise_for_status()
77
+
78
+ # Manejar la respuesta en streaming
79
+ accumulated_response = ""
80
+ for line in response.iter_lines():
81
+ if line:
82
+ # Las líneas comienzan con "data: " en SSE
83
+ line_text = line.decode('utf-8')
84
+ if line_text.startswith("data: "):
85
+ data_str = line_text[6:] # Eliminar el prefijo "data: "
86
+
87
+ # El último mensaje es "data: [DONE]"
88
+ if data_str == "[DONE]":
89
+ break
90
+
91
+ try:
92
+ data = json.loads(data_str)
93
+ if 'choices' in data and len(data['choices']) > 0:
94
+ delta = data['choices'][0].get('delta', {})
95
+ if 'content' in delta and delta['content']:
96
+ token = delta['content']
97
+ accumulated_response += token
98
+ yield accumulated_response
99
+ except json.JSONDecodeError:
100
+ continue
101
+
102
+ if not accumulated_response:
103
+ yield "No se recibió respuesta del modelo. Intenta nuevamente."
104
+
105
+ except requests.exceptions.RequestException as e:
106
+ yield f"Error de conexión: {str(e)}"
107
+ except Exception as e:
108
+ yield f"Error inesperado: {str(e)}"
109
+
110
+
111
+ # Tema personalizado para mejorar la experiencia móvil
112
+ custom_theme = gr.themes.Soft().set(
113
+ body_background_fill="#f7f7f7",
114
+ block_background_fill="#ffffff",
115
+ block_label_background_fill="#ffffff",
116
+ block_border_width="0px",
117
+ button_primary_background_fill="#2563eb",
118
+ button_primary_text_color="#ffffff",
119
+ button_primary_background_fill_hover="#1d4ed8",
120
+ button_secondary_background_fill="#f3f4f6",
121
+ button_secondary_text_color="#374151",
122
+ border_color_primary="#e5e7eb",
123
+ block_radius="8px",
124
+ button_large_radius="8px",
125
+ button_large_padding="10px 20px",
126
+ )
127
+
128
+ # --- Interfaz mejorada ---
129
  with gr.Blocks(
130
+ theme=custom_theme,
131
  css="""
132
  /* Estilos generales para el contenedor */
133
  .gradio-container {
134
  max-width: 100% !important;
135
  margin: 0 auto !important;
136
  padding: 0 !important;
137
+ font-family: 'Inter', sans-serif;
138
  }
139
+
140
  /* Estilos para el chatbot */
141
+ .containing-element {
142
+ height: calc(100vh - 110px) !important;
143
+ max-height: 100vh !important;
144
+ margin: 0 !important;
145
+ padding: 0 !important;
146
+ border-radius: 0 !important;
147
  }
148
+
149
+ /* Mensajes del chatbot */
150
+ .message {
151
+ padding: 10px 15px !important;
152
+ border-radius: 18px !important;
153
+ margin-bottom: 10px !important;
154
+ max-width: 85% !important;
155
+ line-height: 1.5 !important;
156
+ word-wrap: break-word !important;
157
  }
158
+
159
+ /* Mensaje del usuario */
160
+ .user-message {
161
+ background-color: #dcf8c6 !important;
162
+ color: #000000 !important;
163
+ margin-left: auto !important;
164
+ margin-right: 5px !important;
165
+ border-top-right-radius: 5px !important;
166
  }
167
+
168
+ /* Mensaje del asistente */
169
+ .bot-message {
170
+ background-color: #ffffff !important;
171
+ color: #000000 !important;
172
+ margin-right: auto !important;
173
+ margin-left: 5px !important;
174
+ border-top-left-radius: 5px !important;
175
+ box-shadow: 0 1px 2px rgba(0,0,0,0.1) !important;
176
  }
177
+
178
+ /* Contenedor del área de texto */
179
+ .message-inputs {
180
+ position: fixed !important;
181
+ bottom: 0 !important;
182
+ left: 0 !important;
183
+ right: 0 !important;
184
+ padding: 10px 15px !important;
185
+ background-color: #f7f7f7 !important;
186
+ border-top: 1px solid #e5e7eb !important;
187
+ display: flex !important;
188
+ align-items: center !important;
189
+ z-index: 100 !important;
190
  }
191
+
192
+ /* Área de texto */
193
+ .message-inputs textarea {
194
+ border-radius: 20px !important;
195
+ padding: 10px 15px !important;
196
+ resize: none !important;
197
+ max-height: 80px !important;
198
+ overflow-y: auto !important;
199
+ margin-right: 10px !important;
200
+ box-shadow: 0 1px 3px rgba(0,0,0,0.1) !important;
201
+ flex: 1 !important;
202
+ border: 1px solid #e0e0e0 !important;
203
  }
204
+
205
+ /* Botón de enviar */
206
+ .message-inputs .send-btn {
207
+ width: 40px !important;
208
+ height: 40px !important;
209
+ border-radius: 50% !important;
210
+ display: flex !important;
211
+ align-items: center !important;
212
+ justify-content: center !important;
213
+ background-color: #2563eb !important;
214
+ color: white !important;
215
+ cursor: pointer !important;
216
+ padding: 0 !important;
217
+ box-shadow: 0 1px 3px rgba(0,0,0,0.2) !important;
218
  }
219
+
220
+ /* Indicador de escritura */
221
+ .typing-indicator {
222
+ display: flex !important;
223
+ align-items: center !important;
224
+ margin-left: 15px !important;
225
+ margin-bottom: 10px !important;
226
+ opacity: 0.7 !important;
227
+ }
228
+
229
+ /* Para pantallas pequeñas */
230
  @media (max-width: 600px) {
231
+ .message {
232
+ max-width: 90% !important;
233
+ padding: 8px 12px !important;
234
+ }
235
+
236
+ .containing-element {
237
+ height: calc(100vh - 90px) !important;
238
  }
239
+
240
+ .message-inputs {
241
+ padding: 8px 10px !important;
242
  }
243
+
244
+ .message-inputs textarea {
245
+ padding: 8px 12px !important;
246
+ font-size: 14px !important;
247
+ }
248
+
249
+ .send-btn {
250
+ width: 36px !important;
251
+ height: 36px !important;
252
  }
253
  }
254
  """
255
  ) as demo:
256
+ # Título y descripción
257
+ gr.Markdown(
258
+ """
259
+ # 💬 Asistente IA
260
+ ##### Pregúntame lo que quieras saber
261
+ """
262
+ )
263
+
264
+ # Interfaz de chat mejorada
265
+ chatbot = gr.ChatInterface(
266
+ respond,
267
+ chatbot=gr.Chatbot(
268
+ layout="panel",
269
+ bubble_full_width=False,
270
+ show_label=False,
271
+ height="100%",
272
+ container=True,
273
+ render=False
274
+ ),
275
+ textbox=gr.Textbox(
276
+ placeholder="Escribe tu mensaje aquí...",
277
+ container=False,
278
+ scale=7,
279
+ render=False,
280
+ show_label=False,
281
+ min_width=200
282
+ ),
283
+ submit_btn="Enviar",
284
+ retry_btn="♻️",
285
+ undo_btn="↩️",
286
+ clear_btn="🗑️"
287
+ )
288
+
289
+ # Nota de pie de página
290
+ with gr.Accordion("ℹ️ Acerca de", open=False):
291
+ gr.Markdown(
292
+ """
293
+ Este chatbot utiliza el modelo LLama 3 70B a través de la API de Groq.
294
+
295
+ **Información importante:**
296
+ - Las respuestas generadas son creadas por IA y podrían contener inexactitudes.
297
+ - No compartas información sensible o personal.
298
+ """
299
+ )
300
 
301
+ # Lanzar la aplicación
302
  if __name__ == "__main__":
303
+ demo.launch(
304
+ share=False, # No compartir en Hugging Face Spaces
305
+ debug=False, # Evitar información de debug
306
+ quiet=True, # Reducir logs
307
+ show_error=True, # Mostrar errores
308
+ height=800 # Altura predeterminada
309
+ )