Explorar o código

feat(mode_workflow): GET /api/category_tree 拉取+缓存 实质/形式 分类树

刘文武 hai 1 semana
pai
achega
ff41136c4f
Modificáronse 1 ficheiros con 26 adicións e 0 borrados
  1. 26 0
      examples/mode_workflow/server.py

+ 26 - 0
examples/mode_workflow/server.py

@@ -25,6 +25,7 @@ from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
 from pathlib import Path
 from urllib.parse import urlparse, parse_qs
 import urllib.request
+import urllib.parse
 import urllib.error
 
 try:
@@ -49,6 +50,29 @@ def _matrix():
     return _MATRIX_CACHE
 
 
+CATEGORY_API = "https://library.aiddit.com/api/pattern/executions/401/category-tree"
+CAT_CACHE_DIR = HERE / ".cache" / "category_tree"
+
+
+def _category_tree(source_type):
+    """拉取并缓存 实质/形式 分类树(library.aiddit.com)。缓存命中直接读盘;
+    上游不可达则抛异常(do_GET 转 500,前端降级)。"""
+    if source_type not in ("实质", "形式"):
+        raise ValueError("source_type 只能是 实质/形式")
+    CAT_CACHE_DIR.mkdir(parents=True, exist_ok=True)
+    cache = CAT_CACHE_DIR / f"{source_type}.json"
+    if cache.is_file():
+        return json.loads(cache.read_text(encoding="utf-8"))
+    url = CATEGORY_API + "?" + urllib.parse.urlencode({"source_type": source_type})
+    req = urllib.request.Request(url, headers={"Accept": "application/json"})
+    with urllib.request.urlopen(req, timeout=20) as resp:
+        data = json.loads(resp.read().decode("utf-8"))
+    tmp = cache.with_suffix(".tmp")
+    tmp.write_text(json.dumps(data, ensure_ascii=False), encoding="utf-8")
+    tmp.replace(cache)
+    return data
+
+
 LOG_DIR = HERE / "runs" / "logs"
 # 工序步骤 via 字段的「无具体工具」占位符,不计入工序提及工具 TOP 榜
 _VIA_PLACEHOLDERS = {"-", "—", "-", "--", "/", "无", "n/a", "none"}
@@ -435,6 +459,8 @@ class Handler(BaseHTTPRequestHandler):
                 self.wfile.write(body)
             elif u.path == "/api/query_matrix":
                 self._json_etag(_matrix())
+            elif u.path == "/api/category_tree":
+                self._json_etag(_category_tree(qs.get("source_type", "实质")))
             elif u.path == "/api/dashboard":
                 self._json_etag(_dashboard_cached())
             elif u.path == "/api/queries":