import sqlite3 import numpy as np import pandas as pd import gradio as gr from pickle import load from datetime import datetime import sqlalchemy from radiomics import featureextractor from sqlalchemy.orm import sessionmaker import nibabel as nib from PIL import Image extractor3D = featureextractor.RadiomicsFeatureExtractor("3DParams.yaml") with open("model.pickle", "rb") as file: loaded_model = load(file) def validation(username : str, password : str): if username == "" or password == "": return False table = pd.read_sql_table(table_name="Usuarios", con="sqlite:///database_test.db") row = table[table["Usuario"] == username] if row.empty: return False password_db = row["Contraseña"].to_numpy().tolist()[0] return password == password_db with gr.Blocks(title="Historial de diagnósticos") as ViewingHistory: history_dataframe = gr.Dataframe(visible=False, type="pandas", wrap=True, interactive=False) def update_dataframe(history_dataframe): temp = pd.read_sql_table(table_name="Predicciones", con="sqlite:///database_test.db") return gr.Dataframe(value=temp, visible=True, type="pandas", wrap=True, interactive=False) ViewingHistory.load(fn=update_dataframe, inputs=[history_dataframe], outputs=[history_dataframe]) with gr.Blocks(title="Clasificación") as AIModel: with gr.Row(): with gr.Column(): image_file = gr.File(file_count="single", file_types=[".nii.gz", ".nii"], type="filepath", label="Imagen") segment_file = gr.File(file_count="single", file_types=[".nii.gz", ".nii"], type="filepath", label="Segmento") dropdown_navigator = gr.Dropdown(value="eje X", choices=["eje X", "eje Y", "eje Z"], filterable=True, type="value", label="Eje") slider = gr.Slider(visible=False) image_preview = gr.Image(visible=False) def preview_image(axis, image): brain_volume_data = nib.load(image).get_fdata() if axis == "eje X": middle_index = brain_volume_data.shape[0] // 2 max_index = brain_volume_data.shape[0] - 1 slice = brain_volume_data[middle_index, :, :] image = Image.fromarray(slice) image = image.rotate(90) elif axis == "eje Y": middle_index = brain_volume_data.shape[1] // 2 max_index = brain_volume_data.shape[1] - 1 slice = brain_volume_data[:, middle_index, :] image = Image.fromarray(slice) image = image.rotate(90) else: middle_index = brain_volume_data.shape[2] // 2 max_index = brain_volume_data.shape[2] - 1 slice = brain_volume_data[:, :, middle_index] image = Image.fromarray(slice) image = image.rotate(90) return ( gr.Slider(value=middle_index, minimum=0, maximum=max_index, visible=True), gr.Image(value=image, label="Previsualización", type="pil", visible=True, interactive=False, show_download_button=True) ) def slicing_image(axis, image, index): brain_volume_data = nib.load(image).get_fdata() if axis == "eje X": slice = brain_volume_data[index, :, :] image = Image.fromarray(slice) image = image.rotate(90) elif axis == "eje Y": slice = brain_volume_data[:, index, :] image = Image.fromarray(slice) image = image.rotate(90) else: slice = brain_volume_data[:, :, index] image = Image.fromarray(slice) return ( gr.Image(value=image, label="Previsualización", type="pil", visible=True, interactive=False, show_download_button=True) ) dropdown_navigator.change(fn=preview_image, inputs=[dropdown_navigator, image_file], outputs=[slider, image_preview]) image_file.upload(fn=preview_image, inputs=[dropdown_navigator, image_file], outputs=[slider, image_preview]) slider.change(fn=slicing_image, inputs=[dropdown_navigator, image_file, slider], outputs=[image_preview]) with gr.Column(): label_output = gr.Label(label="Resultado") comment_output = gr.Textbox(label="Observación", type="text", interactive=True) with gr.Row(): with gr.Column(): with gr.Row(): with gr.Column(): clear_button = gr.ClearButton(value="Borrar", components=[image_file, segment_file, label_output, comment_output, dropdown_navigator]) with gr.Column(): submit_button = gr.Button(value="Enviar", variant="primary") def clear_image_preview(image_preview, slider): return (gr.Image(visible=False), gr.Slider(visible=False)) clear_button.click(fn=clear_image_preview, inputs=[image_preview, slider], outputs=[image_preview, slider]) with gr.Column(): flag_button = gr.Button(value="Guardar") def save_prediction(image, label_output, comment_output): grade1 = list(label_output.values())[0] grade2 = list(label_output.values())[1] engine = sqlalchemy.create_engine("sqlite:///database_test.db", echo=False) Session = sessionmaker(bind=engine) session = Session() metadata = sqlalchemy.MetaData() predictions_table = sqlalchemy.Table("Predicciones", metadata, autoload_with=engine) new_prediction = { "Imagen": image, "Grado 1":grade1, "Grado 2": grade2, "Observacion": comment_output, "Usuario ID": 1, "Ultima actualizacion": datetime.utcnow(), "Creado el": datetime.utcnow() } stmt = predictions_table.insert().values(**new_prediction) session.execute(stmt) session.commit() return gr.Info("Se ha guardado exitosamente") def classify_image(image, segment): features3D = extractor3D.execute(imageFilepath=image, maskFilepath=segment) dict = {} for key, value in zip(features3D.keys(), features3D.values()): if isinstance(value, np.ndarray): dict[key] = [value.tolist()] else: dict[key] = [value] temp = pd.DataFrame(dict).select_dtypes(exclude=["object"]).to_numpy() prediction = loaded_model.predict_proba(temp).tolist()[0] return {"Grado 1": prediction[0], "Grado 2": prediction[1]} flag_button.click(fn=save_prediction, inputs=[image_file, label_output, comment_output]).success(update_dataframe, history_dataframe, history_dataframe) submit_button.click(fn=classify_image, inputs=[image_file, segment_file], outputs=[label_output]) with gr.Blocks(title="Base de datos") as Database: with gr.Row(): table_dropdown = gr.Dropdown(value="Usuarios", choices=["Usuarios", "Predicciones"], filterable=True, label="Tabla") with gr.Row(): with gr.Column(): action_dropdown = gr.Dropdown(choices=["Eliminar", "Descargar"], filterable=True, label="Acciones") with gr.Column(): id_dropdown = gr.Dropdown(visible=False, filterable=True, label="Identificador (ID)") with gr.Column(): action_button = gr.Button(visible=False) with gr.Row(): database_dataframe = gr.Dataframe(visible=False, type="pandas", wrap=True, interactive=False) def on_table_dropdown_change(table_dropdown, database_dataframe, id_dropdown): temp = pd.read_sql_table(table_dropdown, "sqlite:///database_test.db") ids = temp["ID"].values.flatten().tolist() return ( gr.Dataframe(value=temp, visible=True, type="pandas", wrap=True, interactive=False), gr.Dropdown(choices=ids, visible=True, filterable=True, label="Identificador (ID)"), ) def on_database_load(table_dropdown, database_dataframe): temp = pd.read_sql_table(table_dropdown, "sqlite:///database_test.db") return gr.Dataframe(value=temp, visible=True, type="pandas", wrap=True, interactive=False) def on_action_dropdown_change(action_dropdown): return gr.Button(value=action_dropdown, visible=True, variant="primary") def on_action_button_click(table_dropdown, action_dropdown, id_dropdown, database_dataframe): if action_dropdown == "Eliminar": engine = sqlalchemy.create_engine("sqlite:///database_test.db", echo=False) Session = sessionmaker(bind=engine) session = Session() metadata = sqlalchemy.MetaData() table = sqlalchemy.Table(table_dropdown, metadata, autoload_with=engine) stmt = sqlalchemy.delete(table).where(table.c.ID == id_dropdown) session.execute(stmt) session.commit() return gr.Info(f"Se ha eliminado el registro #{id_dropdown}") elif action_dropdown == "Descargar": if table_dropdown == "Predicciones": file_path = database_dataframe["Imagen"].to_numpy().tolist()[0] print(file_path) return gr.DownloadButton(value=file_path) #return gr.Info(f"Se ha descargado el registro #{id_dropdown}") table_dropdown.change(fn=on_table_dropdown_change, inputs=[table_dropdown, database_dataframe, id_dropdown], outputs=[database_dataframe, id_dropdown]) Database.load(fn=on_database_load, inputs=[table_dropdown, database_dataframe], outputs=[database_dataframe]).success(fn=on_table_dropdown_change, inputs=[table_dropdown, database_dataframe, id_dropdown], outputs=[database_dataframe, id_dropdown]) action_dropdown.change(fn=on_action_dropdown_change, inputs=[action_dropdown], outputs=[action_button]) action_button.click(fn=on_action_button_click, inputs=[table_dropdown, action_dropdown, id_dropdown, database_dataframe], outputs=[action_dropdown]) with gr.Blocks(title="Información de usuario") as AdminInformation: with gr.Row(): with gr.Column(): input_profile_image = gr.Image(interactive=False) with gr.Column(): input_first_names = gr.Textbox(label="Nombres", interactive=False, type="text", max_lines=1) input_username = gr.Textbox(label="Usuario", interactive=False, type="text", max_lines=1) input_is_admin = gr.Textbox(label="Rol", interactive=False, type="text", max_lines=1) with gr.Column(): input_last_names = gr.Textbox(label="Apellidos", interactive=False, type="text", max_lines=1) input_email = gr.Textbox(label="Correo electrónico", interactive=False, type="email", max_lines=1) input_phone = gr.Textbox(label="Número de teléfono", interactive=False, type="text", max_lines=1) with gr.Row(): with gr.Row(): edit_button = gr.Button(value="Editar") save_button = gr.Button(value="Guardar", variant="primary") def FillFields(input_username, input_first_names, input_last_names, input_email, input_phone, input_is_admin): table = pd.read_sql_table(table_name="Usuarios", con="sqlite:///database_test.db") row = table[table["ID"] == 1] if not row.empty: username_db = row["Usuario"].to_numpy().tolist()[0] first_names_db = row["Nombres"].to_numpy().tolist()[0] last_names_db = row["Apellidos"].to_numpy().tolist()[0] email_db = row["Correo electronico"].to_numpy().tolist()[0] phone_db = row["Telefono"].to_numpy().tolist()[0] is_admin_db = row["Es Administrador"].to_numpy().tolist()[0] else: username_db = "" first_names_db = "" last_names_db = "" email_db = "" phone_db = "" is_admin_db = False return ( gr.Textbox(value=username_db, label="Usuario", interactive=False, max_lines=1), gr.Textbox(value=first_names_db, label="Nombres", interactive=False, max_lines=1), gr.Textbox(value=last_names_db, label="Apellidos", interactive=False, max_lines=1), gr.Textbox(value=email_db, label="Correo electrónico", interactive=False, max_lines=1), gr.Textbox(value=phone_db, label="Número de teléfono", interactive=False, max_lines=1), gr.Textbox(value="Administrador" if is_admin_db else "Doctor", label="Rol", interactive=False, type="text", max_lines=1) ) def make_editable(edit_button, input_username, input_first_names, input_last_names, input_email, input_phone): if edit_button == "Editar": return ( gr.Button(value="Cancelar"), gr.Textbox(value=input_username, interactive=True), gr.Textbox(value=input_first_names, interactive=True), gr.Textbox(value=input_last_names, interactive=True), gr.Textbox(value=input_email, interactive=True), gr.Textbox(value=input_phone, interactive=True), ) else: return ( gr.Button(value="Editar"), gr.Textbox(value=input_username, interactive=True), gr.Textbox(value=input_first_names, interactive=True), gr.Textbox(value=input_last_names, interactive=True), gr.Textbox(value=input_email, interactive=True), gr.Textbox(value=input_phone, interactive=True), ) def save_values(input_username, input_first_names, input_last_names, input_email, input_phone): #connection = sqlite3.connect("database_test.db") #cursor = connection.cursor() #data = cursor.execute(f'''UPDATE Usuarios SET Nombres = '{input_first_names}', Usuario = '{input_username}', Apellidos = '{input_last_names}', "Correo electronico" = '{input_email}', Telefono = '{input_phone}' WHERE ID==1;''') #connection.commit() #connection.close() engine = sqlalchemy.create_engine("sqlite:///database_test.db", echo=False) Session = sessionmaker(bind=engine) session = Session() metadata = sqlalchemy.MetaData() table = sqlalchemy.Table("Usuarios", metadata, autoload_with=engine) new_user = { "Usuario": input_username, "Nombres": input_first_names, "Apellidos": input_last_names, "Correo electronico": input_email, "Telefono": input_phone } stmt = sqlalchemy.update(table).where(table.c.ID == 1).values(**new_user) session.execute(stmt) session.commit() return ( gr.Textbox(value=input_username, interactive=False), gr.Textbox(value=input_first_names, interactive=False), gr.Textbox(value=input_last_names, interactive=False), gr.Textbox(value=input_email, interactive=False), gr.Textbox(value=input_phone, interactive=False), ) AdminInformation.load(fn=FillFields, inputs=[input_username, input_first_names, input_last_names, input_email, input_phone, input_is_admin], outputs=[input_username, input_first_names, input_last_names, input_email, input_phone, input_is_admin]) edit_button.click(fn=make_editable, inputs=[edit_button, input_username, input_first_names, input_last_names, input_email, input_phone], outputs=[edit_button, input_username, input_first_names, input_last_names, input_email, input_phone]) save_button.click(fn=save_values, inputs=[input_username, input_first_names, input_last_names, input_email, input_phone], outputs=[input_username, input_first_names, input_last_names, input_email, input_phone]) Demo = gr.TabbedInterface( interface_list=[AIModel, ViewingHistory, Database, AdminInformation], tab_names=["Aplicación", "Historial", "Base de datos", "Administrador"], ) if __name__ == "__main__": Demo.launch( share=True, debug=True, inbrowser=True, auth=validation )