子系统接入指南
新建一个子系统,放个文件就能接进工具站,不用改任何主程序代码。
一、一句话原理
工具站有个「动态蓝图加载器」(toolpage/loader.py + toolpage/registry.py),它会在 TOOLPAGE 目录下递归扫描所有以 _touse.py 结尾的文件,逐个隔离导入并注册成 Flask 蓝图。
所以接入一个新子系统 = 新建一个 XXX_touse.py 文件,仅此而已。加文件、重启(或点看板「刷新目录」),它就出现在首页目录里了。
二、必须遵守的 5 条约定
| 约定 | 规则 | 示例 |
|---|---|---|
| 文件名 | 必须以 _touse.py 结尾 | MYTOOL_touse.py |
| 蓝图变量 | 定义蓝图实例,变量名 = 文件名去掉后缀,即 XXX_bp | MYTOOL_bp = Blueprint(...) |
| 蓝图 name | Blueprint(name, ...) 的 name 填 XXX(与 slug 相同),全站必须唯一 | Blueprint("MYTOOL", __name__) |
| 展示标题 | 顶层定义 msystem_name = "中文名",首页用它做卡片标题;不写回落用文件名 | msystem_name = "我的小工具" |
| 访问路由 | 自动挂在 /XXX。内部路由用 XXX_bp.route("/xxx") | /MYTOOL、/MYTOOL/do |
目录分组(决定首页归类)
- 文件放在
TOOLPAGE下的某一级文件夹里,文件夹名 = 首页的「分组」名; - 二级子文件夹 = 该分组下的「小类」名(多个层级会被压平成一个小类名);
- 直接扔在
TOOLPAGE根目录的散装文件不会进目录树(必须放进某个文件夹)。
推荐结构:
TOOLPAGE/
└── 我的分组/ <- 首页分组名
└── 小类/ <- 首页小类名(可省略)
├── MYTOOL_touse.py <- 子系统主文件
└── MYTOOL_Config/ <- 子系统私有资源(模板/数据/依赖)
安全红线(别踩)
- 不要在模块顶层调用
os.chdir(); - 路由前缀
/XXX不要和核心路由撞车:/api/dashboard/monitor/about/static/_tp已占用; - 用户可控输入要清洗 + 限制长度,别直接拼命令 / 拼路径;
- 模板若自带
templates目录,用Blueprint("MYTOOL", __name__, template_folder=os.path.dirname(__file__) + "/MYTOOL_Config/templates")指绝对路径。
三、最小可运行模板
复制下面这段,把 MYTOOL 换成你的子系统名即可:
# MYTOOL_touse.py
import os
from flask import Blueprint, render_template, request, jsonify
# 1) 首页展示标题(中文),不写则回落用文件名
msystem_name = "我的小工具"
# 2) 蓝图:name 用 slug(去掉 _touse 的部分),全站唯一
MYTOOL_bp = Blueprint("MYTOOL", __name__,
template_folder=os.path.dirname(__file__) + "/MYTOOL_Config/templates")
# 3) 页面路由:自动挂在 /MYTOOL
@MYTOOL_bp.route("/")
def index():
return "<h2>你好,这是我的子系统</h2>"
# 4) 接口路由:挂在 /MYTOOL/api
@MYTOOL_bp.route("/api", methods=["POST"])
def api():
name = (request.form.get("name") or "").strip()[:64] # 记得限长
return jsonify({"ok": True, "echo": name})
放好文件 → 重启工具站(或看板点「刷新目录」)→ 首页「我的分组 / 小类」下就会出现「我的小工具」卡片,点进去就是 /MYTOOL。
四、给 AI 的接入提示词(直接复制给 AI 用)
我要给一个叫「TOOLPAGE」的 Flask 工具站新增一个自建子系统。
这个工具站有一个动态蓝图加载器,约定如下,请严格遵守:
【接入约定】
1. 新建文件必须命名为 <子系统名>_touse.py(例如 MYTOOL_touse.py),放在 TOOLPAGE 目录下的某个文件夹里(不要直接放根目录)。
2. 文件顶层必须定义 msystem_name = "中文展示标题"。
3. 文件顶层必须定义蓝图实例,变量名 = <子系统名>_bp,Blueprint 的 name 参数填 <子系统名>(与文件名去掉 _touse 后缀一致),全站唯一。
4. 子系统首页路由用 <子系统名>_bp.route("/"),自动映射到 /<子系统名>;其它路由都挂在 /<子系统名>/... 下。
5. 不要使用以下已占用路由前缀:/api /dashboard /monitor /about /static /_tp。
6. 不要做 os.chdir;不要执行未清洗的用户输入;用户输入要限长(建议 <= 200 字符)并做类型/范围校验。
7. 如果子系统需要自己的 HTML 模板,用 Blueprint(name, __name__, template_folder=os.path.dirname(__file__) + "/<子系统名>_Config/templates") 指定绝对路径。
【交付要求】
- 只输出这一个 .py 文件(含必要注释),以及一个可选的 <子系统名>_Config 目录说明。
- 给出一个「放好文件后如何验证接入成功」的步骤清单(重启工具站 / 看板刷新目录 / 打开 /<子系统名>)。
- 不要改动工具站主程序(toolpage/ 下的任何文件)。
我的子系统需求是:<在这里描述你的功能>
五、常见问题
为什么我的模块没出现在首页?
文件名不是
_touse.py 结尾?直接放根目录了(根目录散装文件不进目录树,请放进某个文件夹)?模块导入报错?去看「关于」页或 /api/health,加载失败的模块会列在那里并带错误原因。两个子系统路由打架了?
多半是
Blueprint(name, ...) 的 name 重名了,确保每个子系统的蓝图 name 唯一。怎么不重启就生效?
数据看板 → 运维操作 → 「刷新目录」,加载器会重新扫描注册(个别深度改动的仍建议重启)。