Files
Novel-Map/backend/app.py

84 lines
2.4 KiB
Python
Raw Normal View History

2026-03-31 17:18:30 +08:00
"""
大唐双龙传 GraphRAG FastAPI 后端
端点:
GET /api/health 健康检查 Neo4j 连通性
GET /api/stats 图谱节点/关系统计
POST /api/import 触发数据导入一次性操作
POST /api/chat 知识问答Text-to-Cypher + LLM 回答
"""
from fastapi import FastAPI, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel
from graph_query import get_driver, get_graph_stats
from graph_builder import build_graph
from llm_router import answer_question
2026-03-31 19:07:20 +08:00
import uvicorn
2026-03-31 17:18:30 +08:00
app = FastAPI(title="大唐双龙传 GraphRAG API", version="1.0.0")
app.add_middleware(
CORSMiddleware,
2026-03-31 19:07:20 +08:00
allow_origins=["*"],
2026-03-31 17:18:30 +08:00
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# ── Models ────────────────────────────────────────────────
2026-03-31 19:07:20 +08:00
2026-03-31 17:18:30 +08:00
class ChatRequest(BaseModel):
question: str
class ImportRequest(BaseModel):
2026-03-31 19:07:20 +08:00
clear: bool = False # True = 先清空图谱再重新导入
2026-03-31 17:18:30 +08:00
# ── Endpoints ─────────────────────────────────────────────
2026-03-31 19:07:20 +08:00
2026-03-31 17:18:30 +08:00
@app.get("/api/health")
def health():
driver = get_driver()
try:
driver.verify_connectivity()
return {"status": "ok", "neo4j": "connected"}
except Exception as e:
raise HTTPException(status_code=503, detail=f"Neo4j 连接失败: {e}")
@app.get("/api/stats")
def stats():
try:
return get_graph_stats()
except Exception as e:
raise HTTPException(status_code=503, detail=str(e))
@app.post("/api/import")
def import_data(req: ImportRequest = ImportRequest()):
"""导入所有卷数据到 Neo4j耗时约 1-3 分钟,请勿重复调用)"""
driver = get_driver()
try:
build_graph(driver, clear=req.clear)
stats = get_graph_stats()
return {"status": "ok", "stats": stats}
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@app.post("/api/chat")
def chat(req: ChatRequest):
if not req.question.strip():
raise HTTPException(status_code=400, detail="问题不能为空")
return answer_question(req.question)
2026-03-31 19:07:20 +08:00
if __name__ == "__main__":
uvicorn.run("app:app", host="0.0.0.0", port=8000, reload=True)