JairoCesar commited on
Commit
ef010e2
·
verified ·
1 Parent(s): a7da8ed

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +36 -31
app.py CHANGED
@@ -6,6 +6,7 @@
6
  # \ VVVV/ \VVVV /
7
  # \____/ \____/
8
  # __________________________________________________________________________________________________________
 
9
  # Adaptado por JAIRO ALEXANDER ERASO MD U Nacional de Colombia, basado en la solicitud del usuario.
10
  #
11
 
@@ -114,9 +115,7 @@ def search_direct(query, data, notif_map):
114
  # Construir la lista de resultados completos
115
  final_results = []
116
  for ficha in results:
117
- # Encontrar todos los detalles de códigos para esa ficha
118
  detalles_codigos = [d for d in data if d.get("FICHA") == ficha]
119
- # Obtener los datos de notificación
120
  info_notificacion = notif_map.get(ficha)
121
  if info_notificacion:
122
  final_results.append({
@@ -132,7 +131,6 @@ def search_with_gemini(query, event_list):
132
  if not model:
133
  return "Error: Modelo de IA no disponible."
134
 
135
- # Prompt cuidadosamente diseñado para obtener una respuesta estructurada
136
  system_prompt = f"""
137
  Eres un asesor experto en SIVIGILA, el sistema de vigilancia en salud pública de Colombia.
138
  Tu tarea es identificar el evento de notificación más relevante basado en la consulta de un profesional de la salud.
@@ -158,7 +156,6 @@ def search_with_gemini(query, event_list):
158
  logger.info(f"✅ Respuesta de Gemini: '{result_text}'")
159
  if result_text == "NO_ENCONTRADO":
160
  return []
161
- # Devolver una lista de nombres de protocolos encontrados
162
  return [name.strip() for name in result_text.split(';') if name.strip()]
163
  else:
164
  logger.warning(f"⚠️ Respuesta de Gemini vacía o bloqueada. Razón: {response.prompt_feedback}")
@@ -174,41 +171,47 @@ def search_with_gemini(query, event_list):
174
  st.title("👨‍⚕️ Asesor Experto en Notificación SIVIGILA - Colombia")
175
  st.markdown("Busque una enfermedad por nombre, sinónimo, código CIE-10 o CIE-11 para obtener información de notificación.")
176
 
177
- # << CAMBIO 1: INICIALIZACIÓN DE SESSION STATE >>
178
- # Nos aseguramos de que las variables existan en la memoria de la sesión
179
  if 'search_results' not in st.session_state:
180
  st.session_state.search_results = None
181
  if 'last_query' not in st.session_state:
182
  st.session_state.last_query = ""
183
 
 
 
 
 
184
 
185
- query = st.text_input(
186
- "Ingrese su búsqueda:",
187
- placeholder="Ej: Dengue, T630, mordedura de serpiente, intoxicación por mercurio...",
188
- help="Puede buscar por nombre de la enfermedad, palabras clave, o códigos CIE."
189
- )
 
 
 
 
190
 
191
- if st.button("Buscar", type="primary"):
 
192
  if not query:
193
  st.warning("Por favor, ingrese un término de búsqueda.")
194
- # Limpiamos resultados si la búsqueda está vacía
195
- st.session_state.search_results = None
196
- st.session_state.last_query = ""
197
  elif data_codigos is None or notificacion_map is None:
198
  st.error("Los datos no se pudieron cargar. La aplicación no puede funcionar.")
199
  else:
200
- # --- Lógica principal al hacer clic en el botón ---
201
  with st.spinner("Buscando..."):
 
202
 
203
- # 1. Intento de búsqueda directa
204
- results = search_direct(query, data_codigos, notificacion_map)
205
 
206
- # 2. Si no hay resultados directos, usar IA
207
- if not results:
208
  logger.info(f"Búsqueda directa para '{query}' no arrojó resultados. Usando Gemini...")
209
  protocol_names = search_with_gemini(query, nombres_eventos_unicos)
210
 
211
- if isinstance(protocol_names, str): # Manejo de errores de Gemini
212
  st.error(protocol_names)
213
  protocol_names = []
214
 
@@ -223,18 +226,23 @@ if st.button("Buscar", type="primary"):
223
  if ficha not in unique_fichas:
224
  results.append(res)
225
  unique_fichas.add(ficha)
226
-
227
- # << CAMBIO 2: GUARDAR RESULTADOS Y CONSULTA EN SESSION STATE >>
228
- # En lugar de mostrar los resultados directamente, los guardamos en la "memoria"
 
 
 
229
  st.session_state.search_results = results
230
  st.session_state.last_query = query
231
 
 
 
 
232
 
233
- # << CAMBIO 3: LÓGICA DE VISUALIZACIÓN SEPARADA >>
234
- # Este bloque se ejecuta en CADA recarga del script. Revisa la "memoria" y muestra lo que hay guardado.
235
  st.markdown("---")
 
 
236
  if st.session_state.search_results is not None:
237
- # `is not None` nos permite manejar el caso de una búsqueda que no arrojó resultados (una lista vacía [])
238
  results = st.session_state.search_results
239
 
240
  if not results:
@@ -248,13 +256,11 @@ if st.session_state.search_results is not None:
248
 
249
  with st.expander(f"**Evento: {info.get('Evento', 'Sin nombre')} (Ficha: {info.get('FICHA', 'N/A')})**", expanded=True):
250
 
251
- # Resumen de notificación
252
  st.subheader("Información de Notificación")
253
 
254
  notif_super = info.get("Notificación superinmedita", "NO") == "SI"
255
-
256
  if notif_super:
257
- st.error(f"**¡ATENCIÓN! Requiere Notificación SUPERINMEDIATA:** {info.get('Descripción superinmediata', '')}")
258
  elif info.get("Notificación Inmediata", "NO") == "SI":
259
  st.warning("**Requiere Notificación Inmediata (dentro de las 24 horas).**")
260
  else:
@@ -265,7 +271,6 @@ if st.session_state.search_results is not None:
265
  fichas_texto = info.get('Fichas a Utilizar', 'No especificado').replace('+', '\n+ ')
266
  st.markdown(f"**Fichas a utilizar:** {fichas_texto}")
267
 
268
- # Detalles de códigos
269
  st.subheader("Códigos Relacionados (CIE-10 y CIE-11)")
270
  for codigo in codigos:
271
  st.markdown(f"""
 
6
  # \ VVVV/ \VVVV /
7
  # \____/ \____/
8
  # __________________________________________________________________________________________________________
9
+ # Versión Final Estable
10
  # Adaptado por JAIRO ALEXANDER ERASO MD U Nacional de Colombia, basado en la solicitud del usuario.
11
  #
12
 
 
115
  # Construir la lista de resultados completos
116
  final_results = []
117
  for ficha in results:
 
118
  detalles_codigos = [d for d in data if d.get("FICHA") == ficha]
 
119
  info_notificacion = notif_map.get(ficha)
120
  if info_notificacion:
121
  final_results.append({
 
131
  if not model:
132
  return "Error: Modelo de IA no disponible."
133
 
 
134
  system_prompt = f"""
135
  Eres un asesor experto en SIVIGILA, el sistema de vigilancia en salud pública de Colombia.
136
  Tu tarea es identificar el evento de notificación más relevante basado en la consulta de un profesional de la salud.
 
156
  logger.info(f"✅ Respuesta de Gemini: '{result_text}'")
157
  if result_text == "NO_ENCONTRADO":
158
  return []
 
159
  return [name.strip() for name in result_text.split(';') if name.strip()]
160
  else:
161
  logger.warning(f"⚠️ Respuesta de Gemini vacía o bloqueada. Razón: {response.prompt_feedback}")
 
171
  st.title("👨‍⚕️ Asesor Experto en Notificación SIVIGILA - Colombia")
172
  st.markdown("Busque una enfermedad por nombre, sinónimo, código CIE-10 o CIE-11 para obtener información de notificación.")
173
 
174
+ # Inicialización de session_state para guardar los resultados
 
175
  if 'search_results' not in st.session_state:
176
  st.session_state.search_results = None
177
  if 'last_query' not in st.session_state:
178
  st.session_state.last_query = ""
179
 
180
+ def clear_search_state():
181
+ """Función para reiniciar el estado de la búsqueda."""
182
+ st.session_state.search_results = None
183
+ st.session_state.last_query = ""
184
 
185
+ # Uso de st.form para agrupar widgets y evitar re-ejecuciones no deseadas
186
+ with st.form(key="search_form"):
187
+ query = st.text_input(
188
+ "Ingrese su búsqueda:",
189
+ placeholder="Ej: Dengue, T630, mordedura de serpiente, 3MC...",
190
+ help="Puede buscar por nombre de la enfermedad, palabras clave, o códigos CIE."
191
+ )
192
+
193
+ submitted = st.form_submit_button("Buscar", type="primary")
194
 
195
+ # La lógica de búsqueda se ejecuta solo cuando el formulario es enviado
196
+ if submitted:
197
  if not query:
198
  st.warning("Por favor, ingrese un término de búsqueda.")
199
+ clear_search_state()
 
 
200
  elif data_codigos is None or notificacion_map is None:
201
  st.error("Los datos no se pudieron cargar. La aplicación no puede funcionar.")
202
  else:
 
203
  with st.spinner("Buscando..."):
204
+ results = []
205
 
206
+ # 1. Búsqueda directa
207
+ direct_results = search_direct(query, data_codigos, notificacion_map)
208
 
209
+ # 2. Si falla, usar IA
210
+ if not direct_results:
211
  logger.info(f"Búsqueda directa para '{query}' no arrojó resultados. Usando Gemini...")
212
  protocol_names = search_with_gemini(query, nombres_eventos_unicos)
213
 
214
+ if isinstance(protocol_names, str):
215
  st.error(protocol_names)
216
  protocol_names = []
217
 
 
226
  if ficha not in unique_fichas:
227
  results.append(res)
228
  unique_fichas.add(ficha)
229
+ else:
230
+ results = []
231
+ else:
232
+ results = direct_results
233
+
234
+ # Guardar resultados en la memoria de la sesión
235
  st.session_state.search_results = results
236
  st.session_state.last_query = query
237
 
238
+ # Botón para limpiar los resultados, visible solo si hay resultados en pantalla
239
+ if st.session_state.search_results is not None:
240
+ st.button("Limpiar Búsqueda", on_click=clear_search_state)
241
 
 
 
242
  st.markdown("---")
243
+
244
+ # La lógica de visualización lee siempre de la memoria de la sesión
245
  if st.session_state.search_results is not None:
 
246
  results = st.session_state.search_results
247
 
248
  if not results:
 
256
 
257
  with st.expander(f"**Evento: {info.get('Evento', 'Sin nombre')} (Ficha: {info.get('FICHA', 'N/A')})**", expanded=True):
258
 
 
259
  st.subheader("Información de Notificación")
260
 
261
  notif_super = info.get("Notificación superinmedita", "NO") == "SI"
 
262
  if notif_super:
263
+ st.error(f"**¡ATENCIÓN! Requiere Notificación SUPERINMEDIATA:** {info.get('Descripción superinmedita', '')}")
264
  elif info.get("Notificación Inmediata", "NO") == "SI":
265
  st.warning("**Requiere Notificación Inmediata (dentro de las 24 horas).**")
266
  else:
 
271
  fichas_texto = info.get('Fichas a Utilizar', 'No especificado').replace('+', '\n+ ')
272
  st.markdown(f"**Fichas a utilizar:** {fichas_texto}")
273
 
 
274
  st.subheader("Códigos Relacionados (CIE-10 y CIE-11)")
275
  for codigo in codigos:
276
  st.markdown(f"""