olegp156 commited on
Commit
5d2f783
·
verified ·
1 Parent(s): 70d1d5d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +58 -77
app.py CHANGED
@@ -9,14 +9,12 @@ import os
9
 
10
  # ---------- CONFIG ----------
11
  DATA_FILE = "База философских концептов - База философских концептов.csv"
12
- NODES_FILE = "nodes.csv"
13
- EDGES_FILE = "edges.csv"
14
 
15
  # ---------- APP SETUP ----------
16
  app = FastAPI(
17
  title="Philosophy Knowledge Graph",
18
  description="Онтологическая база философских концептов — Knowledge GraphRAG",
19
- version="2.1.0",
20
  )
21
 
22
  app.add_middleware(
@@ -35,38 +33,29 @@ df = df.fillna("")
35
  G = nx.DiGraph()
36
 
37
  for _, row in df.iterrows():
38
- concept = row["concept"]
39
  G.add_node(
40
- concept,
41
  definition=row["definition"],
42
- source=row["source"],
43
- author=row["author"],
44
- tech_problem=row["tech_problem"],
45
- needs_level=row["needs_level"],
46
  )
47
 
48
- # добавляем связи из поля relations
49
- if row["relations"]:
50
- relations = re.findall(r'«([^»]+)»\s*[↔→]\s*«([^»]+)»', str(row["relations"]))
51
- for a, b in relations:
52
- if a in df["concept"].values and b in df["concept"].values:
53
- G.add_edge(a, b, label=row["tech_problem"])
54
-
55
- # связи с тех. проблемами и потребностями
56
  for _, row in df.iterrows():
57
- if row["tech_problem"]:
58
- G.add_edge(row["concept"], row["tech_problem"])
59
- if row["needs_level"]:
60
- G.add_edge(row["concept"], row["needs_level"])
61
-
62
- # ---------- EXPORT FOR NEO4J ----------
63
- nodes_data = [{"id": n, **G.nodes[n]} for n in G.nodes()]
64
- edges_data = [{"source": u, "target": v} for u, v in G.edges()]
65
-
66
- pd.DataFrame(nodes_data).to_csv(NODES_FILE, index=False)
67
- pd.DataFrame(edges_data).to_csv(EDGES_FILE, index=False)
68
-
69
- # ---------- ROUTES ----------
 
 
70
  @app.get("/")
71
  def root():
72
  return {"message": "Philosophy Knowledge Graph API — работает!"}
@@ -74,28 +63,44 @@ def root():
74
 
75
  @app.get("/concepts")
76
  def get_concepts():
77
- return JSONResponse(nodes_data)
 
78
 
79
 
80
  @app.get("/relations")
81
  def get_relations():
82
- return JSONResponse(edges_data)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
83
 
84
 
85
  @app.get("/graph", response_class=HTMLResponse)
86
  def get_graph():
87
- """Интерактивный граф (Plotly)"""
88
- color_map = {
89
- "Физиологические": "#f4a261",
90
- "Безопасность": "#2a9d8f",
91
- "Принадлежность": "#e9c46a",
92
- "Самоуважение": "#264653",
93
- "Самореализация": "#e76f51",
94
- }
95
 
96
- pos = nx.spring_layout(G, k=0.7, iterations=80)
97
  edge_x, edge_y = [], []
98
-
99
  for edge in G.edges():
100
  x0, y0 = pos[edge[0]]
101
  x1, y1 = pos[edge[1]]
@@ -104,26 +109,26 @@ def get_graph():
104
 
105
  edge_trace = go.Scatter(
106
  x=edge_x, y=edge_y,
107
- line=dict(width=0.5, color="#888"),
108
- hoverinfo="none",
109
- mode="lines",
110
  )
111
 
 
112
  node_x, node_y, node_color, node_text = [], [], [], []
113
  for node, data in G.nodes(data=True):
114
  x, y = pos[node]
115
  node_x.append(x)
116
  node_y.append(y)
117
- need_level = data.get("needs_level", "")
118
- node_color.append(color_map.get(need_level, "#8d99ae"))
119
  node_text.append(
120
- f"<b>{node}</b><br>{data.get('definition','')}<br><i>{data.get('tech_problem','')}</i>"
121
  )
122
 
123
  node_trace = go.Scatter(
124
  x=node_x, y=node_y,
125
- mode="markers",
126
- hoverinfo="text",
127
  text=node_text,
128
  marker=dict(showscale=False, color=node_color, size=12, line_width=1),
129
  )
@@ -134,40 +139,16 @@ def get_graph():
134
  title="Онтологическая база философских концептов",
135
  titlefont_size=20,
136
  showlegend=False,
137
- hovermode="closest",
138
  margin=dict(b=0, l=0, r=0, t=40),
139
  xaxis=dict(showgrid=False, zeroline=False),
140
- yaxis=dict(showgrid=False, zeroline=False),
141
- ),
142
  )
143
 
144
  return HTMLResponse(content=fig.to_html(full_html=True))
145
 
146
 
147
- @app.get("/jsonld")
148
- def get_jsonld():
149
- """Экспорт в машиночитаемом формате JSON-LD"""
150
- jsonld = {
151
- "@context": {
152
- "concept": "http://example.org/concept",
153
- "definition": "http://example.org/definition",
154
- "relation": "http://example.org/relation",
155
- },
156
- "@graph": [],
157
- }
158
- for node, data in G.nodes(data=True):
159
- jsonld["@graph"].append(
160
- {
161
- "@id": f"http://example.org/{node.replace(' ', '_')}",
162
- "concept": node,
163
- "definition": data.get("definition", ""),
164
- "tech_problem": data.get("tech_problem", ""),
165
- "needs_level": data.get("needs_level", ""),
166
- }
167
- )
168
- return JSONResponse(jsonld)
169
-
170
-
171
  # ---------- RUN ----------
172
  if __name__ == "__main__":
173
  import uvicorn
 
9
 
10
  # ---------- CONFIG ----------
11
  DATA_FILE = "База философских концептов - База философских концептов.csv"
 
 
12
 
13
  # ---------- APP SETUP ----------
14
  app = FastAPI(
15
  title="Philosophy Knowledge Graph",
16
  description="Онтологическая база философских концептов — Knowledge GraphRAG",
17
+ version="3.0.0",
18
  )
19
 
20
  app.add_middleware(
 
33
  G = nx.DiGraph()
34
 
35
  for _, row in df.iterrows():
 
36
  G.add_node(
37
+ row["concept"],
38
  definition=row["definition"],
39
+ needs=row["needs_level"],
40
+ tech=row["tech_problem"]
 
 
41
  )
42
 
 
 
 
 
 
 
 
 
43
  for _, row in df.iterrows():
44
+ relations = re.findall(r'«([^»]+)»\s*[↔→]\s*«([^»]+)»', str(row["relations"]))
45
+ for a, b in relations:
46
+ if a in G.nodes and b in G.nodes:
47
+ G.add_edge(a, b, label=row["tech_problem"])
48
+
49
+ # Цвета по Маслоу
50
+ color_map = {
51
+ "Физиологические": "#f4a261",
52
+ "Безопасность": "#2a9d8f",
53
+ "Принадлежность": "#e9c46a",
54
+ "Самоуважение": "#264653",
55
+ "Самореализация": "#e76f51"
56
+ }
57
+
58
+ # ---------- API ----------
59
  @app.get("/")
60
  def root():
61
  return {"message": "Philosophy Knowledge Graph API — работает!"}
 
63
 
64
  @app.get("/concepts")
65
  def get_concepts():
66
+ nodes = [{"concept": n, **G.nodes[n]} for n in G.nodes()]
67
+ return JSONResponse(nodes)
68
 
69
 
70
  @app.get("/relations")
71
  def get_relations():
72
+ edges = [{"source": u, "target": v, "label": d.get("label", "")} for u, v, d in G.edges(data=True)]
73
+ return JSONResponse(edges)
74
+
75
+
76
+ @app.get("/jsonld")
77
+ def get_jsonld():
78
+ jsonld = {
79
+ "@context": {
80
+ "concept": "http://example.org/concept",
81
+ "definition": "http://example.org/definition",
82
+ "relation": "http://example.org/relation"
83
+ },
84
+ "@graph": []
85
+ }
86
+ for node, data in G.nodes(data=True):
87
+ jsonld["@graph"].append({
88
+ "@id": f"http://example.org/{node.replace(' ', '_')}",
89
+ "concept": node,
90
+ "definition": data.get("definition", ""),
91
+ "tech_problem": data.get("tech", ""),
92
+ "needs_level": data.get("needs", "")
93
+ })
94
+ return JSONResponse(jsonld)
95
 
96
 
97
  @app.get("/graph", response_class=HTMLResponse)
98
  def get_graph():
99
+ """Интерактивный граф с Plotly"""
100
+ pos = nx.spring_layout(G, k=0.7, iterations=80, seed=42)
 
 
 
 
 
 
101
 
102
+ # --- Рёбра ---
103
  edge_x, edge_y = [], []
 
104
  for edge in G.edges():
105
  x0, y0 = pos[edge[0]]
106
  x1, y1 = pos[edge[1]]
 
109
 
110
  edge_trace = go.Scatter(
111
  x=edge_x, y=edge_y,
112
+ line=dict(width=0.5, color='#888'),
113
+ hoverinfo='none',
114
+ mode='lines'
115
  )
116
 
117
+ # --- Узлы ---
118
  node_x, node_y, node_color, node_text = [], [], [], []
119
  for node, data in G.nodes(data=True):
120
  x, y = pos[node]
121
  node_x.append(x)
122
  node_y.append(y)
123
+ node_color.append(color_map.get(data['needs'], '#8d99ae'))
 
124
  node_text.append(
125
+ f"<b>{node}</b><br>{data['definition']}<br><i>{data['tech']}</i>"
126
  )
127
 
128
  node_trace = go.Scatter(
129
  x=node_x, y=node_y,
130
+ mode='markers',
131
+ hoverinfo='text',
132
  text=node_text,
133
  marker=dict(showscale=False, color=node_color, size=12, line_width=1),
134
  )
 
139
  title="Онтологическая база философских концептов",
140
  titlefont_size=20,
141
  showlegend=False,
142
+ hovermode='closest',
143
  margin=dict(b=0, l=0, r=0, t=40),
144
  xaxis=dict(showgrid=False, zeroline=False),
145
+ yaxis=dict(showgrid=False, zeroline=False)
146
+ )
147
  )
148
 
149
  return HTMLResponse(content=fig.to_html(full_html=True))
150
 
151
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
152
  # ---------- RUN ----------
153
  if __name__ == "__main__":
154
  import uvicorn