C2MV commited on
Commit
89cadbc
·
verified ·
1 Parent(s): d7a5a15

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +38 -31
app.py CHANGED
@@ -1,8 +1,10 @@
1
  """
2
- CÓDIGO COMPLETO Y MEJORADO - VERSIÓN 4.0
3
- - AÑADIDO: Una función que crea automáticamente el archivo de ejemplo `archivo.xlsx`.
4
- - MEJORADO: El diagrama de flujo ahora está en formato de arte ASCII puro para máxima compatibilidad.
5
- - MANTIENE: La robusta y clara arquitectura de agentes, la lógica del pipeline y la UI funcional.
 
 
6
  """
7
 
8
  import gradio as gr
@@ -41,7 +43,7 @@ except Exception as e:
41
  analysis_client = None
42
 
43
  # ============================================================================
44
- # 🤖 SISTEMA DE AGENTES (DEFINICIONES MEJORADAS)
45
  # ============================================================================
46
 
47
  class LoggingAgent:
@@ -92,19 +94,39 @@ class StructureValidationAgent:
92
  logger.info("📐 StructureValidationAgent activado.")
93
 
94
  def validate(self, file_obj) -> (bool, str, pd.DataFrame):
 
 
 
 
 
 
 
 
 
95
  self.log_agent.register("StructureValidationAgent", "Iniciando validación de estructura de archivo.")
 
96
  try:
97
- file_content = file_obj.read()
98
- file_name = file_obj.name
99
-
 
 
 
 
 
 
 
 
 
100
  if file_name.endswith('.csv'):
101
- df = pd.read_csv(io.BytesIO(file_content))
102
  elif file_name.endswith(('.xls', '.xlsx')):
103
- df = pd.read_excel(io.BytesIO(file_content))
104
  else:
105
  msg = "Formato de archivo no soportado. Por favor, sube un archivo .csv, .xls o .xlsx."
106
  self.log_agent.register("StructureValidationAgent", "Error de validación: Formato no soportado", msg)
107
  return False, msg, None
 
108
 
109
  if df.empty:
110
  msg = "Validación fallida: El archivo está vacío o no contiene datos."
@@ -137,9 +159,7 @@ class StructureValidationAgent:
137
  class ModelSelectionAgent:
138
  """
139
  Agente 3: El estratega del análisis. Si el usuario lo habilita, este agente
140
- entra en acción para optimizar la selección de modelos. Basándose en las
141
- características de los datos, infiere el tipo de experimento y filtra la
142
- selección de modelos del usuario para quedarse solo con los más adecuados.
143
  """
144
  GROWTH_MODELS = ['logistic', 'gompertz', 'baranyi', 'richards', 'stannard', 'huang']
145
  FERMENTATION_MODELS = ['monod', 'contois', 'andrews', 'moser', 'tessier']
@@ -190,7 +210,7 @@ log_agent = LoggingAgent()
190
  validation_agent = StructureValidationAgent(log_agent)
191
  model_selection_agent = ModelSelectionAgent(log_agent)
192
 
193
- # --- LÓGICA DEL PIPELINE ---
194
 
195
  def create_dummy_plot():
196
  fig = go.Figure(go.Scatter(x=[], y=[]))
@@ -332,13 +352,8 @@ def process_complete_pipeline_with_agents(
332
  return (parse_plot_data(plot_info), df_data, analysis_report, implementation_code,
333
  final_report_path, "\n\n".join(progress_updates), final_report_path, log_agent.get_report())
334
 
335
- # --- FUNCIÓN PARA CREAR ARCHIVO DE EJEMPLO ---
336
  def create_dummy_excel_file():
337
- """
338
- Crea un archivo Excel de ejemplo (`archivo.xlsx`) si no existe,
339
- para que el componente `gr.Examples` funcione de inmediato.
340
- Es necesario tener `openpyxl` instalado: pip install openpyxl
341
- """
342
  examples_dir = "examples"
343
  file_path = os.path.join(examples_dir, "archivo.xlsx")
344
 
@@ -347,25 +362,18 @@ def create_dummy_excel_file():
347
 
348
  if not os.path.exists(file_path):
349
  logger.info(f"Creando archivo de ejemplo en: {file_path}")
350
- # Datos simulados de crecimiento microbiano
351
  time = np.arange(0, 25, 2)
352
  biomass = 0.2 + (5 - 0.2) / (1 + np.exp(4 - 0.5 * time)) + np.random.rand(len(time)) * 0.1
353
  substrate = 10 * np.exp(-0.1 * time) + np.random.rand(len(time)) * 0.2
354
 
355
- df = pd.DataFrame({
356
- 'Time': time,
357
- 'Biomass': biomass,
358
- 'Substrate': substrate
359
- })
360
-
361
  df.to_excel(file_path, index=False)
362
  logger.info("✅ Archivo de ejemplo creado.")
363
 
364
- # --- INTERFAZ DE USUARIO (UI) CON GRADIO ---
365
  theme = gr.themes.Soft(primary_hue="blue", secondary_hue="indigo", neutral_hue="slate")
366
  custom_css = ".file-upload { border: 2px dashed #3b82f6; } button.primary { background: linear-gradient(135deg, #3b82f6 0%, #8b5cf6 100%); }"
367
 
368
- # Diagrama de flujo en formato ASCII puro
369
  ascii_diagram = r"""
370
  ```
371
  [ 📁 Usuario sube Archivo Excel/CSV ]
@@ -409,11 +417,10 @@ ascii_diagram = r"""
409
  """
410
 
411
  if __name__ == "__main__":
412
- # Asegúrate de que el archivo de ejemplo exista antes de lanzar la UI
413
  create_dummy_excel_file()
414
 
415
  with gr.Blocks(theme=theme, title="BioTech Analysis & Report Generator", css=custom_css) as demo:
416
- gr.Markdown("# 🧬 BioTech Analysis & Report Generator v4.0")
417
  gr.Markdown("## Full Pipeline: Biotech Modeling → AI Reporting")
418
 
419
  with gr.Accordion("🤖 Cómo Funcionan los Agentes de IA (Diagrama de Flujo)", open=False):
 
1
  """
2
+ CÓDIGO COMPLETO Y CORREGIDO - VERSIÓN 4.1
3
+ - CORREGIDO: El error `AttributeError: 'NamedString' object has no attribute 'read'`.
4
+ - CAUSA: El agente `StructureValidationAgent` no manejaba correctamente el objeto pasado por `gr.Examples`.
5
+ - SOLUCIÓN: El agente ahora obtiene la ruta del archivo desde el atributo `.name` del objeto de Gradio
6
+ y pasa la ruta directamente a Pandas, lo que funciona tanto para cargas directas como para ejemplos.
7
+ - MANTIENE: Toda la arquitectura de agentes, la creación de archivos de ejemplo y el diagrama ASCII.
8
  """
9
 
10
  import gradio as gr
 
43
  analysis_client = None
44
 
45
  # ============================================================================
46
+ # 🤖 SISTEMA DE AGENTES (CON CORRECCIÓN)
47
  # ============================================================================
48
 
49
  class LoggingAgent:
 
94
  logger.info("📐 StructureValidationAgent activado.")
95
 
96
  def validate(self, file_obj) -> (bool, str, pd.DataFrame):
97
+ """
98
+ Valida el archivo de entrada de forma robusta.
99
+
100
+ Args:
101
+ file_obj: El objeto de archivo subido por el usuario en Gradio.
102
+
103
+ Returns:
104
+ tuple: (es_valido, mensaje, dataframe_o_none)
105
+ """
106
  self.log_agent.register("StructureValidationAgent", "Iniciando validación de estructura de archivo.")
107
+
108
  try:
109
+ # --- INICIO DE LA CORRECCIÓN ---
110
+ # En lugar de leer el objeto, obtenemos su ruta (atributo .name).
111
+ # Esto funciona tanto para cargas directas como para ejemplos de Gradio.
112
+ if not hasattr(file_obj, 'name'):
113
+ msg = "Error interno: El objeto de archivo recibido de Gradio no es válido."
114
+ self.log_agent.register("StructureValidationAgent", "Error crítico: Objeto de archivo inválido", msg)
115
+ return False, msg, None
116
+
117
+ file_path = file_obj.name
118
+ file_name = os.path.basename(file_path)
119
+
120
+ # Usamos la ruta del archivo directamente con Pandas.
121
  if file_name.endswith('.csv'):
122
+ df = pd.read_csv(file_path)
123
  elif file_name.endswith(('.xls', '.xlsx')):
124
+ df = pd.read_excel(file_path)
125
  else:
126
  msg = "Formato de archivo no soportado. Por favor, sube un archivo .csv, .xls o .xlsx."
127
  self.log_agent.register("StructureValidationAgent", "Error de validación: Formato no soportado", msg)
128
  return False, msg, None
129
+ # --- FIN DE LA CORRECCIÓN ---
130
 
131
  if df.empty:
132
  msg = "Validación fallida: El archivo está vacío o no contiene datos."
 
159
  class ModelSelectionAgent:
160
  """
161
  Agente 3: El estratega del análisis. Si el usuario lo habilita, este agente
162
+ entra en acción para optimizar la selección de modelos.
 
 
163
  """
164
  GROWTH_MODELS = ['logistic', 'gompertz', 'baranyi', 'richards', 'stannard', 'huang']
165
  FERMENTATION_MODELS = ['monod', 'contois', 'andrews', 'moser', 'tessier']
 
210
  validation_agent = StructureValidationAgent(log_agent)
211
  model_selection_agent = ModelSelectionAgent(log_agent)
212
 
213
+ # --- LÓGICA DEL PIPELINE (Sin cambios) ---
214
 
215
  def create_dummy_plot():
216
  fig = go.Figure(go.Scatter(x=[], y=[]))
 
352
  return (parse_plot_data(plot_info), df_data, analysis_report, implementation_code,
353
  final_report_path, "\n\n".join(progress_updates), final_report_path, log_agent.get_report())
354
 
355
+ # --- FUNCIÓN PARA CREAR ARCHIVO DE EJEMPLO (Sin cambios) ---
356
  def create_dummy_excel_file():
 
 
 
 
 
357
  examples_dir = "examples"
358
  file_path = os.path.join(examples_dir, "archivo.xlsx")
359
 
 
362
 
363
  if not os.path.exists(file_path):
364
  logger.info(f"Creando archivo de ejemplo en: {file_path}")
 
365
  time = np.arange(0, 25, 2)
366
  biomass = 0.2 + (5 - 0.2) / (1 + np.exp(4 - 0.5 * time)) + np.random.rand(len(time)) * 0.1
367
  substrate = 10 * np.exp(-0.1 * time) + np.random.rand(len(time)) * 0.2
368
 
369
+ df = pd.DataFrame({'Time': time, 'Biomass': biomass, 'Substrate': substrate})
 
 
 
 
 
370
  df.to_excel(file_path, index=False)
371
  logger.info("✅ Archivo de ejemplo creado.")
372
 
373
+ # --- INTERFAZ DE USUARIO (UI) CON GRADIO (Sin cambios) ---
374
  theme = gr.themes.Soft(primary_hue="blue", secondary_hue="indigo", neutral_hue="slate")
375
  custom_css = ".file-upload { border: 2px dashed #3b82f6; } button.primary { background: linear-gradient(135deg, #3b82f6 0%, #8b5cf6 100%); }"
376
 
 
377
  ascii_diagram = r"""
378
  ```
379
  [ 📁 Usuario sube Archivo Excel/CSV ]
 
417
  """
418
 
419
  if __name__ == "__main__":
 
420
  create_dummy_excel_file()
421
 
422
  with gr.Blocks(theme=theme, title="BioTech Analysis & Report Generator", css=custom_css) as demo:
423
+ gr.Markdown("# 🧬 BioTech Analysis & Report Generator v4.1")
424
  gr.Markdown("## Full Pipeline: Biotech Modeling → AI Reporting")
425
 
426
  with gr.Accordion("🤖 Cómo Funcionan los Agentes de IA (Diagrama de Flujo)", open=False):