You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

311 lines
11 KiB

3 months ago
import json
import sys
3 months ago
import traceback
3 months ago
from datetime import datetime
3 months ago
import httpx
3 months ago
from app import app
from robyn import Robyn, jsonify, Response
from typing import Optional, List, Any, Dict
from service.GraphService import build_g6_subgraph_by_props, get_drug_names_from_neo4j, get_group_key, \
3 months ago
get_check_names_from_neo4j, get_disease_names_from_neo4j
3 months ago
from util.neo4j_utils import Neo4jUtil
from util.neo4j_utils import neo4j_client
from util.redis_utils import set as redis_set, get as redis_get # 使用你已有的模块级 Redis 工
# 缓存键
DRUG_TREE_KEY = "cache:drug_tree"
CHECK_TREE_KEY = "cache:check_tree"
3 months ago
DISEASE_TREE_KEY = "cache:disease_tree" # 👈 新增
3 months ago
# ========================
# 🔥 启动时预加载数据(在 app 启动前执行)
# ========================
def preload_data():
print("🚀 正在预加载 Drug 和 Check 树...")
try:
# --- Drug Tree ---
names = get_drug_names_from_neo4j()
groups = {}
for name in names:
key = get_group_key(name)
groups.setdefault(key, []).append(name)
alphabet = [chr(i) for i in range(ord('A'), ord('Z') + 1)]
all_keys = alphabet + ["0-9", "其他"]
tree_data = []
for key in all_keys:
if key in groups:
children = [{"label": name, "type": "Drug"} for name in sorted(groups[key])]
3 months ago
tree_data.append({"label": key, "children": children})
3 months ago
3 months ago
redis_set(DRUG_TREE_KEY, json.dumps(tree_data, ensure_ascii=False), ex=None)
3 months ago
# --- Check Tree ---
names = get_check_names_from_neo4j()
groups = {}
for name in names:
key = get_group_key(name)
groups.setdefault(key, []).append(name)
tree_data = []
for key in all_keys:
if key in groups:
children = [{"label": name, "type": "Check"} for name in sorted(groups[key])]
3 months ago
tree_data.append({"label": key, "children": children})
3 months ago
3 months ago
redis_set(CHECK_TREE_KEY, json.dumps(tree_data, ensure_ascii=False), ex=None)
3 months ago
3 months ago
names = get_disease_names_from_neo4j()
groups = {}
for name in names:
key = get_group_key(name)
groups.setdefault(key, []).append(name)
tree_data = []
for key in all_keys:
if key in groups:
children = [{"label": name, "type": "Disease"} for name in sorted(groups[key])]
tree_data.append({"label": key, "children": children})
redis_set(DISEASE_TREE_KEY, json.dumps(tree_data, ensure_ascii=False), ex=None)
3 months ago
print("✅ 预加载完成!数据已写入 Redis 缓存。")
except Exception as e:
print(f"❌ 预加载失败: {e}", file=sys.stderr)
# 可选:是否允许启动失败?这里选择继续启动(接口会返回错误)
# 或者 sys.exit(1) 强制退出
# 执行预加载(在 app 创建前)
preload_data()
3 months ago
@app.get("/api/preload")
def preload():
preload_data()
3 months ago
@app.get("/api/getData")
def get_data():
try:
graph_data = build_g6_subgraph_by_props(
neo4j_client,
node_label="Disease",
node_properties={"name": "霍乱"},
direction="both",
rel_type=None
)
return Response(
status_code=200,
description=jsonify(graph_data),
headers={"Content-Type": "text/plain; charset=utf-8"}
)
except Exception as e:
return jsonify({"error": str(e)}), 500
3 months ago
@app.get("/api/getCount")
def get_data():
try:
diseaselen = neo4j_client.count_nodes_by_label(label="Disease")
druglen = neo4j_client.count_nodes_by_label(label="Drug")
checklen = neo4j_client.count_nodes_by_label(label="Check")
data={
"Disease":diseaselen,
"Drug":druglen,
"Check":checklen
}
return Response(
status_code=200,
description=jsonify(data),
headers={"Content-Type": "text/plain; charset=utf-8"}
)
except Exception as e:
error_trace = traceback.format_exc()
print(error_trace)
return jsonify({"error": str(e)}), 500
3 months ago
@app.post("/api/getGraph")
def get_graph(req):
try:
# 1. 获取 JSON body(自动解析为 dict)
body = req.json()
# 2. 提取 label 字段(即疾病名称)
disease_name = body.get("label")
if not disease_name:
return jsonify({"error": "Missing 'label' in request body"}), 400
graph_data = build_g6_subgraph_by_props(
neo4j_client,
node_label=body.get("type"),
node_properties={"name": disease_name},
direction="both",
rel_type=None
)
return Response(
status_code=200,
description=jsonify(graph_data),
headers={"Content-Type": "text/plain; charset=utf-8"}
)
except Exception as e:
return jsonify({"error": str(e)}), 500
@app.get("/api/drug-tree")
def get_drug_tree():
3 months ago
print(redis_get(DRUG_TREE_KEY))
3 months ago
return Response(
status_code=200,
description=redis_get(DRUG_TREE_KEY),
headers={"Content-Type": "application/json; charset=utf-8"}
)
# try:
# names = get_drug_names_from_neo4j()
# print(f"[Step 1] Loaded {len(names)} names")
#
# groups = {}
# for name in names:
# key = get_group_key(name)
# groups.setdefault(key, []).append(name)
# print(f"[Step 2] Grouped into {len(groups)} groups")
#
# # ✅ 顺序:A-Z, 0-9, 其他
# alphabet = [chr(i) for i in range(ord('A'), ord('Z') + 1)]
# all_keys = alphabet + ["0-9", "其他"]
#
# tree_data = []
# total_children = 0
# for key in all_keys:
# if key in groups:
# children = [{"label": name,"type":"Drug"} for name in sorted(groups[key])]
# total_children += len(children)
# tree_data.append({"label": key,"type":"Drug", "children": children})
#
# print(f"[Step 3] Final tree: {len(tree_data)} groups, {total_children} drugs")
#
# json_str = json.dumps(tree_data, ensure_ascii=False)
# print(f"[Step 4] JSON size: {len(json_str)} chars")
#
# return Response(
# status_code=200,
# description=json_str,
# headers={"Content-Type": "application/json; charset=utf-8"}
# )
# except Exception as e:
# print(f"[ERROR] {str(e)}")
# return Response(
# status_code=500,
# description=json.dumps({"error": str(e)}, ensure_ascii=False),
# headers={"Content-Type": "application/json; charset=utf-8"}
# )
@app.get("/api/check-tree")
def get_check_tree():
return Response(
status_code=200,
description=redis_get(CHECK_TREE_KEY),
headers={"Content-Type": "application/json; charset=utf-8"}
)
# try:
# names = get_check_names_from_neo4j()
# print(f"[Step 1] Loaded {len(names)} names")
#
# groups = {}
# for name in names:
# key = get_group_key(name)
# groups.setdefault(key, []).append(name)
# print(f"[Step 2] Grouped into {len(groups)} groups")
#
# # ✅ 顺序:A-Z, 0-9, 其他
# alphabet = [chr(i) for i in range(ord('A'), ord('Z') + 1)]
# all_keys = alphabet + ["0-9", "其他"]
#
# tree_data = []
# total_children = 0
# for key in all_keys:
# if key in groups:
# children = [{"label": name,"type":"Check"} for name in sorted(groups[key])]
# total_children += len(children)
# tree_data.append({"label": key,"type":"Check", "children": children})
#
# print(f"[Step 3] Final tree: {len(tree_data)} groups, {total_children} checks")
#
# json_str = json.dumps(tree_data, ensure_ascii=False)
# print(f"[Step 4] JSON size: {len(json_str)} chars")
#
# return Response(
# status_code=200,
# description=json_str,
# headers={"Content-Type": "application/json; charset=utf-8"}
# )
# except Exception as e:
# print(f"[ERROR] {str(e)}")
# return Response(
# status_code=500,
# description=json.dumps({"error": str(e)}, ensure_ascii=False),
# headers={"Content-Type": "application/json; charset=utf-8"}
# )
3 months ago
@app.get("/api/disease-tree")
def get_disease_tree():
return Response(
status_code=200,
description=redis_get(DISEASE_TREE_KEY),
headers={"Content-Type": "application/json; charset=utf-8"}
)
@app.get("/api/disease-depart-tree")
def get_department_disease_tree():
try:
tree_data = neo4j_client.get_department_disease_tree()
return Response(
status_code=200,
description=jsonify(tree_data),
headers={"Content-Type": "text/plain; charset=utf-8"}
)
except Exception as e:
error_trace = traceback.format_exc()
print("Error in /api/tree:", error_trace)
return jsonify({"error": str(e)}), 500
@app.get("/api/drug-subject-tree")
def get_drug_subject_tree():
try:
tree_data = neo4j_client.get_subject_drug_tree()
return Response(
status_code=200,
description=jsonify(tree_data),
headers={"Content-Type": "text/plain; charset=utf-8"}
)
except Exception as e:
error_trace = traceback.format_exc()
print("Error in /api/tree:", error_trace)
return jsonify({"error": str(e)}), 500
3 months ago
@app.get("/health")
def health():
print(redis_get(DRUG_TREE_KEY))
print(redis_get(CHECK_TREE_KEY))
3 months ago
return {"status": "ok", "drug_cached": redis_get(DRUG_TREE_KEY) is not None}
3 months ago
# @app.post("/api/analyze")
# async def analyze(request):
# # 假设前端传入 JSON: {"text": "病例文本..."}
# body = request.json()
# input_text = body.get("text", "").strip()
#
# if not input_text:
# return jsonify({"error": "缺少 text 字段"}), 400
# client = httpx.AsyncClient(base_url="http://192.168.50.113:8088")
# # 调用实体关系抽取服务
# response = await client.post(
# "/extract_entities_and_relations",
# json={"text": input_text}
# )
# print(response)
# if response.status_code == 200:
# result = response.json()
# return jsonify(result)
# else:
# return jsonify({
# "error": "实体抽取服务返回错误",
# "status": response.status_code,
# "detail": response.text
# }), response.status_code