- wwwroot/api/ 六个对外端点(Bearer Key 鉴权,路由授 any、业务鉴权在 api_core):
kb_create/kb_delete/doc_upload/doc_delete/tag_create/doc_set_tags/search
- rag/api_core.py: verify_api_key + make_api_env(org注入) + 六个业务核心
(复用 init.py 底层检索/入库能力,杜绝双实现分叉)
- 统一返回格式 {"status":"ok"|"error","data":...}
- rag/ingest.py: 入库管线从 upload_file.dspy 抽出共享(UI/API同一引擎)
- rag/tools.py: RAG_TOOL_SCHEMAS + exec_rag_tool(与API同构,供内部助手调用)
- rag_api_keys 表 model(key 只存 SHA256);管理端 api_key_create/list/revoke
- load_path.py 注册 7 个 API 端点(any) + 3 个管理端点(logined)
36 lines
2.3 KiB
Plaintext
36 lines
2.3 KiB
Plaintext
# 管理端:API Key 列表(本机构;只展示前缀,不回显明文)
|
||
# GET /rag/knowledge_bases_list/api_key_list.dspy
|
||
ns = params_kw.copy()
|
||
env = request._run_ns
|
||
org_id = await env.get_userorgid()
|
||
rows = []
|
||
db = DBPools()
|
||
async with db.sqlorContext(get_module_dbname('rag')) as sor:
|
||
recs = await sor.sqlExe(
|
||
"SELECT id, name, prefix, scopes, status, last_used_at, expires_at, created_at "
|
||
"FROM rag_api_keys WHERE org_id=${o}$ ORDER BY created_at DESC", {"o": org_id})
|
||
await sor.sqlExe("COMMIT", {})
|
||
for r in (recs or []):
|
||
st = getattr(r, 'status', '')
|
||
badge = '🟢' if st == 'active' else '⛔'
|
||
exp = str(getattr(r, 'expires_at', '') or '')
|
||
exp_s = ('至 ' + exp[:10]) if exp and exp != 'None' else '永久'
|
||
used = str(getattr(r, 'last_used_at', '') or '')
|
||
used_s = used[:16] if used and used != 'None' else '从未使用'
|
||
rows.append({"widgettype": "HBox", "options": {"spacing": "12px", "padding": "8px 12px", "borderBottom": "1px solid #eee"},
|
||
"subwidgets": [
|
||
{"widgettype": "Text", "options": {"text": badge + " " + str(getattr(r, 'name', '') or ''), "cfontsize": 13}},
|
||
{"widgettype": "Text", "options": {"text": str(getattr(r, 'prefix', '')) + '…', "cfontsize": 12, "color": "#888"}},
|
||
{"widgettype": "Text", "options": {"text": str(getattr(r, 'scopes', '') or ''), "cfontsize": 11, "color": "#aaa"}},
|
||
{"widgettype": "Text", "options": {"text": exp_s + " · " + used_s, "cfontsize": 11, "color": "#aaa"}},
|
||
{"widgettype": "Button", "options": {"label": ("禁用" if st == 'active' else "启用"), "cfontsize": 11},
|
||
"binds": [{"wid": "self", "event": "click", "actiontype": "ajax",
|
||
"options": {"url": entire_url('./api_key_revoke.dspy'),
|
||
"params": {"key_id": str(getattr(r, 'id', '')),
|
||
"action": ("disable" if st == 'active' else "enable")},
|
||
"success": "refresh"}}]},
|
||
]})
|
||
if not rows:
|
||
rows = [{"widgettype": "Text", "options": {"text": "暂无 API Key", "color": "#aaa"}}]
|
||
return {"widgettype": "VBox", "options": {"width": "100%"}, "subwidgets": rows}
|