forked from tigergraph/graphrag
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdashboard_api.py
More file actions
132 lines (110 loc) · 4.9 KB
/
Copy pathdashboard_api.py
File metadata and controls
132 lines (110 loc) · 4.9 KB
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
"""
CyberGraph Dashboard API Server
Serves the benchmark dashboard and proxies pipeline calls.
Run: python dashboard_api.py
Visit: http://localhost:8888
"""
import sys, os, json, time
from http.server import HTTPServer, BaseHTTPRequestHandler
from urllib.parse import urlparse
# Add parent dir so we can import benchmark_engine
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
try:
sys.stdout.reconfigure(encoding='utf-8')
except Exception:
pass
from benchmark_engine import (
pipeline_llm_only, pipeline_basic_rag, pipeline_graphrag,
evaluate_response, BENCHMARK_QUERIES
)
DASHBOARD_DIR = os.path.join(os.path.dirname(__file__), "dashboard")
PORT = int(os.environ.get("PORT", 8888))
class Handler(BaseHTTPRequestHandler):
def log_message(self, fmt, *args):
print(f" [{time.strftime('%H:%M:%S')}] {fmt % args}", flush=True)
def _send(self, code, body, ctype="application/json"):
data = body.encode("utf-8") if isinstance(body, str) else body
self.send_response(code)
self.send_header("Content-Type", ctype)
self.send_header("Content-Length", len(data))
self.send_header("Access-Control-Allow-Origin", "*")
self.send_header("Access-Control-Allow-Methods", "GET,POST,OPTIONS")
self.send_header("Access-Control-Allow-Headers", "Content-Type")
self.end_headers()
self.wfile.write(data)
def do_OPTIONS(self):
self._send(200, b"")
def do_GET(self):
path = urlparse(self.path).path
if path == "/" or path == "/index.html":
fpath = os.path.join(DASHBOARD_DIR, "index.html")
with open(fpath, "rb") as f:
self._send(200, f.read(), "text/html; charset=utf-8")
elif path == "/health":
self._send(200, json.dumps({"status": "ok"}))
elif path == "/queries":
self._send(200, json.dumps([{"id": q["id"], "query": q["query"]} for q in BENCHMARK_QUERIES]))
else:
self._send(404, json.dumps({"error": "Not found"}))
def do_POST(self):
path = urlparse(self.path).path
length = int(self.headers.get("Content-Length", 0))
body = json.loads(self.rfile.read(length)) if length else {}
if path == "/benchmark":
query = body.get("query", "")
evaluate = body.get("evaluate", False)
ground_truth = body.get("ground_truth", "")
skip_graphrag = body.get("skip_graphrag", False)
if not query:
self._send(400, json.dumps({"error": "query required"}))
return
print(f"\n Query: {query[:80]}", flush=True)
# Run all 3 pipelines
print(" [1/3] LLM-Only...", flush=True)
r_llm = pipeline_llm_only(query)
print(" [2/3] Basic RAG...", flush=True)
r_rag = pipeline_basic_rag(query)
print(" [3/3] GraphRAG...", flush=True)
r_graph = pipeline_graphrag(query) if not skip_graphrag else {
"response": "GraphRAG not yet available — graph ingestion in progress.",
"total_tokens": 0, "latency": 0.0, "cost": 0.0, "input_tokens": 0, "output_tokens": 0,
}
# Evaluate if requested
eval_results = {}
if evaluate and ground_truth:
print(" [Eval] Running LLM-as-Judge...", flush=True)
eval_results = {
"llm_only": evaluate_response(query, ground_truth, r_llm["response"]),
"basic_rag": evaluate_response(query, ground_truth, r_rag["response"]),
"graphrag": evaluate_response(query, ground_truth, r_graph["response"]),
}
r_llm["evaluation"] = eval_results["llm_only"]
r_rag["evaluation"] = eval_results["basic_rag"]
r_graph["evaluation"] = eval_results["graphrag"]
result = {
"query": query,
"llm_only": r_llm,
"basic_rag": r_rag,
"graphrag": r_graph,
}
self._send(200, json.dumps(result, ensure_ascii=False))
elif path == "/benchmark/full":
# Run all preset queries
from benchmark_engine import run_benchmark
results = run_benchmark(evaluate=body.get("evaluate", False),
skip_graphrag=body.get("skip_graphrag", False))
self._send(200, json.dumps(results, ensure_ascii=False))
else:
self._send(404, json.dumps({"error": "Not found"}))
def main():
print(f"\n{'='*60}")
print(f" CyberGraph Dashboard API — http://localhost:{PORT}")
print(f" Dashboard UI — http://localhost:{PORT}/")
print(f"{'='*60}\n")
server = HTTPServer(("0.0.0.0", PORT), Handler)
try:
server.serve_forever()
except KeyboardInterrupt:
print("\nServer stopped.")
if __name__ == "__main__":
main()