Spaces:
Sleeping
Sleeping
import gradio as gr | |
from gradio_client import Client, handle_file | |
import pandas as pd | |
import json | |
import tempfile | |
import os | |
from datetime import datetime | |
import plotly.graph_objects as go | |
import plotly.express as px | |
import matplotlib.pyplot as plt | |
import numpy as np | |
# Configuración de clientes | |
biotech_client = Client("C2MV/BiotechU4") | |
analysis_client = Client("C2MV/Project-HF-2025") | |
# Tema personalizado | |
theme = gr.themes.Soft( | |
primary_hue="blue", | |
secondary_hue="indigo", | |
neutral_hue="slate", | |
spacing_size="md", | |
radius_size="lg", | |
) | |
def process_biotech_data(file, models, component, use_de, maxfev, exp_names): | |
"""Procesa los datos en el primer endpoint de BiotechU4""" | |
try: | |
result = biotech_client.predict( | |
file=handle_file(file.name), | |
models=models, | |
component=component, | |
use_de=use_de, | |
maxfev=maxfev, | |
exp_names=exp_names, | |
theme=False, | |
api_name="/run_analysis_wrapper" | |
) | |
return result | |
except Exception as e: | |
return None, None, f"Error en el análisis: {str(e)}" | |
def create_dummy_plot(): | |
"""Crea un plot de ejemplo cuando no se pueden parsear los datos""" | |
fig = go.Figure() | |
# Añadir datos de ejemplo | |
x = np.linspace(0, 10, 100) | |
y = np.exp(-x/5) * np.cos(2*np.pi*x) | |
fig.add_trace(go.Scatter( | |
x=x, | |
y=y, | |
mode='lines', | |
name='Datos de ejemplo', | |
line=dict(color='blue', width=2) | |
)) | |
fig.update_layout( | |
title="Visualización de Resultados", | |
xaxis_title="Tiempo", | |
yaxis_title="Valor", | |
template="plotly_white", | |
height=500 | |
) | |
return fig | |
def parse_plot_data(plot_dict): | |
"""Convierte el diccionario del plot en un objeto visualizable""" | |
if not plot_dict: | |
return create_dummy_plot() | |
try: | |
# Si es un diccionario con tipo y plot | |
if isinstance(plot_dict, dict) and 'type' in plot_dict and 'plot' in plot_dict: | |
plot_type = plot_dict['type'] | |
plot_data = plot_dict['plot'] | |
# Si es plotly | |
if plot_type == 'plotly': | |
if isinstance(plot_data, str): | |
try: | |
# Intentar parsear como JSON | |
plot_json = json.loads(plot_data) | |
# Crear figura de Plotly desde JSON | |
fig = go.Figure(plot_json) | |
return fig | |
except: | |
# Si falla, intentar evaluar como dict | |
try: | |
import ast | |
plot_dict = ast.literal_eval(plot_data) | |
fig = go.Figure(plot_dict) | |
return fig | |
except: | |
pass | |
elif isinstance(plot_data, dict): | |
# Si ya es un diccionario, crear figura directamente | |
fig = go.Figure(plot_data) | |
return fig | |
# Si es matplotlib, crear una figura simple | |
elif plot_type == 'matplotlib': | |
return create_dummy_plot() | |
# Si es altair o bokeh, también crear dummy | |
elif plot_type in ['altair', 'bokeh']: | |
return create_dummy_plot() | |
# Si el plot_dict ya es una figura válida, devolverla | |
if hasattr(plot_dict, 'data') or hasattr(plot_dict, 'figure'): | |
return plot_dict | |
except Exception as e: | |
print(f"Error parsing plot: {str(e)}") | |
# En caso de error, devolver plot dummy | |
return create_dummy_plot() | |
def download_results_as_csv(df_data): | |
"""Descarga los resultados como CSV desde BiotechU4""" | |
try: | |
result = biotech_client.predict( | |
df=df_data, | |
api_name="/download_results_excel" | |
) | |
return result | |
except Exception as e: | |
# Si falla, crear un archivo temporal con los datos | |
if df_data and 'data' in df_data and 'headers' in df_data: | |
try: | |
df = pd.DataFrame(df_data['data'], columns=df_data['headers']) | |
temp_file = tempfile.NamedTemporaryFile(mode='w', suffix='.csv', delete=False) | |
df.to_csv(temp_file.name, index=False) | |
temp_file.close() | |
return temp_file.name | |
except: | |
pass | |
return None | |
def generate_claude_report(csv_file, model, detail_level, language, additional_specs): | |
"""Genera el informe usando Claude""" | |
try: | |
result = analysis_client.predict( | |
files=[handle_file(csv_file)], | |
model=model, | |
detail=detail_level, | |
language=language, | |
additional_specs=additional_specs, | |
api_name="/process_and_store" | |
) | |
return result | |
except Exception as e: | |
return f"Error en el análisis: {str(e)}", "" | |
def export_report(format_type, language, analysis, code): | |
"""Exporta el informe en el formato seleccionado""" | |
try: | |
result = analysis_client.predict( | |
format=format_type, | |
language=language, | |
api_name="/handle_export" | |
) | |
return result[1], result[0] | |
except Exception as e: | |
return None, f"Error al exportar: {str(e)}" | |
def process_complete_pipeline( | |
file, | |
models, | |
component, | |
use_de, | |
maxfev, | |
exp_names, | |
claude_model, | |
detail_level, | |
language, | |
additional_specs, | |
export_format | |
): | |
"""Pipeline completo de procesamiento""" | |
progress_updates = [] | |
if not file: | |
empty_fig = create_dummy_plot() | |
return empty_fig, None, None, None, None, "❌ Por favor, sube un archivo para procesar" | |
if not models: | |
empty_fig = create_dummy_plot() | |
return empty_fig, None, None, None, None, "❌ Por favor, selecciona al menos un modelo" | |
# Paso 1: Procesar con BiotechU4 | |
progress_updates.append("🔄 Procesando datos biotecnológicos...") | |
plot_data, df_data, status = process_biotech_data( | |
file, models, component, use_de, maxfev, exp_names | |
) | |
if plot_data is None or "Error" in str(status): | |
empty_fig = create_dummy_plot() | |
return empty_fig, None, None, None, None, status | |
# Parsear el plot correctamente | |
plot = parse_plot_data(plot_data) | |
progress_updates.append("✅ Análisis biotecnológico completado") | |
# Paso 2: Descargar resultados como CSV | |
progress_updates.append("📥 Descargando resultados...") | |
csv_file = download_results_as_csv(df_data) | |
if not csv_file: | |
return plot, df_data, None, None, None, "\n".join(progress_updates) + "\n❌ Error al descargar resultados" | |
# Paso 3: Generar análisis con Claude | |
progress_updates.append(f"🤖 Generando análisis con {claude_model}...") | |
analysis, code = generate_claude_report( | |
csv_file, claude_model, detail_level, language, additional_specs | |
) | |
if "Error" in analysis: | |
return plot, df_data, analysis, code, None, "\n".join(progress_updates) + f"\n❌ {analysis}" | |
progress_updates.append("✅ Análisis con Claude completado") | |
# Paso 4: Exportar informe | |
progress_updates.append(f"📄 Exportando informe en formato {export_format}...") | |
report_file, export_status = export_report(export_format, language, analysis, code) | |
if report_file: | |
progress_updates.append("✅ Informe exportado exitosamente") | |
else: | |
progress_updates.append(f"❌ {export_status}") | |
final_status = "\n".join(progress_updates) | |
return plot, df_data, analysis, code, report_file, final_status | |
# CSS personalizado | |
custom_css = """ | |
.container { | |
max-width: 1400px; | |
margin: auto; | |
} | |
.file-upload { | |
border: 2px dashed #3b82f6; | |
border-radius: 12px; | |
padding: 20px; | |
text-align: center; | |
transition: all 0.3s ease; | |
} | |
.file-upload:hover { | |
border-color: #2563eb; | |
background-color: #eff6ff; | |
} | |
button.primary { | |
background: linear-gradient(135deg, #3b82f6 0%, #8b5cf6 100%); | |
border: none; | |
color: white; | |
font-weight: bold; | |
transition: all 0.3s ease; | |
} | |
button.primary:hover { | |
transform: translateY(-2px); | |
box-shadow: 0 10px 20px rgba(59, 130, 246, 0.3); | |
} | |
.tabs { | |
border-radius: 12px; | |
overflow: hidden; | |
} | |
.tab-nav { | |
background-color: #f3f4f6; | |
padding: 5px; | |
} | |
.tab-nav button { | |
border-radius: 8px; | |
margin: 0 2px; | |
} | |
.tab-nav button.selected { | |
background-color: white; | |
box-shadow: 0 2px 4px rgba(0,0,0,0.1); | |
} | |
.gr-dataframe { | |
border-radius: 8px; | |
overflow: hidden; | |
} | |
.gr-dataframe table { | |
font-size: 14px; | |
} | |
""" | |
# Interfaz de Gradio | |
with gr.Blocks(theme=theme, title="BioTech Analysis & Report Generator", css=custom_css) as demo: | |
gr.Markdown( | |
""" | |
# 🧬 BioTech Analysis & Report Generator | |
### Pipeline completo de análisis biotecnológico con IA | |
Este sistema combina análisis avanzado de datos biotecnológicos con generación de informes mediante Claude 3.5. | |
""" | |
) | |
with gr.Row(): | |
with gr.Column(scale=1): | |
gr.Markdown("## 📊 Configuración del Análisis") | |
# Inputs para BiotechU4 | |
file_input = gr.File( | |
label="📁 Archivo de datos (CSV/Excel)", | |
file_types=[".csv", ".xlsx", ".xls"], | |
elem_classes=["file-upload"] | |
) | |
with gr.Group(): | |
gr.Markdown("### 🔬 Parámetros de Análisis") | |
models_input = gr.CheckboxGroup( | |
choices=['logistic', 'gompertz', 'moser', 'baranyi', 'monod', | |
'contois', 'andrews', 'tessier', 'richards', 'stannard', 'huang'], | |
value=['logistic', 'gompertz', 'moser', 'baranyi'], | |
label="📊 Modelos a probar" | |
) | |
component_input = gr.Dropdown( | |
choices=['all', 'biomass', 'substrate', 'product'], | |
value='all', | |
label="📈 Componente a visualizar" | |
) | |
exp_names_input = gr.Textbox( | |
label="🏷️ Nombres de experimentos", | |
placeholder="Experimento 1, Experimento 2...", | |
value="Análisis Biotecnológico" | |
) | |
with gr.Row(): | |
use_de_input = gr.Checkbox( | |
label="🧮 Usar Evolución Diferencial", | |
value=False | |
) | |
maxfev_input = gr.Number( | |
label="🔄 Iteraciones máximas", | |
value=50000, | |
minimum=1000, | |
maximum=100000, | |
step=1000 | |
) | |
with gr.Group(): | |
gr.Markdown("### 🤖 Configuración de Claude") | |
claude_model_input = gr.Dropdown( | |
choices=[ | |
'claude-3-7-sonnet-20250219', | |
'claude-3-5-sonnet-20241022', | |
'claude-3-5-haiku-20241022', | |
'claude-sonnet-4-20250514', | |
'claude-opus-4-20250514' | |
], | |
value='claude-3-7-sonnet-20250219', | |
label="🤖 Modelo de Claude" | |
) | |
detail_level_input = gr.Radio( | |
choices=['detailed', 'summarized'], | |
value='detailed', | |
label="📋 Nivel de detalle del análisis" | |
) | |
language_input = gr.Dropdown( | |
choices=['en', 'es', 'fr', 'de', 'pt'], | |
value='es', | |
label="🌐 Idioma del informe" | |
) | |
additional_specs_input = gr.Textbox( | |
label="📝 Especificaciones adicionales", | |
placeholder="Añade contexto o requisitos específicos para el análisis...", | |
lines=3, | |
value="Proporciona un análisis detallado de los modelos ajustados, incluyendo métricas de bondad de ajuste, comparación entre modelos y recomendaciones prácticas." | |
) | |
export_format_input = gr.Radio( | |
choices=['PDF', 'DOCX'], | |
value='PDF', | |
label="📄 Formato de exportación" | |
) | |
process_btn = gr.Button( | |
"🚀 Ejecutar Pipeline Completo", | |
variant="primary", | |
size="lg", | |
elem_classes=["primary"] | |
) | |
with gr.Column(scale=2): | |
gr.Markdown("## 📈 Resultados") | |
with gr.Tabs(elem_classes=["tabs"]): | |
with gr.TabItem("📊 Visualización"): | |
plot_output = gr.Plot(label="Gráfico interactivo") | |
with gr.TabItem("📋 Tabla de Resultados"): | |
table_output = gr.Dataframe( | |
label="Resultados del ajuste", | |
interactive=False | |
) | |
with gr.TabItem("📝 Análisis de Claude"): | |
analysis_output = gr.Markdown(label="Análisis comparativo") | |
with gr.TabItem("💻 Código"): | |
code_output = gr.Code( | |
label="Código de implementación", | |
language="python" | |
) | |
with gr.Row(): | |
status_output = gr.Textbox( | |
label="📊 Estado del proceso", | |
lines=6, | |
interactive=False | |
) | |
with gr.Row(): | |
report_output = gr.File( | |
label="📥 Descargar informe", | |
interactive=False | |
) | |
# Conectar la función principal | |
process_btn.click( | |
fn=process_complete_pipeline, | |
inputs=[ | |
file_input, | |
models_input, | |
component_input, | |
use_de_input, | |
maxfev_input, | |
exp_names_input, | |
claude_model_input, | |
detail_level_input, | |
language_input, | |
additional_specs_input, | |
export_format_input | |
], | |
outputs=[ | |
plot_output, | |
table_output, | |
analysis_output, | |
code_output, | |
report_output, | |
status_output | |
] | |
) | |
# Footer | |
gr.Markdown( | |
""" | |
--- | |
### 📚 Instrucciones de uso: | |
1. **Sube tu archivo de datos** en formato CSV o Excel | |
2. **Selecciona los modelos** que deseas probar para el ajuste | |
3. **Configura los parámetros** de análisis según tus necesidades | |
4. **Elige el modelo de Claude** para generar el informe | |
5. **Especifica el idioma y formato** de exportación deseado | |
6. **Haz clic en "Ejecutar Pipeline Completo"** y espera los resultados | |
El sistema procesará tus datos, realizará el ajuste de modelos, generará un análisis | |
detallado con IA y producirá un informe profesional descargable. | |
""" | |
) | |
if __name__ == "__main__": | |
demo.launch( | |
share=False, | |
show_error=True | |
) |