Test / app.py
niplinig's picture
Update app.py
af455dd verified
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
)