Metadata-Version: 2.5
Name: chongming-gateway
Version: 0.1.1
Summary: chongming 网关：FastAPI + Zenoh 的配置驱动微服务网关（插件路由动态挂载、Worker 服务发现与负载均衡）
Requires-Python: >=3.12
Requires-Dist: amqtt
Requires-Dist: chongming-auth
Requires-Dist: chongming-cache
Requires-Dist: chongming-config
Requires-Dist: chongming-jwt
Requires-Dist: chongming-license
Requires-Dist: chongming-worker
Requires-Dist: eclipse-zenoh
Requires-Dist: fastapi
Requires-Dist: granian[reload,uvloop]
Requires-Dist: greenlet
Requires-Dist: gunicorn
Requires-Dist: httptools
Requires-Dist: orjson
Requires-Dist: pwdlib
Requires-Dist: pydantic
Requires-Dist: python-multipart
Requires-Dist: sqlite-vfs
Requires-Dist: starlette
Requires-Dist: uvicorn
Requires-Dist: uvloop
Description-Content-Type: text/markdown

# chongming-gateway

chongming 网关本体：基于 **FastAPI + Zenoh** 的配置驱动微服务网关。

把宿主项目里的插件（inline 进程内 / external 独立进程）发布的路由统一挂载为 HTTP 端点，
并提供 Worker 服务发现、负载均衡、超时重试、实例定向、MQTT Bridge、内置登录鉴权
与机器码授权（chongming-license）。

网关只提供**代码**：配置、插件与打包骨架由宿主项目提供（见「运行时约定」）。

---

## 安装

```bash
# 作为依赖（宿主项目，从私有源安装）
uv add chongming-gateway

# 开发期可编辑安装（在 chongming-core 仓库内）
uv pip install -e utils/gateway
```

网关自带完整依赖清单（`fastapi` / `granian` / `zenoh` / `chongming-worker` 等），
宿主项目无需重复声明；需要哪些第三方包，见本包 `pyproject.toml`。

## 快速开始

宿主项目（cwd）下准备 `config.toml` 与 `config/workers/<type>/config.toml`，
并保证插件包（`plugins.<type>`）可导入。之后任选一种启动方式：

```bash
# 按 config.toml [<env>.server] 启动（三个入口等价，仅默认服务器不同）
uv run serve            # uvicorn
uv run granian          # granian
uv run gunicorn         # gunicorn + uvicorn worker

# 或把 ASGI 应用交给任意服务器
uvicorn chongming.app:app --host 0.0.0.0 --port 8000
```

网关按 `config/workers/<name>/config.toml` 的 `[workers]` 节逐插件读取加载方式
（`load_mode = "inline" | "external"`）与副本数，启动时自动发现并挂载路由。

## 运行时约定

- **配置**：cwd 下 `config.toml`（环境、服务器、安全、MQTT、缓存、授权等）与
  `config/workers/**`（插件注册与路由定义），运行期读取，随宿主项目部署。
- **插件**：网关按 `plugins.<type>` 约定导入插件包，来源不限——`.mbank` 模块银行、
  源码目录（开发态 `src/plugins`）或已安装包均可。
- **工作目录**：日志、上传、数据等相对路径均以 cwd 为基准。

## 机器码授权（chongming-license）

厂商用**私钥**离线签发 `license.lic`（绑定机器指纹 + 插件白名单 + 有效期），
网关内置**公钥**验签，全程无需联网。未授权的插件不加载、不注册路由
（external 插件经 Zenoh 推来的描述符同样被忽略）、管理接口一律 403。
是否启用校验见下方「打包」一节：非授权版产物完全不校验，授权版产物强制校验。

宿主 `config.toml` 的 `[license]` 段（缺省视为未配置，不启用校验）：

```toml
[license]
# 是否执行拒绝。**只在非打包态生效**（uv run serve / 测试）——打包产物的
# 开关由构建期烘焙决定（部署目录的 config.toml 明文可写，以它为准等于放行
# 现场改一行就绕过授权）
enabled = false
path = "license.lic"                # 授权文件路径（相对网关工作目录）
public_key = ""                     # 厂商公钥（base64 裸 32 字节或 PEM）；由构建脚本注入，
                                    # 授权版还会把公钥烘焙进产物代码，此处仅作镜像/兜底
min_match = 3                       # 指纹命中阈值（N-of-M），容忍单块网卡/eMMC 更换
```

非打包态也可用 `CHONGMING_LICENSE_MODE=on`（或 `off`）临时开启/关闭，
便于在开发机上验证门禁逻辑。

### 打包：license 是可选构建项

"是否强制校验"由**构建期烘焙**决定，而不是运行时可写的配置 —— 打包脚本在编译前
生成 `chongming/_build_flags.py`（随代码编译进产物，部署侧不可改）：

| 构建方式 | 产物 | 行为 |
| --- | --- | --- |
| 不加 `--license` | 非授权版 | 不校验授权，插件照常加载（与开发态一致） |
| `--license` + 厂商公钥 | 授权版 | 强制校验；公钥随代码内置，现场换 `config.toml` 里的公钥也无法自签绕过 |
| 旧打包脚本（未烘焙） | 兼容旧语义 | 打包即强制校验 |

即**不配 license 也能正常出包**（非授权版不是"拒绝所有插件"的砖头包），
授权版则无法被现场改配置/环境变量关掉。宿主打包命令：

```bash
uv run build --encrypt --license      # 授权版产物（读 CHONGMING_LICENSE_PUBKEY / license_public.key）
uv run build --encrypt                # 非授权版产物：不校验、插件照常加载
```

烘焙标记只对打包产物生效——源码运行（含可编辑安装）仍只由上面的配置/环境变量
决定，不会因为上次打了授权版包就把开发态也锁上。

授权管理端点（`/api/v1/license/...`，仅超级管理员）：

| 端点 | 用途 |
| --- | --- |
| `GET /license/info` | 机器码、申请码、授权状态、各插件授权情况与硬件来源明细 |
| `POST /license/reload` | 重新读取磁盘上的授权文件（不改插件加载状态） |
| `POST /license/file` | 导入 `license.lic`：先验签/机器码/有效期，通过才原子替换 |

导入接口**先校验后落盘**：坏文件一律拒绝且不覆盖现有可用授权；通过校验但
白名单含此前未授权的插件时，需**重启网关**才会加载（响应里的 `restart_required`
如实告知）。申请授权时把 `/license/info` 的 `request_code` 发给厂商即可。

## 目录结构

```text
src/chongming/
├── __init__.py        # 启动入口（serve / granian / gunicorn）与服务器参数转换
└── app/
    ├── __init__.py    # FastAPI 应用装配（lifespan、中间件、异常处理）
    ├── core/          # WorkerManager / RouteGenerator / MQTT Bridge / 日志 / 鉴权 / 授权门禁
    └── routes/        # 内置管理端点（stats / worker_admin / auth / license）

test/
└── test_license_gate.py   # 授权门禁测试（自造夹具，直接 python 运行）
```

## 开发与发布

```bash
# 在 chongming-core 仓库内改代码后，让 venv 用本地源码（联调用）
uv pip install -e utils/gateway

# 授权门禁测试（自造夹具，可在任意目录直接运行）
python test/test_license_gate.py

# 发版：构建 wheel 并推私有源
uv build                                    # dist/chongming_gateway-<version>-py3-none-any.whl
uv run twine upload --repository <私有源> dist/*
```

发版后依赖方执行 `uv lock --upgrade-package chongming-gateway` 刷新版本 pin。
注意 `uv sync` 会用锁文件版本替换可编辑安装——打包/发版前先确认 venv 指向目标版本。

## 相关文档

- [项目主 README](../../README.md)：整体架构、使用与构建部署
- [Worker 管理与多实例运维](../../docs/worker-management.md)：管理端点、扩缩容、实例定向
- [机器码授权指南](../../docs/license.md)：密钥管理、签发/激活流程、指纹容错与命令行参考
