jcmachicao commited on
Commit
c999e16
·
verified ·
1 Parent(s): 5cc8a28

Update utils_gdmk.py

Browse files
Files changed (1) hide show
  1. utils_gdmk.py +130 -39
utils_gdmk.py CHANGED
@@ -1,71 +1,162 @@
1
  import networkx as nx
2
  import matplotlib.pyplot as plt
3
  import json
4
- import textwrap
5
  import requests
6
  import pandas as pd
7
  import os
 
 
 
8
 
9
- api_key = os.getenv("AIRT_KEY")
10
- AIRT_DBASEx = os.getenv("AIRT_DBASE")
11
- AIRT_TABLEx = os.getenv("AIRT_TABLE")
12
 
13
- G = nx.DiGraph()
 
 
14
 
15
- url = f"https://api.airtable.com/v0/{AIRT_DBASEx}/{AIRT_TABLEx}"
16
  headers = {
17
- "Authorization": f"Bearer {api_key}",
18
  "Content-Type": "application/json"
19
  }
20
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21
  def cargar_desde_airtable():
22
- response = requests.get(url, headers=headers)
23
-
24
  if response.status_code != 200:
25
  print(f"Error: {response.status_code} - {response.text}")
26
  return pd.DataFrame(columns=["Nombre", "Conceptos"])
 
27
  records = response.json().get("records", [])
28
- aportes = [
29
- [record["fields"].get("Nombre", ""),
30
- record["fields"].get("Conceptos", "")] for record in records
31
- ]
32
- return pd.DataFrame(aportes, columns=["Nombre", "Conceptos"])
 
 
 
 
 
 
 
33
 
34
  def inicializar_grafo():
35
  df = cargar_desde_airtable()
 
36
  for _, row in df.iterrows():
37
- nombre, conceptos = row["Nombre"], row["Conceptos"]
38
- for termino in conceptos:
39
- if not G.has_node(termino):
40
- G.add_node(termino, color='gray')
41
- if not G.has_edge(nombre, termino):
42
- G.add_edge(norma, enfoque)
43
-
44
- def guardar_en_airtable(nombre, conceptos):
45
- data = {"fields": {"Nombre": nombre, "Conceptos": conceptos}}
46
- requests.post(url, headers=headers, json=data)
47
-
48
- def agregar_aporte(nombre, enfoque, norma, texto):
49
- textox = wrap_text(f"{nombre}: {texto}")
50
 
51
- if not G.has_node(norma):
52
- G.add_node(norma, color='gray')
53
- if not G.has_edge(norma, enfoque):
54
- G.add_edge(norma, enfoque, label=textox)
55
-
56
- guardar_en_airtable(nombre, enfoque, norma, texto)
57
- return visualizar_grafo()
 
 
 
 
 
 
 
 
 
 
58
 
59
  def visualizar_grafo():
60
  plt.figure(figsize=(10, 6))
61
- pos = nx.spring_layout(G)
62
 
63
- edge_labels = nx.get_edge_attributes(G, 'label')
 
 
 
 
 
 
 
 
 
 
64
 
65
- nx.draw(G, pos, with_labels=True, node_color='lightblue', edge_color='gray', node_size=2000, font_size=10)
 
 
 
 
 
 
 
 
 
 
 
66
  nx.draw_networkx_edge_labels(G, pos, edge_labels=edge_labels, font_size=8)
67
-
68
- plt.title("Red de Aportes")
69
  plt.savefig("graph.png")
70
  plt.close()
71
  return "graph.png"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import networkx as nx
2
  import matplotlib.pyplot as plt
3
  import json
 
4
  import requests
5
  import pandas as pd
6
  import os
7
+ import gradio as gr
8
+ import openai
9
+ import scipy as sp
10
 
11
+ # Load OpenAI API Key
12
+ API_KEY = os.getenv("OAIK")
13
+ client = openai.OpenAI(api_key=API_KEY)
14
 
15
+ api_key_airt = os.getenv("AIRT_KEY")
16
+ AIRT_DBASE = 'appUuBVTJR5ju0y6J'
17
+ AIRT_TABLE = 'foros_postdoc'
18
 
19
+ url = f"https://api.airtable.com/v0/{AIRT_DBASE}/{AIRT_TABLE}"
20
  headers = {
21
+ "Authorization": f"Bearer {api_key_airt}",
22
  "Content-Type": "application/json"
23
  }
24
 
25
+ # Sample vocabulary for concept extraction
26
+ VOCABULARY = ["algoritmos", "inteligencia artificial", "políticas públicas",
27
+ "educación a distancia", "gobernanza", "educación superior"]
28
+
29
+ def cargar_nombres(archivo):
30
+ with open('nombres_postdoc.txt', "r", encoding="utf-8") as f:
31
+ students = [line.strip() for line in f if line.strip()] # Eliminar espacios y líneas vacías
32
+ return students
33
+
34
+ students = cargar_nombres("nombres.txt")
35
+
36
+ G = nx.DiGraph()
37
+
38
+ def extract_concepts(text):
39
+
40
+ instrucciones = "Eres un experto en educación superior a distancia con conocimiento de políticas públicas, \
41
+ tanto para educación superior como la adopción de inteligencia artificial"
42
+ prompt = f"""Dado el siguiente mensaje: '{text}', utilizando como base esta lista, {VOCABULARY}, genera una lista corta de los términos \
43
+ coincidentes con la lista larga separados por comas."""
44
+
45
+ version_model = 'gpt-3.5-turbo-0125'
46
+ response = client.chat.completions.create(
47
+ model=version_model,
48
+ messages=[{"role": "system", "content": instrucciones},
49
+ {"role": "user", "content": prompt}],
50
+ temperature=0.8,
51
+ max_tokens=300,
52
+ )
53
+ extract_concepts = response.choices[0].message.content.split(',')
54
+ return extract_concepts
55
+
56
  def cargar_desde_airtable():
57
+ response = requests.get(url, headers=headers)
 
58
  if response.status_code != 200:
59
  print(f"Error: {response.status_code} - {response.text}")
60
  return pd.DataFrame(columns=["Nombre", "Conceptos"])
61
+
62
  records = response.json().get("records", [])
63
+ aportes = []
64
+
65
+ for record in records:
66
+ nombre = record["fields"].get("Nombre", "").strip()
67
+ conceptos = record["fields"].get("Conceptos", "").strip()
68
+ aportes.append([nombre, conceptos])
69
+
70
+ df = pd.DataFrame(aportes, columns=["Nombre", "Conceptos"])
71
+
72
+ print("Loaded Airtable Data:")
73
+ print(df) # 🔍 Debugging: Print the loaded data
74
+ return df
75
 
76
  def inicializar_grafo():
77
  df = cargar_desde_airtable()
78
+
79
  for _, row in df.iterrows():
80
+ nombre = row["Nombre"].strip()
81
+ conceptos = row["Conceptos"].strip()
 
 
 
 
 
 
 
 
 
 
 
82
 
83
+ if not nombre or not conceptos:
84
+ continue # Skip empty rows
85
+
86
+ # Ensure name is added as a node first
87
+ if not G.has_node(nombre):
88
+ G.add_node(nombre, color='lightblue')
89
+
90
+ for termino in conceptos.split(','):
91
+ termino = termino.strip()
92
+ if termino: # ✅ Fix empty terms issue
93
+ if not G.has_node(termino):
94
+ G.add_node(termino, color='lightgreen')
95
+ if not G.has_edge(nombre, termino):
96
+ G.add_edge(nombre, termino)
97
+
98
+ # print("✅ Graph Nodes:", list(G.nodes))
99
+ # print("✅ Graph Edges:", list(G.edges))
100
 
101
  def visualizar_grafo():
102
  plt.figure(figsize=(10, 6))
 
103
 
104
+ if len(G.nodes) == 0:
105
+ print("⚠️ Warning: The graph is empty! Check if data was loaded correctly.")
106
+ plt.text(0.5, 0.5, "No data available", fontsize=12, ha='center')
107
+ plt.savefig("graph.png")
108
+ plt.close()
109
+ return "graph.png"
110
+
111
+ centrality = nx.betweenness_centrality(G)
112
+ pos = nx.kamada_kawai_layout(G)
113
+ node_colors = []
114
+ node_sizes = []
115
 
116
+ for node in G.nodes():
117
+ if node in students: # Si es un estudiante
118
+ node_colors.append('lightblue') # 🔵 Color para nombres
119
+ else:
120
+ node_colors.append('lightgreen') # 🟢 Color para conceptos
121
+
122
+ node_sizes.append(2000 + 8000 * centrality.get(node, 0))
123
+ nx.draw(
124
+ G, pos, with_labels=True, node_color=node_colors, edge_color='gray',
125
+ node_size=node_sizes, font_size=10
126
+ )
127
+ edge_labels = nx.get_edge_attributes(G, 'label')
128
  nx.draw_networkx_edge_labels(G, pos, edge_labels=edge_labels, font_size=8)
129
+ plt.title("Red de Aportes - Optimizada por Betweenness")
 
130
  plt.savefig("graph.png")
131
  plt.close()
132
  return "graph.png"
133
+
134
+ def guardar_en_airtable(nombre, conceptos, texto):
135
+ if isinstance(conceptos, str):
136
+ conceptos = [c.strip() for c in conceptos.split(',') if c.strip()] # Ensure it's a list
137
+ data = {"fields": {"Nombre": nombre, "Conceptos": ", ".join(conceptos), "Texto_Aporte": texto}}
138
+ response = requests.post(url, headers=headers, json=data)
139
+ if response.status_code != 200:
140
+ print(f"Error saving to Airtable: {response.status_code} - {response.text}")
141
+
142
+ def agregar_aporte(nombre, texto):
143
+ conceptos = extract_concepts(texto) # ✅ Extract concepts dynamically
144
+ print(f"Extracted Concepts: {conceptos}") # 🔍 Debugging
145
+
146
+ if not G.has_node(nombre):
147
+ G.add_node(nombre, color='gray')
148
+
149
+ for termino in conceptos:
150
+ termino = termino.strip()
151
+ if not G.has_node(termino):
152
+ G.add_node(termino, color='gray')
153
+ if not G.has_edge(nombre, termino):
154
+ G.add_edge(nombre, termino)
155
+
156
+ guardar_en_airtable(nombre, conceptos, texto)
157
+ return visualizar_grafo()
158
+
159
+ def reload_data():
160
+ """Reloads data from Airtable and updates the graph."""
161
+ inicializar_grafo() # Fetch fresh data and rebuild the graph
162
+ return visualizar_grafo() # Return updated image