Files
Novel-Map/backend/app.py

85 lines
2.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
武侠三部曲 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_all_graphs
from llm_router import answer_question
import uvicorn
app = FastAPI(title="武侠三部曲 GraphRAG API", version="1.1.0")
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# ── Models ────────────────────────────────────────────────
class ChatRequest(BaseModel):
question: str
class ImportRequest(BaseModel):
clear: bool = False # True = 先清空图谱再重新导入
novels: list[str] | None = None # 默认导入 dtslz/ldj/tlbb
# ── Endpoints ─────────────────────────────────────────────
@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_all_graphs(driver, novels=req.novels, 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)
if __name__ == "__main__":
uvicorn.run("app:app", host="0.0.0.0", port=8000, reload=True)