- config.toml:--encrypt 会先 PyArmor 混淆 main.py / server.py,PyInstaller 静态 分析跟不到 `from chongming.app import app`,网关包整个漏收(打包"成功"、产物 启动报 No module named 'chongming')—— 显式列 chongming / chongming.app 等入口包; - public/config.toml:补 [license] 段(public_key 留空),--license 的注入点; - README.project.md:补授权公钥前置条件(keygen → license_public.key 或环境变量), 以及 --only 对 obfuscate 同样划界(加密构建要显式带上,否则混淆被静默跳过)。
5.8 KiB
5.8 KiB
{{app_name}}
基于 chongming 网关的宿主项目(由 chongming 项目模板初始化):
- 网关本体:
chongming-gateway包(FastAPI + Zenoh),从私有源按版本依赖,不在本仓库 - 本仓库负责:宿主骨架(
public/,可执行文件入口)、内置插件(src/plugins/)、 配置(config/)、构建与交付产物
快速开始
uv sync # 同步依赖(网关与 chongming-* 工具包从私有源安装)
uv run serve # 启动服务(开发模式,热重载)
| 通道 | 地址 | 说明 |
|---|---|---|
| HTTP | http://localhost:8000 |
REST API(config.toml 的 prefix 为 /api/v1) |
| Swagger | http://localhost:8000/docs |
OpenAPI 交互文档(调试模式开启) |
| MQTT | mqtt://localhost:1883 |
内嵌 Broker(use_embedded_broker = true) |
开箱示例(内置插件 example):
curl 'http://localhost:8000/api/v1/example/hello?name=world'
# {"message":"hello, world!","count":1}
curl -X POST http://localhost:8000/api/v1/example/hello \
-H 'Content-Type: application/json' -d '{"name":"world"}'
目录结构
├── config.toml # 应用主配置(环境、服务器、缓存、MQTT、打包清单)
├── pyproject.toml # 宿主依赖(chongming-gateway 等)
├── plugins_deps.toml # 内置插件专属依赖(打包收集用)
├── public/ # 可执行文件打包骨架:main.py / server.py / utils / 运行时 config.toml
├── config/ # 项目配置
│ ├── zenoh_config.json5 # Zenoh 会话配置
│ └── workers/<type>/ # 插件注册(config.toml)与端点定义(<op>.toml)
├── src/plugins/ # 内置插件源码(inline,网关进程内加载)
│ └── example/ # 最小示例:Plugin 生命周期 + @rpc_method + 模型
├── workers/ # 进程插件本地开发目录(external,不入库;生产独立容器)
└── resources/ # 构建产物(plugins.mbank 等)
新增插件 / 端点
uv run gen_plugin <name> [operation ...] # 一键生成内置插件骨架(含 config/ 注册与端点 TOML)
uv run gen_models config/workers/<name> src/plugins/<name> # 改 TOML 后重新生成模型
手写流程(参考 src/plugins/example/ 的四个文件):
config/workers/<name>/config.toml:[workers]注册(type/module = "plugins.<name>"/factory/cleanup/count/load_mode)+[worker]路由前缀与端点默认值config/workers/<name>/<op>.toml:端点定义([GET]/[POST]/[MQTT]分节 +params+response_model)uv run gen_models ...生成models/pydantic.pyrouter/<op>.py:@rpc_method(subject="<name>.<op>", method=...)实现; 在router/__init__.py导入
启动时网关会做契约校验:TOML 里的 HTTP 路由缺少对应 @rpc_method 会直接启动失败。
进程插件(load_mode = "external",独立进程/容器部署):
uv run gen_plugin <name> --process # 生成自包含插件项目 workers/<name>/
cd workers/<name> && uv run chongming-worker --type <name> # 本地调试
uv run build_plugin <name> # 打包 → dist/<name>.zip(容器入口 start.sh)
配置
- 应用配置:根
config.toml(开发读[development];[default].env切换环境) - 插件注册与端点:
config/workers/<type>/config.toml、config/workers/<type>/<op>.toml - Zenoh:
config/zenoh_config.json5
常用开关:
| 配置 | 位置 | 说明 |
|---|---|---|
cache.backend |
根 config.toml |
sqlite(单机默认)/ redis(多实例共享) |
mqtt.use_embedded_broker |
根 config.toml |
true 自带 Broker;false 连外部 Broker |
workers.count |
插件 config.toml |
副本数(多网关共享 cache 时按在线网关分摊) |
workers.load_mode |
插件 config.toml |
inline(默认)/ external |
打包与部署
uv run build pyinstaller # 打包可执行文件 → build/chongming
uv run build nuitka # Nuitka 打包(Linux 需宿主 patchelf)
uv run build --encrypt --license # 对外分发:加密插件模块 + 注入授权公钥
uv run build --only mbank # 只重新生成 plugins.mbank(插件热更新只需替换该文件)
--encrypt --license需要厂商授权公钥(未提供会直接构建失败):先uv run chongming-license keygen -o license_private.pem生成密钥对(一次性;私钥离线保管, 绝不进仓库/产物),把输出的公钥写入根目录license_public.key(或用CHONGMING_LICENSE_PUBKEY/CHONGMING_LICENSE_PUBKEY_FILE指定),再构建- 无前端时跳过 vue 步骤:
uv run build pyinstaller --only mbank,prepare,pack(--only对所有步骤划界:加密构建还要显式带上obfuscate,如uv run build --encrypt --license --only mbank,prepare,obfuscate,pack,license_guard, 否则 PyArmor 混淆会被静默跳过) - 插件代码在
plugins.mbank里 → 换文件即可热更新;网关本体是普通依赖 → 升级网关需改pyproject.toml版本(或uv lock --upgrade-package chongming-gateway) 并重新uv run build - 新增插件用了新第三方包时:
pyproject.toml追加依赖 +plugins_deps.toml声明 (否则打包产物运行到加载插件时才报 ImportError)
进一步文档
网关主体、插件开发、进程插件、Worker 运维等完整文档在 chongming-core(chongming-zenoh)仓库的
README.md 与 docs/;本仓库的管理端点、实例定向、MQTT 协议等用法与之一致。