Skip to content

Commit 6b9e79c

Browse files
committed
add graphrag
1 parent 06016c4 commit 6b9e79c

File tree

14 files changed

+3202
-42
lines changed

14 files changed

+3202
-42
lines changed

.gitignore

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,60 @@ dist
1111
*temp
1212
*repo_metadata.json
1313
__pycache__
14+
15+
# Database files
1416
*.duckdb
1517
*.gexf
16-
*.gexf.gz
18+
*.gexf.gz
19+
20+
# GraphRAG specific
21+
backend/app/kuzu/
22+
backend/app/cache/
23+
rag/kuzu_db_*
24+
*.kuzu
25+
26+
# Python
27+
__pycache__/
28+
*.py[cod]
29+
*$py.class
30+
*.so
31+
.Python
32+
build/
33+
develop-eggs/
34+
dist/
35+
downloads/
36+
eggs/
37+
.eggs/
38+
lib/
39+
lib64/
40+
parts/
41+
sdist/
42+
var/
43+
wheels/
44+
*.egg-info/
45+
.installed.cfg
46+
*.egg
47+
MANIFEST
48+
49+
# Virtual environments
50+
venv/
51+
env/
52+
ENV/
53+
env.bak/
54+
venv.bak/
55+
56+
# IDE
57+
.vscode/
58+
.idea/
59+
*.swp
60+
*.swo
61+
*~
62+
63+
# OS
64+
.DS_Store
65+
.DS_Store?
66+
._*
67+
.Spotlight-V100
68+
.Trashes
69+
ehthumbs.db
70+
Thumbs.db

backend/app/main.py

Lines changed: 187 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
1-
from flask import Flask, jsonify, request, send_file, url_for
1+
from flask import Flask, jsonify, request, send_file, url_for, Response, stream_template
22
from flask_cors import CORS
33
from services.topic_service import TopicService
44
from services.ai_service import AITopicProcessor
55
from services.gexf_node_service import GexfNodeGenerator
66
from services.edge_generation_service import EdgeGenerationService
7+
from services.graphrag_service import graphrag_service
78
import os
89
import asyncio
910
import re
1011
import json
12+
import time
1113

1214
app = Flask(__name__, static_folder='gexf', static_url_path='/gexf')
1315
CORS(
@@ -26,6 +28,43 @@
2628
gexf_node_service = GexfNodeGenerator()
2729
edge_generation_service = EdgeGenerationService()
2830

31+
# Global progress tracking for GraphRAG setup
32+
graphrag_progress = {
33+
"current_step": "",
34+
"current": 0,
35+
"total": 0,
36+
"message": "",
37+
"status": "idle" # idle, running, completed, error
38+
}
39+
40+
# Global variable to track if GraphRAG is set up
41+
graphrag_ready = False
42+
43+
@app.route("/api/graphrag-health", methods=["GET"])
44+
def graphrag_health():
45+
"""Check if GraphRAG backend is ready and set up."""
46+
global graphrag_ready
47+
try:
48+
if graphrag_ready:
49+
return jsonify({
50+
"success": True,
51+
"ready": True,
52+
"message": "GraphRAG backend is ready"
53+
})
54+
else:
55+
return jsonify({
56+
"success": True,
57+
"ready": False,
58+
"message": "GraphRAG backend is not set up"
59+
}), 503
60+
except Exception as e:
61+
return jsonify({
62+
"success": False,
63+
"ready": False,
64+
"error": str(e),
65+
"message": "Error checking GraphRAG health"
66+
}), 500
67+
2968

3069
@app.route("/api/process-topics", methods=["GET", "POST"])
3170
def process_topics():
@@ -621,6 +660,153 @@ def create_edges_on_graph():
621660
}), 500
622661

623662

663+
@app.route("/api/graphrag-reset-progress", methods=["POST", "OPTIONS"])
664+
def graphrag_reset_progress_endpoint():
665+
"""Reset GraphRAG progress status to initial state."""
666+
if request.method == "OPTIONS":
667+
return "", 200
668+
669+
global graphrag_progress
670+
graphrag_progress = {
671+
"current_step": "Initializing...",
672+
"current": 0,
673+
"total": 100,
674+
"message": "Preparing GraphRAG setup",
675+
"status": "running"
676+
}
677+
return jsonify({"success": True, "message": "Progress reset"})
678+
679+
@app.route("/api/graphrag-progress", methods=["GET"])
680+
def graphrag_progress_endpoint():
681+
"""Server-Sent Events endpoint for GraphRAG progress updates."""
682+
def generate():
683+
while True:
684+
# Send current progress
685+
data = f"data: {json.dumps(graphrag_progress)}\n\n"
686+
yield data
687+
688+
# If completed or error, stop streaming
689+
if graphrag_progress["status"] in ["completed", "error"]:
690+
break
691+
692+
time.sleep(0.5) # Update every 0.5 seconds for more responsive updates
693+
694+
return Response(generate(), mimetype="text/event-stream")
695+
696+
697+
@app.route("/api/graphrag-setup", methods=["POST"])
698+
def graphrag_setup_endpoint():
699+
"""GraphRAG setup endpoint with progress tracking."""
700+
global graphrag_progress, graphrag_ready
701+
702+
try:
703+
data = request.get_json()
704+
705+
# Extract parameters
706+
provider = data.get("provider", "openai")
707+
api_keys = data.get("apiKeys", {})
708+
graph_file = data.get("graphFile", "")
709+
710+
if not graph_file:
711+
return jsonify({
712+
"success": False,
713+
"error": "Graph file is required",
714+
"message": "Please provide a graph file"
715+
}), 400
716+
717+
github_token = api_keys.get("githubToken", "")
718+
if not github_token:
719+
return jsonify({
720+
"success": False,
721+
"error": "GitHub token is required",
722+
"message": "Please provide a GitHub personal access token"
723+
}), 400
724+
725+
# Reset progress
726+
graphrag_progress = {
727+
"current_step": "Starting setup...",
728+
"current": 0,
729+
"total": 100,
730+
"message": "Initializing GraphRAG setup",
731+
"status": "running"
732+
}
733+
734+
# Setup database from GEXF content with progress updates
735+
setup_result = graphrag_service.setup_database_from_gexf_with_progress(graph_file, github_token, graphrag_progress)
736+
if not setup_result["success"]:
737+
graphrag_progress["status"] = "error"
738+
graphrag_progress["message"] = setup_result.get("error", "Setup failed")
739+
return jsonify(setup_result), 500
740+
741+
# Initialize GraphRAG with the selected provider
742+
graphrag_progress["current_step"] = "Initializing AI system..."
743+
graphrag_progress["current"] = 90
744+
graphrag_progress["message"] = "Setting up AI analysis system"
745+
746+
init_result = graphrag_service.initialize_graphrag(provider, api_keys)
747+
if not init_result["success"]:
748+
graphrag_progress["status"] = "error"
749+
graphrag_progress["message"] = init_result.get("error", "AI initialization failed")
750+
return jsonify(init_result), 500
751+
752+
# Mark as completed and set ready flag
753+
graphrag_progress["status"] = "completed"
754+
graphrag_progress["current"] = 100
755+
graphrag_progress["message"] = "GraphRAG setup completed successfully!"
756+
graphrag_ready = True
757+
758+
return jsonify({
759+
"success": True,
760+
"message": "GraphRAG setup completed successfully",
761+
"ready": True
762+
})
763+
764+
except Exception as e:
765+
graphrag_progress["status"] = "error"
766+
graphrag_progress["message"] = str(e)
767+
return jsonify({
768+
"success": False,
769+
"error": str(e),
770+
"message": "An error occurred during GraphRAG setup"
771+
}), 500
772+
773+
774+
@app.route("/api/graphrag", methods=["POST"])
775+
def graphrag_endpoint():
776+
"""GraphRAG endpoint for AI-powered graph analysis."""
777+
try:
778+
data = request.get_json()
779+
780+
# Extract parameters
781+
query = data.get("query", "")
782+
provider = data.get("provider", "openai")
783+
api_keys = data.get("apiKeys", {})
784+
785+
if not query:
786+
return jsonify({
787+
"success": False,
788+
"error": "Query is required",
789+
"message": "Please provide a query"
790+
}), 400
791+
792+
# Execute the query
793+
query_result = graphrag_service.query_graphrag(query)
794+
if not query_result["success"]:
795+
return jsonify(query_result), 500
796+
797+
return jsonify({
798+
"success": True,
799+
"result": query_result["result"]
800+
})
801+
802+
except Exception as e:
803+
return jsonify({
804+
"success": False,
805+
"error": str(e),
806+
"message": "An error occurred while processing the GraphRAG query"
807+
}), 500
808+
809+
624810
@app.route("/")
625811
def home():
626812
return "Hello World!"

0 commit comments

Comments
 (0)