Spaces:
Build error
Build error
File size: 4,871 Bytes
1d4307f 70d1d5d 1d4307f 9c6e361 54d3859 1d4307f 2d493d6 1d4307f 6fbc572 1d4307f 54d3859 5d2f783 70d1d5d 5d2f783 54d3859 ff2d8da 1d4307f 5d2f783 ff2d8da 5d2f783 2d493d6 ff2d8da 5d2f783 1d4307f 54d3859 1d4307f ff2d8da 1d4307f 54d3859 1d4307f ff2d8da 5d2f783 1d4307f 54d3859 ff2d8da 54d3859 1d4307f ff2d8da 54d3859 5d2f783 54d3859 ff2d8da 54d3859 2d493d6 ff2d8da 2d493d6 6fbc572 54d3859 5d2f783 54d3859 ff2d8da 54d3859 6fbc572 54d3859 5d2f783 54d3859 6fbc572 54d3859 ff2d8da 54d3859 ff2d8da 54d3859 6fbc572 54d3859 ff2d8da 5d2f783 54d3859 ff2d8da 54d3859 1d4307f | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 | from fastapi import FastAPI
from fastapi.responses import JSONResponse, HTMLResponse
from fastapi.middleware.cors import CORSMiddleware
import pandas as pd
import networkx as nx
import plotly.graph_objects as go
import re
import os
# ---------- CONFIG ----------
DATA_FILE = "База философских концептов - База философских концептов.csv"
# ---------- APP SETUP ----------
app = FastAPI(
title="Philosophy Knowledge Graph",
description="Онтологическая база философских концептов — Knowledge GraphRAG",
version="3.3.0",
)
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# ---------- LOAD DATA ----------
if not os.path.exists(DATA_FILE):
raise FileNotFoundError(f"Файл {DATA_FILE} не найден в корне проекта.")
df = pd.read_csv(DATA_FILE)
df = df.fillna("")
# ---------- BUILD GRAPH ----------
G = nx.DiGraph()
for _, row in df.iterrows():
G.add_node(
row["concept"],
definition=row["definition"],
needs=row["needs_level"],
tech=row["tech_problem"]
)
# регулярка для формата: «A» → «B»
for _, row in df.iterrows():
relations = re.findall(r'«([^»]+)»\s*[↔→]\s*«([^»]+)»', str(row["relations"]))
for a, b in relations:
if a in G.nodes and b in G.nodes:
G.add_edge(a, b, label=row["tech_problem"])
# Цвета Маслоу
color_map = {
"Физиологические": "#f4a261",
"Безопасность": "#2a9d8f",
"Принадлежность": "#e9c46a",
"Самоуважение": "#264653",
"Самореализация": "#e76f51"
}
# ---------- PRECOMPUTE LAYOUT ----------
# БЫСТРЫЙ, ЛЁГКИЙ, НЕ ТРЕБУЕТ SCIPY
POS = nx.spring_layout(G, k=0.7, iterations=30, seed=42)
# ---------- API ----------
@app.get("/")
def root():
return {"message": "Philosophy Knowledge Graph API — работает!"}
@app.get("/concepts")
def get_concepts():
return JSONResponse([
{"concept": n, **G.nodes[n]}
for n in G.nodes()
])
@app.get("/relations")
def get_relations():
return JSONResponse([
{"source": u, "target": v, "label": d.get("label", "")}
for u, v, d in G.edges(data=True)
])
@app.get("/jsonld")
def get_jsonld():
jsonld = {
"@context": {
"concept": "http://example.org/concept",
"definition": "http://example.org/definition",
"relation": "http://example.org/relation"
},
"@graph": []
}
for node, data in G.nodes(data=True):
jsonld["@graph"].append({
"@id": f"http://example.org/{node.replace(' ', '_')}",
"concept": node,
"definition": data.get("definition", ""),
"tech_problem": data.get("tech", ""),
"needs_level": data.get("needs", "")
})
return JSONResponse(jsonld)
# ---------- INTERACTIVE GRAPH ----------
@app.get("/graph", response_class=HTMLResponse)
def get_graph():
pos = POS
# --- Рёбра ---
edge_x, edge_y = [], []
for u, v in G.edges():
x0, y0 = pos[u]
x1, y1 = pos[v]
edge_x.extend([x0, x1, None])
edge_y.extend([y0, y1, None])
edge_trace = go.Scatter(
x=edge_x,
y=edge_y,
mode="lines",
line=dict(width=0.5, color="#888"),
hoverinfo="none",
)
# --- Узлы ---
node_x, node_y, node_color, node_text = [], [], [], []
for node, data in G.nodes(data=True):
x, y = pos[node]
node_x.append(x)
node_y.append(y)
node_color.append(color_map.get(data["needs"], "#8d99ae"))
node_text.append(
f"<b>{node}</b><br>{data['definition']}<br><i>{data['tech']}</i>"
)
node_trace = go.Scatter(
x=node_x,
y=node_y,
mode="markers",
hoverinfo="text",
text=node_text,
marker=dict(
size=12,
color=node_color,
line=dict(width=1)
),
)
fig = go.Figure(
data=[edge_trace, node_trace],
layout=go.Layout(
title="Онтологическая база философских концептов",
titlefont=dict(size=20),
showlegend=False,
hovermode="closest",
margin=dict(b=0, l=0, r=0, t=40),
xaxis=dict(showgrid=False, zeroline=False, visible=False),
yaxis=dict(showgrid=False, zeroline=False, visible=False),
)
)
return HTMLResponse(fig.to_html(full_html=False))
# ---------- RUN ----------
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=7860)
|