diff --git a/README.md b/README.md deleted file mode 100644 index a2b0842..0000000 --- a/README.md +++ /dev/null @@ -1,249 +0,0 @@ -# 配置文件说明 - -本目录存放应用的 TOML 配置文件,分为三层:应用主配置、Worker 注册配置、端点路由配置。 - ---- - -## 文件总览 - -```text -config/ -├── zenoh_config.json5 # Zenoh 会话配置(JSON5 格式) -└── workers/ - ├── config.toml # Worker 插件加载列表 - ├── auth/ # 鉴权插件 - │ ├── config.toml # 分组配置(路由前缀、默认值) - │ ├── register.toml # 用户注册 - │ ├── login.toml # 登录 - │ ├── me.toml # 获取用户信息 - │ ├── change_password.toml # 修改密码 - │ └── update_profile.toml # 更新资料 - ├── doubao/ # 豆包视觉理解插件 - │ ├── config.toml - │ └── analyze.toml - ├── aibox_sophon_adapter/ # AI Box 设备监控插件 - │ ├── config.toml - │ ├── board_ping.toml # 设备心跳 - │ ├── list_devices.toml # 设备列表 - │ ├── get_device.toml # 设备详情 - │ ├── get_offline_devices.toml # 离线设备 - │ ├── get_alarm.toml # 告警详情 - │ └── list_alarms.toml # 告警列表 - └── example/ # 示例插件 - ├── config.toml - ├── add.toml - ├── subtract.toml - ├── multiply.toml - ├── divide.toml - └── count.toml -``` - -> **注意**:应用主配置 `config.toml` 位于项目根目录,不在本 `config/` 目录下。 - ---- - -## 1. 应用主配置(根目录 `config.toml`) - -定义应用全局设置:环境、服务器、日志、安全、缓存、MQTT 等。 - -### 主要节 - -| 节 | 说明 | -| ---------------------------- | ----------------------------------------------------------------------------------------------------- | -| `[default]` | 应用元信息:`app.name`, `app.version`, `app.description`, `app.debug`, `env`, `prefix`, `upload_path` | -| `[zenoh]` | Zenoh 配置:`json5_path` 指向 Zenoh 会话配置文件 | -| `[scheduler]` | 任务调度器:`job_store_path` | -| `[cache]` | 缓存:`cache_store_path` | -| `[security]` | JWT 安全:`secret_key`, `algorithm` | -| `[development]` | 开发环境配置(server、logging、cors、mqtt) | -| `[production]` | 生产环境配置 | -| `[plugins_worker]` | 插件 Worker 注册配置路径 | -| `[pyinstaller_build_import]` | PyInstaller 打包时的隐式导入声明 | - -### 开发环境配置示例 - -```toml -[development] -debug = true -env = "development" - -[development.server] -host = "0.0.0.0" -port = 8000 -reload = true -access_log = false - -[development.logging] -file = "logs" -level = "DEBUG" -format = "%(asctime)s - %(name)s - %(levelname)s - %(message)s" - -[development.cors] -allow_origins = ["*"] -allow_methods = ["*"] -allow_headers = ["*"] -allow_credentials = true - -[development.mqtt] -enabled = true -host = "0.0.0.0" -port = 1883 -``` - ---- - -## 2. 插件注册配置(`workers//config.toml` 的 `[workers]` 节) - -定义哪些插件被加载及运行时参数。网关启动时扫描 `config/workers/*/config.toml` 自动发现; -**每个插件在自己目录的 `config.toml` 中用 `[workers]` 节注册**(与 `[worker]` 路由默认值共存于同一文件)。 - -```toml -# config/workers/auth/config.toml -[workers] -type = "auth" # 插件类型名(worker type) -module = "plugins.auth" # Python 模块路径 -factory = "create_workers" # 工厂函数名(Plugin 基类绑定的方法) -cleanup = "cleanup" # 清理函数名 -count = 3 # Worker 副本数 - -[workers.config] -data_dir = "./data" # 插件运行时配置(展平后传给 create_workers) -``` - -> 旧式全局文件 `config/workers/config.toml`(`[[workers]]` 数组)仍兼容读取, -> 仅加载其中尚未由各插件自注册的类型,新插件请勿使用。 - -### 字段说明 - -| 字段 | 必填 | 说明 | -| ------------------ | ---- | ---------------------------------------------------- | -| `type` | ✅ | 插件类型名,需与 `config/workers//` 目录名一致 | -| `module` | ✅ | Python 模块导入路径 | -| `factory` | ✅ | 工厂函数名,用于创建 Worker 实例 | -| `cleanup` | ❌ | 清理函数名,插件卸载时调用 | -| `count` | ✅ | Worker 副本数(并行处理请求数) | -| `[workers.config]` | ❌ | 传递给插件的运行时配置(展平合并,子节见各插件) | -| `[[workers.mqtt_topics]]` | ❌ | 插件声明的 MQTT Bridge 额外订阅主题(topic/subject/response_topic) | - ---- - -## 3. 分组配置(`workers//config.toml` 的 `[worker]` 节) - -每个插件目录下的 `config.toml` 定义该插件所有路由的公共默认值 -(与第 2 节的 `[workers]` 注册节共存于同一文件)。 - -```toml -[worker] -name = "example" -version = "0.1.0" -description = "示例插件" -defaults = { timeout = 3.0, auth_required = false, cacheable = true, internal = false } - -[worker.registration] -router_prefix = "/calc" # 所有路由的统一前缀 -tags = ["example"] # OpenAPI 分组标签 -``` - -### 字段说明 - -| 字段 | 说明 | -| ------------------------ | ------------------------------------------- | -| `defaults.timeout` | 默认超时时间(秒) | -| `defaults.cacheable` | 端点结果是否默认缓存 | -| `defaults.auth_required` | 端点是否默认需要 JWT 鉴权 | -| `defaults.internal` | 端点是否默认仅内部调用(不注册 HTTP 路由) | -| `router_prefix` | 路由前缀,如 `/calc` → 完整路径 `/calc/add` | -| `tags` | OpenAPI 文档分组标签 | - ---- - -## 4. 端点配置 (`workers//.toml`) - -每个操作一个 TOML 文件,支持 `[GET]`、`[POST]`、`[MQTT]` 三种节类型。 - -```toml -# add.toml — 每个方法节独立定义 - -[GET] -summary = "加法运算(GET)" -docstring = "通过 URL 参数执行加法运算" -params = ["a: float", "b: float"] -cacheable = true -auth_required = false -timeout = 5.0 -internal = false - -[GET.response_model] -result = { type = "float", required = true } -operation = { type = "str", default = "add" } -timestamp = { type = "float", required = false, default = 0.0 } - -[POST] -summary = "加法运算(POST)" -params = ["a: float", "b: float"] -auth_required = true - -[POST.response_model] -result = { type = "float", required = true } - -[MQTT] -summary = "加法运算(MQTT)" -params = ["a: float", "b: float"] -``` - -### 端点字段 - -| 字段 | 类型 | 默认值 | 说明 | -| --------------- | ----------- | ------------------------ | ---------------------------------------------------- | -| `summary` | `str` | — | 端点描述,显示在 OpenAPI 文档 | -| `docstring` | `str` | — | 详细说明(可选) | -| `params` | `list[str]` | `[]` | 参数列表,格式 `"name: type"` | -| `cacheable` | `bool` | `defaults.cacheable` | 结果是否可缓存 | -| `auth_required` | `bool` | `defaults.auth_required` | 是否需要 JWT 鉴权 | -| `timeout` | `float` | `defaults.timeout` | RPC 超时(秒) | -| `internal` | `bool` | `false` | 设为 `true` 则只允许内部 Zenoh RPC,不注册 HTTP 路由 | - -### 响应模型字段 - -```toml -[GET.response_model] -required_field = { type = "str", required = true } -optional_field = { type = "int", required = false, default = 0 } -``` - -支持的 `type` 值: - -| TOML 类型 | Python 类型 | -| ------------------ | ---------------- | -| `str` / `string` | `str` | -| `int` / `integer` | `int` | -| `float` / `number` | `float` | -| `bool` / `boolean` | `bool` | -| `dict` | `dict[str, Any]` | -| `list[type]` | `list[type]` | -| `Optional[type]` | `Optional[type]` | - ---- - -## 修改配置后 - -修改任何 TOML 配置后,**必须重新生成 Pydantic 模型**: - -```bash -uv run python -m chongming.scripts.gen_models -``` - -该命令扫描 `config/workers/*/` 下所有 `.toml` 文件,自动更新 `src/plugins/*/models/pydantic.py`。 - ---- - -## 配置层级与优先级 - -``` -config.toml (全局) - └─ workers//config.toml (插件注册 [workers] 节 + 分组默认值 [worker] 节) - └─ workers//.toml (端点覆盖) -``` - -每层可覆盖上层默认值,端点级字段 (`timeout`, `cacheable`, `auth_required`, `internal`) 优先级最高。 -(旧式 `workers/config.toml` 全局注册文件仍兼容读取,仅作兜底。) diff --git a/workers/auth/change_password.toml b/workers/auth/change_password.toml deleted file mode 100644 index b5f443e..0000000 --- a/workers/auth/change_password.toml +++ /dev/null @@ -1,11 +0,0 @@ -[POST] -cacheable = false -auth_required = true -summary = "修改密码" -docstring = "验证旧密码后更新为新密码" -params = ["user_id: str", "old_password: str", "new_password: str"] - -[POST.response_model] -result = {type = "str", required = true} -message = {type = "str", required = true} -timestamp = {type = "float", required = false} diff --git a/workers/auth/config.toml b/workers/auth/config.toml deleted file mode 100644 index 6e2a4d2..0000000 --- a/workers/auth/config.toml +++ /dev/null @@ -1,21 +0,0 @@ -# ====== 插件注册信息(控制加载方式) ====== -[workers] -type = "auth" -module = "plugins.auth" -factory = "create_workers" -cleanup = "cleanup" -count = 0 - -[worker] -name = "auth" -version = "0.1.0" -description = "鉴权管理" -config_version = "1.0" -defaults = { method = "GET", ttl = 30, timeout = 2.0, auth_required = true, cacheable = false } - -[worker.registration] -router_prefix = "/auth" -tags = ["auth"] - -# ====== Worker 运行时配置(由 lifespan_setup 传递给 create_workers) ====== -[workers.config] diff --git a/workers/auth/me.toml b/workers/auth/me.toml deleted file mode 100644 index 8368a27..0000000 --- a/workers/auth/me.toml +++ /dev/null @@ -1,21 +0,0 @@ -[GET] -cacheable = false -auth_required = true -summary = "获取当前用户信息" -docstring = "根据用户ID获取用户详细信息" -params = ["user_id: str"] - -[GET.response_model] -result = {type = "str", required = true} -id = {type = "str", required = true} -username = {type = "str", required = true} -email = {type = "str", required = true} -full_name = {type = "str", required = false} -avatar_url = {type = "str", required = false} -phone = {type = "str", required = false} -is_active = {type = "bool", required = true} -is_verified = {type = "bool", required = true} -is_superuser = {type = "bool", required = true} -created_at = {type = "str", required = false} -updated_at = {type = "str", required = false} -last_login_at = {type = "str", required = false} diff --git a/workers/auth/register.toml b/workers/auth/register.toml deleted file mode 100644 index fc7f166..0000000 --- a/workers/auth/register.toml +++ /dev/null @@ -1,12 +0,0 @@ -[POST] -cacheable = false -auth_required = false -summary = "用户注册" -docstring = "创建新用户账号,用户名和邮箱必须唯一" -params = ["username: str", "password: str", "email: str", "full_name: str", "phone: str"] - -[POST.response_model] -result = {type = "str", required = true} -message = {type = "str", required = true} -user_id = {type = "str", required = false} -timestamp = {type = "float", required = false} diff --git a/workers/auth/update_profile.toml b/workers/auth/update_profile.toml deleted file mode 100644 index 39f54cd..0000000 --- a/workers/auth/update_profile.toml +++ /dev/null @@ -1,11 +0,0 @@ -[POST] -cacheable = false -auth_required = true -summary = "更新用户资料" -docstring = "更新当前用户的基本资料信息(全名、邮箱、头像、手机号)" -params = ["user_id: str", "full_name: str", "email: str", "avatar_url: str", "phone: str"] - -[POST.response_model] -result = {type = "str", required = true} -message = {type = "str", required = true} -timestamp = {type = "float", required = false} diff --git a/workers/auth_oauth/config.toml b/workers/auth_oauth/config.toml deleted file mode 100644 index 9da467d..0000000 --- a/workers/auth_oauth/config.toml +++ /dev/null @@ -1,34 +0,0 @@ -# ====== 插件注册信息(控制加载方式) ====== -[workers] -type = "auth_oauth" -module = "plugins.auth_oauth" -factory = "create_workers" -cleanup = "cleanup" -count = 0 -# 身份源插件持有签名密钥的使用方(issue_token),走 inline 与网关同信任域; -# external 部署前需先解决密钥下发问题(见插件 README 安全说明) -load_mode = "inline" - -[worker] -name = "auth_oauth" -version = "0.1.0" -description = "第三方授权登录示例(GitHub OAuth / 手机验证码)" -config_version = "1.0" -defaults = { method = "GET", ttl = 30, timeout = 10.0, auth_required = false, cacheable = false } - -[worker.registration] -router_prefix = "/auth/oauth" -tags = ["auth_oauth"] - -# ====== Worker 运行时配置 ====== -[workers.config] -data_dir = "./data" -# 演示模式:验证码随响应返回(无短信通道的本地演示)。生产必须置 false 并接真实短信通道 -return_otp_in_response = true - -# GitHub OAuth App 凭据(https://github.com/settings/developers 创建) -[workers.config.github] -client_id = "your-github-oauth-client-id" -client_secret = "your-github-oauth-client-secret" -redirect_uri = "http://localhost:5173/auth/oauth/github/callback" -scope = "read:user user:email" diff --git a/workers/auth_oauth/github_authorize.toml b/workers/auth_oauth/github_authorize.toml deleted file mode 100644 index bb34167..0000000 --- a/workers/auth_oauth/github_authorize.toml +++ /dev/null @@ -1,5 +0,0 @@ -[GET] -summary = "GitHub 授权登录:生成授权跳转 URL" -docstring = "生成 GitHub OAuth 授权链接(含防 CSRF 的 state,存共享缓存 300s)。前端拿 authorize_url 自行跳转。" -auth_required = false -cacheable = false diff --git a/workers/auth_oauth/github_callback.toml b/workers/auth_oauth/github_callback.toml deleted file mode 100644 index 36dd428..0000000 --- a/workers/auth_oauth/github_callback.toml +++ /dev/null @@ -1,12 +0,0 @@ -[POST] -summary = "GitHub 授权回调:换取用户信息并签发平台 token" -docstring = "前端收到 GitHub 回跳的 code+state 后调用;校验 state(一次性)、换取用户信息、按绑定关系 find-or-create 账号,签发与内置登录同契约的平台 token。" -auth_required = false -cacheable = false -params = ["code: str", "state: str"] - -[POST.response_model] -result = { type = "str", required = true } -token = { type = "str", required = true } -message = { type = "str", required = true } -timestamp = { type = "float", required = false } diff --git a/workers/auth_oauth/phone_login.toml b/workers/auth_oauth/phone_login.toml deleted file mode 100644 index 367d5ef..0000000 --- a/workers/auth_oauth/phone_login.toml +++ /dev/null @@ -1,12 +0,0 @@ -[POST] -summary = "手机验证码登录:校验验证码并签发平台 token" -docstring = "校验一次性验证码后,按手机号绑定关系 find-or-create 账号,签发与内置登录同契约的平台 token。" -auth_required = false -cacheable = false -params = ["phone: str", "code: str"] - -[POST.response_model] -result = { type = "str", required = true } -token = { type = "str", required = true } -message = { type = "str", required = true } -timestamp = { type = "float", required = false } diff --git a/workers/auth_oauth/phone_send_code.toml b/workers/auth_oauth/phone_send_code.toml deleted file mode 100644 index 2da823d..0000000 --- a/workers/auth_oauth/phone_send_code.toml +++ /dev/null @@ -1,12 +0,0 @@ -[POST] -summary = "手机验证码登录:下发验证码" -docstring = "生成 6 位验证码存共享缓存(300s)。演示模式随响应返回 dev_code,生产接短信通道后返回 dev_code=null。" -auth_required = false -cacheable = false -params = ["phone: str"] - -[POST.response_model] -result = { type = "str", required = true } -message = { type = "str", required = true } -expires_in = { type = "int", required = false, default = 300 } -dev_code = { type = "str", required = false } diff --git a/workers/doubao/analyze.toml b/workers/doubao/analyze.toml deleted file mode 100644 index 3f04d3b..0000000 --- a/workers/doubao/analyze.toml +++ /dev/null @@ -1,9 +0,0 @@ -[POST] -summary = "分析图片内容" -docstring = "发送图片(base64或路径)到豆包视觉模型,返回描述" -auth_required = false -params = [ - "image_base64: str", - "prompt: str" -] -response_model = { result = { type = "str", required = true }, error = { type = "str", required = false, default = "" } } \ No newline at end of file diff --git a/workers/doubao/config.toml b/workers/doubao/config.toml deleted file mode 100644 index 5d7560c..0000000 --- a/workers/doubao/config.toml +++ /dev/null @@ -1,39 +0,0 @@ -# ====== 插件注册信息(控制加载方式) ====== -[workers] -type = "doubao" -module = "plugins.doubao" -factory = "create_workers" -cleanup = "cleanup" -count = 0 - -[worker] -name = "doubao" -version = "0.1.0" -description = "火山引擎豆包视觉理解 worker" -config_version = "1.0" -defaults = { method = "POST", timeout = 30.0, auth_required = false } - -[worker.registration] -router_prefix = "/doubao" -tags = ["vision", "ai"] - -# is_aicc = true 时启用 AICC 安全通信(端云互信),使用 AsyncOpenAI + AsyncSecureHttpClient -# is_aicc = false 时使用标准 Ark SDK(AsyncArk),默认 false - -# ====== Worker 运行时配置(由 lifespan_setup 传递给 create_workers) ====== -[workers.config] -# api_key 请勿提交到仓库:留空时从环境变量 VOLC_ACCESSKEY 读取(代码中兜底) -api_key = "PLACEHOLDER-REPLACE-WITH-REAL-DOUBAO-KEY" -base_url = "https://ark.cn-beijing.volces.com/api/v3" -model = "doubao-seed-evolving" - -# AICC 模式专用配置(按需启用): -# is_aicc = true -# api_key = "" # AICC 模式的 api_key 同样经 VOLC_ACCESSKEY 提供,勿入库 -# base_url = "https:///api/v3" -# model = "ep-xxx" -# ra_url = "" # 远程证明地址(独立于 base_url 时配置) -# ra_service_name = "AICC.ConfidentialInference" -# ra_policy_id = "router_policy" -# ak = "" # 火山引擎 AK(TOP 网关鉴权模式) -# sk = "" # 火山引擎 SK(TOP 网关鉴权模式) diff --git a/workers/example/add.toml b/workers/example/add.toml deleted file mode 100644 index 0807539..0000000 --- a/workers/example/add.toml +++ /dev/null @@ -1,34 +0,0 @@ -# add 接口 — 按请求类型分节 -# subject 会带上方法后缀: example.add.GET / example.add.POST - -[GET] -cacheable = true -summary = "Add two numbers" -docstring = "Add two numbers via GET query params" -params = ["a: float", "b: float"] -auth_required = false -validate = false - -[GET.response_model] -result = { type = "float", required = true } -operation = { type = "str", default = "add" } -timestamp = { type = "float", required = false, default = 0.0 } - -[POST] -cacheable = true -summary = "Add two numbers (POST)" -docstring = "Add two numbers via POST JSON body" -params = ["a: float", "b: float"] -auth_required = true - -[POST.response_model] -result = { type = "float", required = true } -operation = { type = "str", default = "add" } -timestamp = { type = "float", required = false, default = 0.0 } - -# --- MQTT 端点(不注册 HTTP 路由,仅通过 MQTT chongming/example/add 调用)--- -[MQTT] -summary = "Add two numbers via MQTT" -docstring = "通过 MQTT 主题 chongming/example/add 调用,载荷为 JSON" -params = ["a: float", "b: float"] -auth_required = false diff --git a/workers/example/config.toml b/workers/example/config.toml deleted file mode 100644 index 3f52642..0000000 --- a/workers/example/config.toml +++ /dev/null @@ -1,27 +0,0 @@ -# ====== 插件注册信息(控制加载方式) ====== -[workers] -type = "example" -module = "plugins.example" -factory = "create_workers" -cleanup = "cleanup" -count = 0 -# 运行模式(按插件粒度,两种模式可同时存在): -# "inline"(默认)= 网关进程内加载 -# "external" = 独立进程运行(Docker/K8s 编排: uv run worker_serve --type example), -# 经 Zenoh 注册路由,网关动态挂载 -load_mode = "inline" - -[worker] -name = "example" -version = "0.1.0" -description = "chongming worker example — demonstrates new config features" -config_version = "1.0" -defaults = { method = "GET", ttl = 30, timeout = 2.0, auth_required = true, cacheable = false, internal = false } - -[worker.registration] -router_prefix = "/calc" -tags = ["example"] - -# ====== Worker 运行时配置(由 lifespan_setup 传递给 create_workers) ====== -[workers.config] -data_dir = "./data" diff --git a/workers/example/count.toml b/workers/example/count.toml deleted file mode 100644 index ab2d370..0000000 --- a/workers/example/count.toml +++ /dev/null @@ -1,6 +0,0 @@ -# count.toml -[GET] -summary = "Get visit count and increment" -docstring = "Increments a counter and returns current value" -params = [] # 无参数 -response_model = { name = { type = "str", required = true }, value = { type = "int", required = true } } \ No newline at end of file diff --git a/workers/example/divide.toml b/workers/example/divide.toml deleted file mode 100644 index a6ead12..0000000 --- a/workers/example/divide.toml +++ /dev/null @@ -1,12 +0,0 @@ -# divide 接口 - -[GET] -summary = "Divide two numbers" -docstring = "Divide two numbers via GET query params (a / b). Returns error if b == 0." -params = ["a: float", "b: float"] - -[GET.response_model] -result = { type = "float", required = false, default = 0.0 } -operation = { type = "str", default = "divide" } -timestamp = { type = "float", required = false, default = 0.0 } -error = { type = "str", required = false, default = "" } diff --git a/workers/example/heartbeat.toml b/workers/example/heartbeat.toml deleted file mode 100644 index 0a6dc85..0000000 --- a/workers/example/heartbeat.toml +++ /dev/null @@ -1,7 +0,0 @@ -# heartbeat 接口 — MQTT 心跳上报,无响应 - -[MQTT] -summary = "Heartbeat ping (no response)" -docstring = "通过 MQTT 主题 chongming/example/heartbeat 上报心跳,不返回响应" -params = ["worker_id: str"] -auth_required = false diff --git a/workers/example/multiply.toml b/workers/example/multiply.toml deleted file mode 100644 index f338c89..0000000 --- a/workers/example/multiply.toml +++ /dev/null @@ -1,11 +0,0 @@ -# multiply 接口 - -[GET] -summary = "Multiply two numbers" -docstring = "Multiply two numbers via GET query params (a * b)" -params = ["a: float", "b: float"] - -[GET.response_model] -result = { type = "float", required = true } -operation = { type = "str", default = "multiply" } -timestamp = { type = "float", required = false, default = 0.0 } diff --git a/workers/example/stream_chat.toml b/workers/example/stream_chat.toml deleted file mode 100644 index f8273e5..0000000 --- a/workers/example/stream_chat.toml +++ /dev/null @@ -1,13 +0,0 @@ -[POST] -summary = "模拟 AI 流式对话(SSE,逐 token 输出)" -docstring = "流式端点示例:@rpc_method 返回生成器,框架逐块多回复推送,网关以 text/event-stream 转发。curl -N 可观察逐块到达。" -auth_required = false -stream = true -# 流式超时模型: timeout = 流总寿命上限(zenoh query deadline), -# stream_idle_timeout = 网关侧连续无数据块的最大间隔 -timeout = 300.0 -stream_idle_timeout = 10.0 -params = [ - "prompt: str", - "tokens: int" -] diff --git a/workers/example/subtract.toml b/workers/example/subtract.toml deleted file mode 100644 index bb8c5aa..0000000 --- a/workers/example/subtract.toml +++ /dev/null @@ -1,11 +0,0 @@ -# subtract 接口 - -[GET] -summary = "Subtract two numbers" -docstring = "Subtract two numbers via GET query params (a - b)" -params = ["a: float", "b: float"] - -[GET.response_model] -result = { type = "float", required = true } -operation = { type = "str", default = "subtract" } -timestamp = { type = "float", required = false, default = 0.0 }