Spaces:
Sleeping
Sleeping
| import gradio as gr | |
| import networkx as nx | |
| import matplotlib.pyplot as plt | |
| import uuid | |
| import os | |
| import json | |
| import textwrap | |
| import requests | |
| import pandas as pd | |
| api_key = os.getenv("AIRT_KEY") | |
| AIRT_DBASEx = os.getenv("AIRT_DBASE") | |
| AIRT_TABLEx = os.getenv("AIRT_TABLE") | |
| # Use Directed Graph to represent relationships | |
| G = nx.DiGraph() # Fix: Use DiGraph instead of Graph | |
| url = f"https://api.airtable.com/v0/{AIRT_DBASEx}/{AIRT_TABLEx}" | |
| headers = { | |
| "Authorization": f"Bearer {api_key}", | |
| "Content-Type": "application/json" | |
| } | |
| # Cargar el JSON de normativas | |
| def cargar_normativas(): | |
| with open('normativas.json', 'r', encoding='utf-8') as f: | |
| return json.load(f) | |
| # Cargar la lista de estudiantes | |
| def cargar_estudiantes(): | |
| with open('estudiantes.json', 'r', encoding='utf-8') as f: | |
| return json.load(f) | |
| def crear_html(normativa): | |
| htmlx = f""" | |
| <div style="padding: 16px; border: 1px solid #ddd; border-radius: 8px;"> | |
| <style> | |
| p {{ font-size: 20px; }} | |
| </style> | |
| <h2>{normativa["nombre"]}</h2> | |
| <h2>{normativa["titulo"], normativa["a帽o"]}</h2> | |
| <p><strong>ID:</strong> {normativa["id"]}</p> | |
| <p><strong>Descripci贸n:</strong> {normativa["descripcion"]}</p> | |
| <p><strong>Enfoque de Gesti贸n:</strong> {normativa["enfoque_riesgo"]}</p> | |
| <p><strong>Opini贸n Docente:</strong> {normativa["opinion_docente"]}</p> | |
| <p><strong>Visite <a href={normativa["url"]} target="_blank">este sitio web</a> para m谩s informaci贸n.</strong></p> | |
| </div> | |
| """ | |
| return htmlx | |
| def mostrar_detalles(normativa_seleccionada): | |
| if not normativa_seleccionada: | |
| return "<p>Por favor selecciona una normativa</p>", None | |
| normativas = cargar_normativas() | |
| partes = normativa_seleccionada.split() | |
| id_normativa = normativa['nombre'] | |
| for normativa in normativas["normativa_peruana_gestion_riesgos"]: | |
| if id_normativa == normativa['nombre']: | |
| html = crear_html(normativa) | |
| return html | |
| def mostrar_detalles(normativa_seleccionada): | |
| if not normativa_seleccionada: | |
| return "<p>Por favor selecciona una normativa</p>", "" | |
| normativas = cargar_normativas() | |
| id_normativa = normativa_seleccionada # Extract the norm name | |
| for normativa in normativas["normativa_peruana_gestion_riesgos"]: | |
| if id_normativa == normativa['nombre']: | |
| return crear_html(normativa), normativa["nombre"] # Return both HTML and name | |
| return "<p>No se encontr贸 la normativa</p>", "" | |
| def cargar_desde_airtable(): | |
| response = requests.get(url, headers=headers) | |
| if response.status_code != 200: | |
| print(f"Error: {response.status_code} - {response.text}") # Debugging info | |
| return pd.DataFrame(columns=["Nombre", "Enfoque", "Norma", "Texto_HF"]) # Return empty DataFrame | |
| records = response.json().get("records", []) | |
| # Compact list comprehension to extract data | |
| aportes = [ | |
| [record["fields"].get("Nombre", ""), | |
| record["fields"].get("Enfoque", ""), | |
| record["fields"].get("Norma", ""), | |
| record["fields"].get("Texto_HF", "")] for record in records | |
| ] | |
| return pd.DataFrame(aportes, columns=["Nombre", "Enfoque", "Norma", "Texto_HF"]) | |
| def wrap_text(text, width=10): | |
| return "\n".join(textwrap.wrap(text, width=width)) | |
| def inicializar_grafo(): | |
| df = cargar_desde_airtable() | |
| # Add base nodes for categories | |
| G.add_node("Determinista", color='red') | |
| G.add_node("Sist茅mico", color='blue') | |
| # Process each row and add nodes/edges | |
| for _, row in df.iterrows(): | |
| nombre, enfoque, norma, texto = row["Nombre"], row["Enfoque"], row["Norma"], row["Texto_HF"] | |
| textox = wrap_text(f"{nombre}: {texto}") | |
| if not G.has_node(norma): | |
| G.add_node(norma, color='gray') | |
| if not G.has_edge(norma, enfoque): | |
| G.add_edge(norma, enfoque, label=textox) | |
| def guardar_en_airtable(nombre, enfoque, norma, texto): | |
| data = {"fields": {"Nombre": nombre, "Enfoque": enfoque, "Norma": norma, "Texto_HF": texto}} | |
| requests.post(url, headers=headers, json=data) | |
| def agregar_aporte(nombre, enfoque, norma, texto): | |
| textox = wrap_text(f"{nombre}: {texto}") | |
| if not G.has_node(norma): | |
| G.add_node(norma, color='gray') | |
| if not G.has_edge(norma, enfoque): | |
| G.add_edge(norma, enfoque, label=textox) | |
| guardar_en_airtable(nombre, enfoque, norma, texto) | |
| return visualizar_grafo() | |
| def visualizar_grafo(): | |
| plt.figure(figsize=(8, 8)) | |
| pos = nx.spring_layout(G) | |
| edge_labels = nx.get_edge_attributes(G, 'label') | |
| nx.draw(G, pos, with_labels=True, node_color='lightblue', edge_color='gray', node_size=2000, font_size=10) | |
| nx.draw_networkx_edge_labels(G, pos, edge_labels=edge_labels, font_size=8) | |
| plt.title("Red de Aportes") | |
| plt.savefig("graph.png") | |
| plt.close() | |
| return "graph.png" | |
| inicializar_grafo() | |
| normativas = cargar_normativas() | |
| estudiantes = cargar_estudiantes() | |
| norm_options = [f"{norm['nombre']} {norm['id']}" for norm in normativas["normativa_peruana_gestion_riesgos"]] | |
| student_names = [student for student in estudiantes["estudiantes"]] | |
| iface = gr.Blocks() | |
| with iface: | |
| gr.Markdown("# Foro Din谩mico con Visualizaci贸n de Red") | |
| with gr.Row(): | |
| gr.Markdown('## Selecci贸n de Norma') | |
| normativa_dropdown.change(fn=mostrar_detalles, inputs=normativa_dropdown, outputs=[normativa_html, norma_field]) | |
| with gr.Row(): | |
| gr.Markdown("## Red de Aportes:") | |
| graph_output = gr.Image(visualizar_grafo(), label="Red de Aportes") | |
| with gr.Row(): | |
| nombre = gr.Dropdown(choices=student_names, label="Nombre del Estudiante") | |
| enfoque = gr.Radio(["Determinista", "Sist茅mico"], label="Enfoque") | |
| with gr.Row(): | |
| norma_field = gr.Textbox(label="Norma", interactive=False) # Read-only | |
| texto = gr.Textbox(label="Tu aporte") | |
| submit_button = gr.Button("Agregar Aporte") | |
| submit_button.click(fn=agregar_aporte, inputs=[nombre, enfoque, norma_field, texto], outputs=graph_output) | |
| iface.launch(share=True) |