Upload 3 files
Browse files
UI.py
CHANGED
|
@@ -1,23 +1,14 @@
|
|
| 1 |
# UI.py
|
| 2 |
import gradio as gr
|
| 3 |
|
| 4 |
-
# La importaci贸n de process_and_plot ya no es necesaria aqu铆,
|
| 5 |
-
# la funci贸n de procesamiento se pasar谩 como argumento a create_interface.
|
| 6 |
-
|
| 7 |
def create_interface(process_function_for_button):
|
| 8 |
-
|
| 9 |
-
Esta funci贸n crea la interfaz de usuario y la devuelve.
|
| 10 |
-
Conecta el bot贸n de submit a la 'process_function_for_button' proporcionada.
|
| 11 |
-
"""
|
| 12 |
-
|
| 13 |
-
with gr.Blocks(theme='upsatwal/mlsc_tiet') as demo: # O usa gr.themes.Soft() o tu theme preferido
|
| 14 |
gr.Markdown("# Modelado de Bioprocesos con Ecuaciones Personalizadas y An谩lisis por IA")
|
| 15 |
|
| 16 |
with gr.Row():
|
| 17 |
with gr.Column(scale=2):
|
| 18 |
gr.Markdown("### Carga de Datos y Configuraci贸n General")
|
| 19 |
file_input = gr.File(label="Subir archivo Excel (.xlsx)", file_types=[".xlsx"])
|
| 20 |
-
|
| 21 |
show_legend_ui = gr.Checkbox(label="Mostrar leyenda en gr谩ficos", value=True)
|
| 22 |
show_params_ui = gr.Checkbox(label="Mostrar par谩metros ajustados en gr谩ficos", value=True)
|
| 23 |
legend_position_ui = gr.Dropdown(
|
|
@@ -31,34 +22,30 @@ def create_interface(process_function_for_button):
|
|
| 31 |
substrate_eq_count_ui = gr.Number(label="Sustrato (1-3)", value=1, minimum=1, maximum=3, precision=0, step=1)
|
| 32 |
product_eq_count_ui = gr.Number(label="Producto (1-3)", value=1, minimum=1, maximum=3, precision=0, step=1)
|
| 33 |
|
| 34 |
-
# --- Secci贸n de Biomasa ---
|
| 35 |
with gr.Accordion("Ecuaciones y Par谩metros de Biomasa", open=True):
|
| 36 |
with gr.Row():
|
| 37 |
with gr.Column():
|
| 38 |
biomass_eq1_ui = gr.Textbox(label="Ecuaci贸n de Biomasa 1", value="Xm * (1 - exp(-um * (t - t_lag)))", lines=2, placeholder="Ej: Xm * (1 - exp(-um * (t - t_lag)))")
|
| 39 |
biomass_param1_ui = gr.Textbox(label="Par谩metros Biomasa 1", value="Xm, um, t_lag", info="Nombres de par谩metros, coma sep. Use 't' para tiempo. 'X_val' para X(t) en S/P.")
|
| 40 |
biomass_bound1_ui = gr.Textbox(label="L铆mites Biomasa 1", value="(0, np.inf), (0, np.inf), (0, np.inf)", info="Formato: (low,high) para cada param. Use np.inf.")
|
| 41 |
-
# Columna
|
| 42 |
-
biomass_col2
|
| 43 |
-
with biomass_col2:
|
| 44 |
biomass_eq2_ui = gr.Textbox(label="Ecuaci贸n de Biomasa 2", value="X0 * exp(um * t)", lines=2)
|
| 45 |
biomass_param2_ui = gr.Textbox(label="Par谩metros Biomasa 2", value="X0, um")
|
| 46 |
biomass_bound2_ui = gr.Textbox(label="L铆mites Biomasa 2", value="(0, np.inf), (0, np.inf)")
|
| 47 |
-
# Columna
|
| 48 |
-
biomass_col3
|
| 49 |
-
with biomass_col3:
|
| 50 |
biomass_eq3_ui = gr.Textbox(label="Ecuaci贸n de Biomasa 3", lines=2)
|
| 51 |
biomass_param3_ui = gr.Textbox(label="Par谩metros Biomasa 3")
|
| 52 |
biomass_bound3_ui = gr.Textbox(label="L铆mites Biomasa 3")
|
| 53 |
|
| 54 |
-
# --- Secci贸n de Sustrato ---
|
| 55 |
with gr.Accordion("Ecuaciones y Par谩metros de Sustrato", open=True):
|
| 56 |
-
gr.Markdown("Para
|
| 57 |
with gr.Row():
|
| 58 |
with gr.Column():
|
| 59 |
substrate_eq1_ui = gr.Textbox(label="Ecuaci贸n de Sustrato 1", value="S0 - (X_val / YXS) - mS * t", lines=2)
|
| 60 |
substrate_param1_ui = gr.Textbox(label="Par谩metros Sustrato 1", value="S0, YXS, mS")
|
| 61 |
-
substrate_bound1_ui = gr.Textbox(label="L铆mites Sustrato 1", value="(0, np.inf), (1e-9, np.inf), (0, np.inf)")
|
| 62 |
substrate_col2 = gr.Column(visible=False)
|
| 63 |
with substrate_col2:
|
| 64 |
substrate_eq2_ui = gr.Textbox(label="Ecuaci贸n de Sustrato 2", lines=2)
|
|
@@ -70,7 +57,6 @@ def create_interface(process_function_for_button):
|
|
| 70 |
substrate_param3_ui = gr.Textbox(label="Par谩metros Sustrato 3")
|
| 71 |
substrate_bound3_ui = gr.Textbox(label="L铆mites Sustrato 3")
|
| 72 |
|
| 73 |
-
# --- Secci贸n de Producto ---
|
| 74 |
with gr.Accordion("Ecuaciones y Par谩metros de Producto", open=True):
|
| 75 |
with gr.Row():
|
| 76 |
with gr.Column():
|
|
@@ -88,14 +74,12 @@ def create_interface(process_function_for_button):
|
|
| 88 |
product_param3_ui = gr.Textbox(label="Par谩metros Producto 3")
|
| 89 |
product_bound3_ui = gr.Textbox(label="L铆mites Producto 3")
|
| 90 |
|
| 91 |
-
|
| 92 |
-
|
| 93 |
-
def update_visibility_fn(count):
|
| 94 |
-
return gr.Column(visible=count >= 2), gr.Column(visible=count >= 3)
|
| 95 |
|
| 96 |
-
biomass_eq_count_ui.change(fn=
|
| 97 |
-
substrate_eq_count_ui.change(fn=
|
| 98 |
-
product_eq_count_ui.change(fn=
|
| 99 |
|
| 100 |
submit_button = gr.Button("Procesar y Analizar", variant="primary", scale=1)
|
| 101 |
|
|
@@ -105,7 +89,6 @@ def create_interface(process_function_for_button):
|
|
| 105 |
with gr.Column(scale=3):
|
| 106 |
analysis_output = gr.Markdown(label="An谩lisis del Modelo por IA")
|
| 107 |
|
| 108 |
-
# Lista de todos los inputs para el bot贸n de submit
|
| 109 |
all_inputs_for_button = [
|
| 110 |
file_input,
|
| 111 |
biomass_eq1_ui, biomass_eq2_ui, biomass_eq3_ui,
|
|
@@ -124,26 +107,23 @@ def create_interface(process_function_for_button):
|
|
| 124 |
substrate_eq_count_ui,
|
| 125 |
product_eq_count_ui
|
| 126 |
]
|
| 127 |
-
|
| 128 |
outputs_for_button = [image_output, analysis_output]
|
| 129 |
|
| 130 |
-
# Conexi贸n del bot贸n DENTRO del contexto de Blocks
|
| 131 |
submit_button.click(
|
| 132 |
-
fn=process_function_for_button,
|
| 133 |
inputs=all_inputs_for_button,
|
| 134 |
outputs=outputs_for_button
|
| 135 |
)
|
| 136 |
|
| 137 |
-
# Inicializar
|
| 138 |
-
|
| 139 |
-
|
| 140 |
-
|
| 141 |
-
|
| 142 |
-
|
| 143 |
-
|
| 144 |
-
)
|
| 145 |
demo.load(
|
| 146 |
-
fn=
|
| 147 |
inputs=[biomass_eq_count_ui, substrate_eq_count_ui, product_eq_count_ui],
|
| 148 |
outputs=[
|
| 149 |
biomass_col2, biomass_col3,
|
|
|
|
| 1 |
# UI.py
|
| 2 |
import gradio as gr
|
| 3 |
|
|
|
|
|
|
|
|
|
|
| 4 |
def create_interface(process_function_for_button):
|
| 5 |
+
with gr.Blocks(theme='upsatwal/mlsc_tiet') as demo:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 6 |
gr.Markdown("# Modelado de Bioprocesos con Ecuaciones Personalizadas y An谩lisis por IA")
|
| 7 |
|
| 8 |
with gr.Row():
|
| 9 |
with gr.Column(scale=2):
|
| 10 |
gr.Markdown("### Carga de Datos y Configuraci贸n General")
|
| 11 |
file_input = gr.File(label="Subir archivo Excel (.xlsx)", file_types=[".xlsx"])
|
|
|
|
| 12 |
show_legend_ui = gr.Checkbox(label="Mostrar leyenda en gr谩ficos", value=True)
|
| 13 |
show_params_ui = gr.Checkbox(label="Mostrar par谩metros ajustados en gr谩ficos", value=True)
|
| 14 |
legend_position_ui = gr.Dropdown(
|
|
|
|
| 22 |
substrate_eq_count_ui = gr.Number(label="Sustrato (1-3)", value=1, minimum=1, maximum=3, precision=0, step=1)
|
| 23 |
product_eq_count_ui = gr.Number(label="Producto (1-3)", value=1, minimum=1, maximum=3, precision=0, step=1)
|
| 24 |
|
|
|
|
| 25 |
with gr.Accordion("Ecuaciones y Par谩metros de Biomasa", open=True):
|
| 26 |
with gr.Row():
|
| 27 |
with gr.Column():
|
| 28 |
biomass_eq1_ui = gr.Textbox(label="Ecuaci贸n de Biomasa 1", value="Xm * (1 - exp(-um * (t - t_lag)))", lines=2, placeholder="Ej: Xm * (1 - exp(-um * (t - t_lag)))")
|
| 29 |
biomass_param1_ui = gr.Textbox(label="Par谩metros Biomasa 1", value="Xm, um, t_lag", info="Nombres de par谩metros, coma sep. Use 't' para tiempo. 'X_val' para X(t) en S/P.")
|
| 30 |
biomass_bound1_ui = gr.Textbox(label="L铆mites Biomasa 1", value="(0, np.inf), (0, np.inf), (0, np.inf)", info="Formato: (low,high) para cada param. Use np.inf.")
|
| 31 |
+
biomass_col2 = gr.Column(visible=False) # Columna para la segunda ecuaci贸n de biomasa
|
| 32 |
+
with biomass_col2: # Contenido de la columna 2
|
|
|
|
| 33 |
biomass_eq2_ui = gr.Textbox(label="Ecuaci贸n de Biomasa 2", value="X0 * exp(um * t)", lines=2)
|
| 34 |
biomass_param2_ui = gr.Textbox(label="Par谩metros Biomasa 2", value="X0, um")
|
| 35 |
biomass_bound2_ui = gr.Textbox(label="L铆mites Biomasa 2", value="(0, np.inf), (0, np.inf)")
|
| 36 |
+
biomass_col3 = gr.Column(visible=False) # Columna para la tercera ecuaci贸n de biomasa
|
| 37 |
+
with biomass_col3: # Contenido de la columna 3
|
|
|
|
| 38 |
biomass_eq3_ui = gr.Textbox(label="Ecuaci贸n de Biomasa 3", lines=2)
|
| 39 |
biomass_param3_ui = gr.Textbox(label="Par谩metros Biomasa 3")
|
| 40 |
biomass_bound3_ui = gr.Textbox(label="L铆mites Biomasa 3")
|
| 41 |
|
|
|
|
| 42 |
with gr.Accordion("Ecuaciones y Par谩metros de Sustrato", open=True):
|
| 43 |
+
gr.Markdown("Para Sustrato/Producto, usa `X_val` para X(t). Ejemplo: `S0 - (X_val / YXS)` donde YXS es un par谩metro.")
|
| 44 |
with gr.Row():
|
| 45 |
with gr.Column():
|
| 46 |
substrate_eq1_ui = gr.Textbox(label="Ecuaci贸n de Sustrato 1", value="S0 - (X_val / YXS) - mS * t", lines=2)
|
| 47 |
substrate_param1_ui = gr.Textbox(label="Par谩metros Sustrato 1", value="S0, YXS, mS")
|
| 48 |
+
substrate_bound1_ui = gr.Textbox(label="L铆mites Sustrato 1", value="(0, np.inf), (1e-9, np.inf), (0, np.inf)")
|
| 49 |
substrate_col2 = gr.Column(visible=False)
|
| 50 |
with substrate_col2:
|
| 51 |
substrate_eq2_ui = gr.Textbox(label="Ecuaci贸n de Sustrato 2", lines=2)
|
|
|
|
| 57 |
substrate_param3_ui = gr.Textbox(label="Par谩metros Sustrato 3")
|
| 58 |
substrate_bound3_ui = gr.Textbox(label="L铆mites Sustrato 3")
|
| 59 |
|
|
|
|
| 60 |
with gr.Accordion("Ecuaciones y Par谩metros de Producto", open=True):
|
| 61 |
with gr.Row():
|
| 62 |
with gr.Column():
|
|
|
|
| 74 |
product_param3_ui = gr.Textbox(label="Par谩metros Producto 3")
|
| 75 |
product_bound3_ui = gr.Textbox(label="L铆mites Producto 3")
|
| 76 |
|
| 77 |
+
def update_visibility_gradio(count):
|
| 78 |
+
return gr.update(visible=count >= 2), gr.update(visible=count >= 3)
|
|
|
|
|
|
|
| 79 |
|
| 80 |
+
biomass_eq_count_ui.change(fn=update_visibility_gradio, inputs=biomass_eq_count_ui, outputs=[biomass_col2, biomass_col3])
|
| 81 |
+
substrate_eq_count_ui.change(fn=update_visibility_gradio, inputs=substrate_eq_count_ui, outputs=[substrate_col2, substrate_col3])
|
| 82 |
+
product_eq_count_ui.change(fn=update_visibility_gradio, inputs=product_eq_count_ui, outputs=[product_col2, product_col3])
|
| 83 |
|
| 84 |
submit_button = gr.Button("Procesar y Analizar", variant="primary", scale=1)
|
| 85 |
|
|
|
|
| 89 |
with gr.Column(scale=3):
|
| 90 |
analysis_output = gr.Markdown(label="An谩lisis del Modelo por IA")
|
| 91 |
|
|
|
|
| 92 |
all_inputs_for_button = [
|
| 93 |
file_input,
|
| 94 |
biomass_eq1_ui, biomass_eq2_ui, biomass_eq3_ui,
|
|
|
|
| 107 |
substrate_eq_count_ui,
|
| 108 |
product_eq_count_ui
|
| 109 |
]
|
|
|
|
| 110 |
outputs_for_button = [image_output, analysis_output]
|
| 111 |
|
|
|
|
| 112 |
submit_button.click(
|
| 113 |
+
fn=process_function_for_button,
|
| 114 |
inputs=all_inputs_for_button,
|
| 115 |
outputs=outputs_for_button
|
| 116 |
)
|
| 117 |
|
| 118 |
+
# Inicializar visibilidad usando demo.load para que se aplique al cargar la UI
|
| 119 |
+
def set_initial_visibility_on_load(b_c, s_c, p_c):
|
| 120 |
+
b_vis2_update, b_vis3_update = update_visibility_gradio(b_c)
|
| 121 |
+
s_vis2_update, s_vis3_update = update_visibility_gradio(s_c)
|
| 122 |
+
p_vis2_update, p_vis3_update = update_visibility_gradio(p_c)
|
| 123 |
+
return b_vis2_update, b_vis3_update, s_vis2_update, s_vis3_update, p_vis2_update, p_vis3_update
|
| 124 |
+
|
|
|
|
| 125 |
demo.load(
|
| 126 |
+
fn=set_initial_visibility_on_load,
|
| 127 |
inputs=[biomass_eq_count_ui, substrate_eq_count_ui, product_eq_count_ui],
|
| 128 |
outputs=[
|
| 129 |
biomass_col2, biomass_col3,
|
app.py
CHANGED
|
@@ -2,48 +2,46 @@
|
|
| 2 |
import sys
|
| 3 |
from pathlib import Path
|
| 4 |
|
| 5 |
-
# A帽adir el directorio actual al path para asegurar que se encuentran los m贸dulos locales
|
| 6 |
-
# como UI, interface, decorators, config, models.
|
| 7 |
CURRENT_DIR = Path(__file__).parent
|
| 8 |
if str(CURRENT_DIR) not in sys.path:
|
| 9 |
sys.path.insert(0, str(CURRENT_DIR))
|
| 10 |
|
| 11 |
-
# Ahora que el path est谩 configurado, podemos importar los m贸dulos locales.
|
| 12 |
try:
|
| 13 |
-
import decorators
|
| 14 |
from UI import create_interface
|
| 15 |
import interface as app_interface_module
|
| 16 |
except ImportError as e:
|
| 17 |
-
print(f"Error cr铆tico de importaci贸n en app.py: {e}. Aseg煤rate de que todos los archivos .py est茅n en el mismo directorio.")
|
| 18 |
sys.exit(1)
|
| 19 |
|
| 20 |
-
|
| 21 |
-
|
| 22 |
-
|
| 23 |
-
|
| 24 |
-
print("INFO (app.py): El decorador GPU de 'spaces' parece estar disponible (o es un stub).")
|
| 25 |
-
print("INFO (app.py): Se definir谩 una funci贸n dummy decorada para satisfacer el chequeo de Gradio.")
|
| 26 |
|
| 27 |
-
@decorators.gpu_decorator(duration=1)
|
| 28 |
def _app_py_dummy_gpu_function_for_gradio_startup():
|
| 29 |
-
"""Esta funci贸n es solo para satisfacer el chequeo de Gradio."""
|
| 30 |
-
# print("Funci贸n dummy GPU de app.py ejecutada (no deber铆a hacer nada).")
|
| 31 |
pass
|
| 32 |
else:
|
| 33 |
print("INFO (app.py): El decorador GPU real de 'spaces' no fue importado. No se necesita funci贸n dummy para GPU.")
|
| 34 |
-
|
| 35 |
|
| 36 |
def main():
|
| 37 |
-
# Pasa la funci贸n de procesamiento real (process_and_plot) a create_interface
|
| 38 |
-
# app_interface_module.process_and_plot es la funci贸n que queremos que el bot贸n llame.
|
| 39 |
-
|
| 40 |
print("INFO (app.py): Creando la interfaz Gradio...")
|
| 41 |
demo_instance = create_interface(process_function_for_button=app_interface_module.process_and_plot)
|
| 42 |
|
| 43 |
print("INFO (app.py): Lanzando la interfaz Gradio localmente...")
|
| 44 |
-
#
|
| 45 |
-
#
|
| 46 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 47 |
|
| 48 |
if __name__ == "__main__":
|
| 49 |
main()
|
|
|
|
| 2 |
import sys
|
| 3 |
from pathlib import Path
|
| 4 |
|
|
|
|
|
|
|
| 5 |
CURRENT_DIR = Path(__file__).parent
|
| 6 |
if str(CURRENT_DIR) not in sys.path:
|
| 7 |
sys.path.insert(0, str(CURRENT_DIR))
|
| 8 |
|
|
|
|
| 9 |
try:
|
| 10 |
+
import decorators # Importa tu archivo decorators.py
|
| 11 |
from UI import create_interface
|
| 12 |
import interface as app_interface_module
|
| 13 |
except ImportError as e:
|
| 14 |
+
print(f"Error cr铆tico de importaci贸n en app.py: {e}. Aseg煤rate de que todos los archivos .py est茅n en el mismo directorio o en PYTHONPATH.")
|
| 15 |
sys.exit(1)
|
| 16 |
|
| 17 |
+
|
| 18 |
+
if decorators.was_real_spaces_gpu_imported(): # Usa la funci贸n de decorators.py
|
| 19 |
+
print("INFO (app.py): El decorador GPU de 'spaces' parece estar disponible.")
|
| 20 |
+
print("INFO (app.py): Se definir谩 una funci贸n dummy decorada para satisfacer el chequeo de Gradio si es necesario.")
|
|
|
|
|
|
|
| 21 |
|
| 22 |
+
@decorators.gpu_decorator(duration=1)
|
| 23 |
def _app_py_dummy_gpu_function_for_gradio_startup():
|
|
|
|
|
|
|
| 24 |
pass
|
| 25 |
else:
|
| 26 |
print("INFO (app.py): El decorador GPU real de 'spaces' no fue importado. No se necesita funci贸n dummy para GPU.")
|
| 27 |
+
|
| 28 |
|
| 29 |
def main():
|
|
|
|
|
|
|
|
|
|
| 30 |
print("INFO (app.py): Creando la interfaz Gradio...")
|
| 31 |
demo_instance = create_interface(process_function_for_button=app_interface_module.process_and_plot)
|
| 32 |
|
| 33 |
print("INFO (app.py): Lanzando la interfaz Gradio localmente...")
|
| 34 |
+
# Si el error de localhost persiste, prueba con share=True
|
| 35 |
+
# Esto es m谩s probable si est谩s en un entorno contenedorizado incluso para "local"
|
| 36 |
+
try:
|
| 37 |
+
demo_instance.launch()
|
| 38 |
+
except ValueError as ve:
|
| 39 |
+
if "shareable link must be created" in str(ve):
|
| 40 |
+
print("ADVERTENCIA (app.py): Fall贸 el lanzamiento local directo, intentando con share=True...")
|
| 41 |
+
demo_instance.launch(share=True)
|
| 42 |
+
else:
|
| 43 |
+
raise ve
|
| 44 |
+
|
| 45 |
|
| 46 |
if __name__ == "__main__":
|
| 47 |
main()
|