flowerui 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- flowerui-0.1.0/LICENSE +21 -0
- flowerui-0.1.0/MANIFEST.in +15 -0
- flowerui-0.1.0/PKG-INFO +391 -0
- flowerui-0.1.0/README.md +363 -0
- flowerui-0.1.0/flowerui/__init__.py +3 -0
- flowerui-0.1.0/flowerui/__main__.py +5 -0
- flowerui-0.1.0/flowerui/api/__init__.py +0 -0
- flowerui-0.1.0/flowerui/api/routers/__init__.py +0 -0
- flowerui-0.1.0/flowerui/api/routers/auth.py +48 -0
- flowerui-0.1.0/flowerui/api/routers/broker.py +33 -0
- flowerui-0.1.0/flowerui/api/routers/config.py +98 -0
- flowerui-0.1.0/flowerui/api/routers/control.py +96 -0
- flowerui-0.1.0/flowerui/api/routers/dashboard.py +106 -0
- flowerui-0.1.0/flowerui/api/routers/monitor.py +59 -0
- flowerui-0.1.0/flowerui/api/routers/system.py +55 -0
- flowerui-0.1.0/flowerui/api/routers/tasks.py +257 -0
- flowerui-0.1.0/flowerui/api/routers/themes.py +74 -0
- flowerui-0.1.0/flowerui/api/routers/workers.py +91 -0
- flowerui-0.1.0/flowerui/api/routers/ws.py +130 -0
- flowerui-0.1.0/flowerui/cli.py +479 -0
- flowerui-0.1.0/flowerui/config_bootstrap.py +285 -0
- flowerui-0.1.0/flowerui/core/__init__.py +0 -0
- flowerui-0.1.0/flowerui/core/celery_app.py +193 -0
- flowerui-0.1.0/flowerui/core/config.py +272 -0
- flowerui-0.1.0/flowerui/core/security.py +119 -0
- flowerui-0.1.0/flowerui/main.py +216 -0
- flowerui-0.1.0/flowerui/paths.py +142 -0
- flowerui-0.1.0/flowerui/relaunch.py +162 -0
- flowerui-0.1.0/flowerui/services/__init__.py +0 -0
- flowerui-0.1.0/flowerui/services/broker.py +248 -0
- flowerui-0.1.0/flowerui/services/deploy_env.py +117 -0
- flowerui-0.1.0/flowerui/services/events.py +161 -0
- flowerui-0.1.0/flowerui/services/hub.py +99 -0
- flowerui-0.1.0/flowerui/services/inspector.py +111 -0
- flowerui-0.1.0/flowerui/services/manager.py +833 -0
- flowerui-0.1.0/flowerui/services/metrics.py +60 -0
- flowerui-0.1.0/flowerui/services/mock.py +582 -0
- flowerui-0.1.0/flowerui/services/restart.py +349 -0
- flowerui-0.1.0/flowerui/services/runtime_config.py +916 -0
- flowerui-0.1.0/flowerui/services/search.py +112 -0
- flowerui-0.1.0/flowerui/services/state.py +170 -0
- flowerui-0.1.0/flowerui/services/task_filter.py +150 -0
- flowerui-0.1.0/flowerui/services/theme_manager.py +350 -0
- flowerui-0.1.0/flowerui/static/assets/ApplyTaskView-B9qObJT7.js +1 -0
- flowerui-0.1.0/flowerui/static/assets/ApplyTaskView-D2hDoD-R.css +1 -0
- flowerui-0.1.0/flowerui/static/assets/BrokerView-DIYIpZmB.js +1 -0
- flowerui-0.1.0/flowerui/static/assets/BrokerView-ZIKA8iL4.css +1 -0
- flowerui-0.1.0/flowerui/static/assets/ConfigView-B7YWjAcg.js +4 -0
- flowerui-0.1.0/flowerui/static/assets/ConfigView-D8CMQNiO.css +1 -0
- flowerui-0.1.0/flowerui/static/assets/DashboardView-Ca9ROpWV.css +1 -0
- flowerui-0.1.0/flowerui/static/assets/DashboardView-Dh-iAbii.js +1 -0
- flowerui-0.1.0/flowerui/static/assets/LoginView-svVGjwbS.js +1 -0
- flowerui-0.1.0/flowerui/static/assets/LoginView-u7BR9C_H.css +1 -0
- flowerui-0.1.0/flowerui/static/assets/MonitorView-BcSebSnT.js +1 -0
- flowerui-0.1.0/flowerui/static/assets/SystemView-C1w8703g.css +1 -0
- flowerui-0.1.0/flowerui/static/assets/SystemView-Dk3WUk0h.js +1 -0
- flowerui-0.1.0/flowerui/static/assets/TasksView-CYA-7fKx.css +1 -0
- flowerui-0.1.0/flowerui/static/assets/TasksView-DajUThXW.js +1 -0
- flowerui-0.1.0/flowerui/static/assets/WorkersView--kO8bM1W.css +1 -0
- flowerui-0.1.0/flowerui/static/assets/WorkersView-Dh54AopE.js +1 -0
- flowerui-0.1.0/flowerui/static/assets/charts-Bb6yjXMn.js +60 -0
- flowerui-0.1.0/flowerui/static/assets/el-form-item-D_relxjU.css +1 -0
- flowerui-0.1.0/flowerui/static/assets/el-radio-button-mUGqmzuy.css +1 -0
- flowerui-0.1.0/flowerui/static/assets/element-BD9JNeug.js +63 -0
- flowerui-0.1.0/flowerui/static/assets/index-CoWKp2nS.js +2 -0
- flowerui-0.1.0/flowerui/static/assets/index-DH_7c2-3.css +1 -0
- flowerui-0.1.0/flowerui/static/assets/useChart-2eo5HY7G.js +1 -0
- flowerui-0.1.0/flowerui/static/assets/vendor-CWAvDwR0.js +37 -0
- flowerui-0.1.0/flowerui/static/index.html +16 -0
- flowerui-0.1.0/flowerui/themes/_template.css +33 -0
- flowerui-0.1.0/flowerui/themes/amber-night.css +58 -0
- flowerui-0.1.0/flowerui/themes/aurora.css +91 -0
- flowerui-0.1.0/flowerui/themes/base.css +81 -0
- flowerui-0.1.0/flowerui/themes/charcoal-minimal.css +52 -0
- flowerui-0.1.0/flowerui/themes/cream-peach.css +41 -0
- flowerui-0.1.0/flowerui/themes/forest-fog.css +41 -0
- flowerui-0.1.0/flowerui/themes/gray-morandi.css +26 -0
- flowerui-0.1.0/flowerui/themes/lavender-light.css +22 -0
- flowerui-0.1.0/flowerui/themes/mint-breeze.css +23 -0
- flowerui-0.1.0/flowerui/themes/oat-milk.css +22 -0
- flowerui-0.1.0/flowerui/themes/salt-ocean.css +22 -0
- flowerui-0.1.0/flowerui/themes/silver-fog.css +41 -0
- flowerui-0.1.0/flowerui/themes/tech-liquid.css +101 -0
- flowerui-0.1.0/flowerui/themes/violet-space.css +63 -0
- flowerui-0.1.0/flowerui.egg-info/PKG-INFO +391 -0
- flowerui-0.1.0/flowerui.egg-info/SOURCES.txt +90 -0
- flowerui-0.1.0/flowerui.egg-info/dependency_links.txt +1 -0
- flowerui-0.1.0/flowerui.egg-info/entry_points.txt +5 -0
- flowerui-0.1.0/flowerui.egg-info/requires.txt +12 -0
- flowerui-0.1.0/flowerui.egg-info/top_level.txt +1 -0
- flowerui-0.1.0/pyproject.toml +97 -0
- flowerui-0.1.0/setup.cfg +4 -0
flowerui-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 FlowerUI contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
include LICENSE
|
|
2
|
+
include README.md
|
|
3
|
+
include pyproject.toml
|
|
4
|
+
recursive-include flowerui/static *
|
|
5
|
+
recursive-include flowerui/themes *.css
|
|
6
|
+
exclude flowerui.runtime.toml
|
|
7
|
+
exclude .pypirc
|
|
8
|
+
exclude flowerui.db
|
|
9
|
+
exclude flower.state*
|
|
10
|
+
prune logs
|
|
11
|
+
prune tests
|
|
12
|
+
global-exclude __pycache__/*
|
|
13
|
+
global-exclude *.py[cod]
|
|
14
|
+
global-exclude *.db
|
|
15
|
+
global-exclude *.log
|
flowerui-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,391 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: flowerui
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: 可嵌入现有 Celery 项目的 Web 监控面板(FastAPI + Vue,单端口托管)
|
|
5
|
+
Author: FlowerUI contributors
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/baobingbo/flower-fastapi
|
|
8
|
+
Project-URL: Repository, https://github.com/baobingbo/flower-fastapi
|
|
9
|
+
Project-URL: Issues, https://github.com/baobingbo/flower-fastapi/issues
|
|
10
|
+
Keywords: celery,flower,monitor,fastapi,dashboard
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Environment :: Web Environment
|
|
13
|
+
Classifier: Framework :: Celery
|
|
14
|
+
Classifier: Framework :: FastAPI
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
+
Classifier: Operating System :: OS Independent
|
|
17
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.7
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
24
|
+
Classifier: Topic :: System :: Monitoring
|
|
25
|
+
Requires-Python: >=3.7
|
|
26
|
+
Description-Content-Type: text/markdown
|
|
27
|
+
License-File: LICENSE
|
|
28
|
+
|
|
29
|
+
# FlowerUI 后端
|
|
30
|
+
|
|
31
|
+
> 基于 **FastAPI + Celery** 的实时任务 / 队列监控与管理服务([mher/flower](https://github.com/mher/flower) 2.0.1 的前后端分离重构版)。
|
|
32
|
+
>
|
|
33
|
+
> 本仓库即 FlowerUI 的后端服务(FastAPI + Celery)。前端为独立仓库 [`flowerui-template`](https://github.com/baobingbo/flowerui-template)。
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## 1. 概览
|
|
38
|
+
|
|
39
|
+
- **框架**:FastAPI + Uvicorn,单端口 **5555** 同时托管 API 与构建后的前端静态资源。
|
|
40
|
+
- **监控对象**:标准 Celery 集群(Worker / 任务 / Broker 队列),通过 Celery 事件总线实时采集。
|
|
41
|
+
- **传输层**:WebSocket 主动推送 + 定时轮询兜底,无需前端长轮询。
|
|
42
|
+
- **Broker 支持**:Redis 单机、**Redis 哨兵(Sentinel)高可用**(monitor 端与 worker 端需同时配置)。
|
|
43
|
+
- **零依赖演示**:`FLOWER_MOCK=true` 时启动内置模拟集群,无需任何 broker。
|
|
44
|
+
|
|
45
|
+
### 系统架构
|
|
46
|
+
|
|
47
|
+

|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## 2. 目录结构
|
|
52
|
+
|
|
53
|
+
```
|
|
54
|
+
flowerui/ # FlowerUI 后端 Python 包(import flowerui)
|
|
55
|
+
├── main.py # 应用装配、静态托管、生命周期(lifespan)
|
|
56
|
+
├── cli.py # 命令行入口(flowerui / celery flowerui 子命令)
|
|
57
|
+
├── __main__.py # python -m flowerui
|
|
58
|
+
├── config_bootstrap.py # 启动期单次级联配置解析
|
|
59
|
+
├── relaunch.py # 重启继任者进程
|
|
60
|
+
├── paths.py # 运行时数据目录解析
|
|
61
|
+
├── core/
|
|
62
|
+
│ ├── config.py # pydantic v1 BaseSettings + TOML 配置加载
|
|
63
|
+
│ ├── celery_app.py # Celery 实例与 broker 探测(哨兵感知)
|
|
64
|
+
│ └── security.py # Basic / JWT 鉴权
|
|
65
|
+
├── services/ # manager / state / events / inspector / broker / ...
|
|
66
|
+
├── api/routers/ # auth / workers / tasks / broker / dashboard / ...
|
|
67
|
+
├── static/ # 前端构建产物(随包分发,由 flowerui-template 构建)
|
|
68
|
+
└── themes/ # 内置主题 CSS(目录即真理,运行时播种到运行目录)
|
|
69
|
+
├── tests/ # 功能自测:functional_check / e2e_check / test_* 等
|
|
70
|
+
├── docs/ # SVG 图(架构 / 启动监控流程 / 配置)
|
|
71
|
+
├── examples/ # 示例 Celery 项目(demo_proj)
|
|
72
|
+
├── start_workers.py # Worker 批量启动 + 前台监控
|
|
73
|
+
├── send_tasks.py # 随机发送测试任务
|
|
74
|
+
├── _broker_env.py # 解析运行时配置(TOML 优先,兼容旧 .env)
|
|
75
|
+
├── register_celery_command.py # 注册 celery flowerui 子命令
|
|
76
|
+
├── celery_app.py # 示例 Celery 应用(-A 入口)
|
|
77
|
+
├── manage.sh # 服务管理(dev/run/demo/stop/status/workers/deps/...)
|
|
78
|
+
├── pyproject.toml # 依赖声明 + PyPI 打包配置
|
|
79
|
+
├── uv.lock # 版本锁定(随代码提交,uv sync 按此还原)
|
|
80
|
+
├── .python-version # 钉死 3.7
|
|
81
|
+
├── requirements.txt # 无 uv 环境 / Docker 的兼容入口
|
|
82
|
+
├── flowerui-settings.toml # 静态默认配置(可提交)
|
|
83
|
+
└── flowerui.runtime.toml # 运行时覆盖配置(界面改 → 落盘,自动生成,不入库)
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
> 注:`examples/`(示例 Celery 项目 `demo_proj`)位于仓库根目录;`start_workers.py` / `send_tasks.py` 通过 `_broker_env.py` 读取 `flowerui.runtime.toml` 自动配置 broker。
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## 3. 环境准备(uv)
|
|
91
|
+
|
|
92
|
+
后端虚拟环境位于 **`.venv`,Python 3.7.9**,由 uv 管理。
|
|
93
|
+
`.python-version` 已把解释器钉在 3.7,避免 `uv sync` 误挑更高版本重建环境。
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
cd . # 本仓库根目录
|
|
97
|
+
|
|
98
|
+
# 首次创建环境 / 重装(自动按 uv.lock 精确还原)
|
|
99
|
+
uv sync
|
|
100
|
+
|
|
101
|
+
# 升级全部依赖到 Python 3.7 下的最新兼容版本
|
|
102
|
+
uv sync --upgrade
|
|
103
|
+
|
|
104
|
+
# 只升级某一个包
|
|
105
|
+
uv sync --upgrade-package fastapi
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
> **约定:以后升级后端依赖统一用 `uv sync`**,不要再手动改版本号或 `pip install`。
|
|
109
|
+
> - 依赖声明源:`pyproject.toml`(不锁版本,只保留 `pydantic<2` 与 `importlib-metadata<5` 两个必要上界)
|
|
110
|
+
> - 版本锁定:`uv.lock`(必须随代码提交)
|
|
111
|
+
> - `requirements.txt` 仅作为**无 uv 环境 / Docker 构建**的兼容入口,不是权威来源
|
|
112
|
+
> - `.venv` 内的 Python 为 3.7.9;项目根目录的 `.venv` 是早期 Python 3.9 环境,勿用
|
|
113
|
+
|
|
114
|
+
### 为什么保留两个上界
|
|
115
|
+
|
|
116
|
+
| 约束 | 原因 |
|
|
117
|
+
|---|---|
|
|
118
|
+
| `pydantic<2` | `flowerui/core/config.py` 使用 v1 的 `BaseSettings`,v2 已移到 `pydantic-settings` |
|
|
119
|
+
| `importlib-metadata<5` | kombu 5.2.4 依赖 `entry_points().get()`,5.0+ 移除该接口,否则 `celery.events` 导入失败 |
|
|
120
|
+
|
|
121
|
+
Python 3.7 下 uv 解析出的主要版本:fastapi 0.103.2 / starlette 0.27.0 / uvicorn 0.22.0 /
|
|
122
|
+
pydantic 1.10.27 / celery 5.2.7 / kombu 5.2.4 / redis 5.0.8 / httpx 0.24.1 / toml 0.10.2。
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
## 4. 快速开始
|
|
127
|
+
|
|
128
|
+
### 方式一:演示模式(零依赖,推荐先跑)
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
# 后端专属脚本
|
|
132
|
+
./manage.sh demo
|
|
133
|
+
# 等价于:
|
|
134
|
+
FLOWER_MOCK=true .venv/Scripts/python.exe -m uvicorn flowerui.main:app --host 0.0.0.0 --port 5555
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
打开 <http://127.0.0.1:5555> 即可看到 4 个模拟 worker 与持续事件流,所有控制指令均可真实操作。
|
|
138
|
+
|
|
139
|
+
### 方式二:连接真实 Celery 集群
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
# 1) 启动 broker(Redis 单机或哨兵,见第 8 节)
|
|
143
|
+
# 2) 启动后端(生产模式,单端口托管前端静态资源)
|
|
144
|
+
./manage.sh run
|
|
145
|
+
# 3) 另开一个终端,前台启动并监控 worker(Ctrl+C 停止)
|
|
146
|
+
./manage.sh workers # 默认 4 个;可 ./manage.sh workers 8
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
> Worker 必须开启事件上报:`celery -A proj worker -E`。`start_workers.py` 已默认带 `-E`。
|
|
150
|
+
|
|
151
|
+
### 方式三:Celery 子命令启动(支持命令行参数)
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
# 一次性注册(幂等;uv sync 重建 venv 后需重新执行)
|
|
155
|
+
.venv/Scripts/python.exe register_celery_command.py
|
|
156
|
+
source .venv/Scripts/activate
|
|
157
|
+
|
|
158
|
+
# 启动(页面与 API 同一端口,默认 http://127.0.0.1:5555/)
|
|
159
|
+
celery -A celery_app flowerui
|
|
160
|
+
celery -A celery_app flowerui --port 5555 --mock
|
|
161
|
+
celery -A celery_app flowerui --broker-url redis://127.0.0.1:6379/0 --set debug=true
|
|
162
|
+
celery -A celery_app flowerui --port 6001 ui_transport=polling --dry-run
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
> **访问地址**:启动日志会打印 `页面地址`(把绑定用的 `0.0.0.0` 自动换成 `127.0.0.1`),
|
|
166
|
+
> 打开它即可;`--port` 改成 6001 就访问 `http://127.0.0.1:6001/`。
|
|
167
|
+
> `5556` 是 **Vite 前端开发端口**,只有 `./manage.sh dev` 才会在 5556 起服务;
|
|
168
|
+
> 单独用本方式启动时访问 5556 会得到空白 / 连接失败。前端静态资源由后端
|
|
169
|
+
> `flowerui/static/` 直接托管,无需另起前端进程。
|
|
170
|
+
|
|
171
|
+
`flowerui` 是通过 `celery.commands` entry point 注册的 click 命令,实现在 `flowerui/cli.py`;
|
|
172
|
+
`celery_app.py` 提供 `-A` 所需的 Celery 实例。注册脚本只改动当前 venv(写
|
|
173
|
+
`.dist-info` + `.pth`),不改 `pyproject.toml` / `uv.lock`,也不影响 `./manage.sh`。
|
|
174
|
+
|
|
175
|
+
> **发布形态**:本仓库即 PyPI 包 `flowerui` 的源码(`requires-python >=3.7`)。
|
|
176
|
+
> `uv build` 产出的 wheel 自带 `celery.commands` 与独立命令 `flowerui`
|
|
177
|
+
> 两个入口点,安装后**无需**执行上面的注册脚本。命令示例与当前限制见 PyPI 发布说明。
|
|
178
|
+
> 「方式六」及 `docs/pypi-release-plan.md`。
|
|
179
|
+
|
|
180
|
+
| 类别 | 参数 |
|
|
181
|
+
| --- | --- |
|
|
182
|
+
| 服务 | `--host` / `--address`、`--port` / `-p`、`--url-prefix`、`--log-level`、`--reload`、`--workers` |
|
|
183
|
+
| Celery | `--broker-url`、`--result-backend`、`--broker-transport-options`(JSON);全局 `-b/--broker` 亦生效 |
|
|
184
|
+
| 运行模式 | `--mock` / `--no-mock`、`--debug` / `--no-debug`、`--basic-auth`、`--basic-auth-enabled` |
|
|
185
|
+
| 配置 | `--runtime-config PATH` 指定运行时 TOML;`--set KEY=VALUE` 或位置参数 `KEY=VALUE` 覆盖任意配置项 |
|
|
186
|
+
| 调试 | `--list-keys` 列出全部配置键、`--dry-run` 只打印生效配置不启动 |
|
|
187
|
+
|
|
188
|
+
**优先级**:命令行 > `flowerui.runtime.toml` 回放 > `FLOWER_*` 环境变量 >
|
|
189
|
+
`flowerui-settings.toml` > 代码默认值。`runtime_config.set_cli_overrides()` 会登记
|
|
190
|
+
命令行键,`load()` 回放磁盘配置时跳过它们;覆盖项同时写入 `FLOWERUI_CLI_OVERRIDES`
|
|
191
|
+
环境变量,使 `--reload` / `--workers` 的子进程保持一致。命令行参数**不落盘**,重启后仍以 TOML 为准。
|
|
192
|
+
|
|
193
|
+
> 注意:Celery 全局选项(`-A`、`-b`、`--result-backend` 等)必须写在 `flowerui` 之前。
|
|
194
|
+
> Git Bash 下用注册脚本生成的 `celery` shim 绕开 uv 0.12.3 在 Windows + Python 3.7
|
|
195
|
+
> 下损坏的 `celery.exe`;PowerShell / CMD 请用 `.venv/Scripts/python.exe -m celery ...`。
|
|
196
|
+
|
|
197
|
+
---
|
|
198
|
+
|
|
199
|
+
## 5. 服务管理(`manage.sh`)
|
|
200
|
+
|
|
201
|
+
所有命令在本仓库根目录下执行(Git Bash / Linux / macOS 通用)。
|
|
202
|
+
|
|
203
|
+
| 命令 | 说明 |
|
|
204
|
+
| --- | --- |
|
|
205
|
+
| `./manage.sh dev` | 开发模式:停 + 起(`--reload` 默认关,可加 `--reload` 开热更新) |
|
|
206
|
+
| `./manage.sh dev --mock` | 开发模式 + 模拟数据 |
|
|
207
|
+
| `./manage.sh dev --clean` | 开发模式 + 启动前清理历史日志 |
|
|
208
|
+
| `./manage.sh restart` | 命令行重启(等价于 `dev`,先停后起);**界面「重启系统」不走本脚本**,由 `python -m flowerui.relaunch` 继任者进程接管 |
|
|
209
|
+
| `./manage.sh run` | 生产模式:**前台**运行,单端口托管前端静态资源 |
|
|
210
|
+
| `./manage.sh demo` | 演示模式:模拟集群,无需 broker |
|
|
211
|
+
| `./manage.sh stop` | 仅停止后端(精确定位端口 5555,不误杀 celery worker) |
|
|
212
|
+
| `./manage.sh status` | 环境摘要 + 端口存活 + `/api/system` 生效配置 |
|
|
213
|
+
| `./manage.sh clean` | 清理 `logs/` 下历史日志(仅删 `*.log`,保留 PID 文件) |
|
|
214
|
+
| `./manage.sh workers [N=4]` | **前台**启动并监控 N 个 worker(Ctrl+C 停止,详见第 6 节) |
|
|
215
|
+
| `./manage.sh deps` | 依赖还原 `uv sync`(按 `uv.lock`,**唯一入口**) |
|
|
216
|
+
| `./manage.sh deps --upgrade` / `./manage.sh upgrade` | 升级到 Python 3.7 下的最新兼容版 |
|
|
217
|
+
| `./manage.sh deps --upgrade-package <包名>` | 只升级单个包 |
|
|
218
|
+
| `./manage.sh deps --add <包名>` | 新增依赖(`uv add`,改 `pyproject.toml` + `uv.lock`) |
|
|
219
|
+
| `./manage.sh deps --check` | 只读体检:版本清单 + `pydantic<2` / `importlib-metadata<5` |
|
|
220
|
+
| `./manage.sh config` | 配置体检:TOML 可解析性 / 分节误用 / `FLOWER_*` 覆盖 / 生效值 |
|
|
221
|
+
| `./manage.sh help` | 显示帮助 |
|
|
222
|
+
|
|
223
|
+
> **后台行为说明**:`dev` / `restart` / `demo` 会将 uvicorn 以后台方式拉起(关终端不影响服务);`run` 为前台(`exec`)。`workers` 始终为前台监控模式——这是有意设计,便于你直接观察 worker 状态并在结束时用 Ctrl+C 一并收回。
|
|
224
|
+
>
|
|
225
|
+
> **说明**:本脚本即本仓库的服务入口,负责后端自身的启停与依赖管理;打包时按本仓库 `.gitignore` 排除 `.venv` 等运行时产物。
|
|
226
|
+
>
|
|
227
|
+
> **日志位置**:所有运行时日志与 PID 文件统一放在后端自己的 `logs/` 下——`logs/`(uvicorn 标准输出 / 错误 + `_backend.pid`)、`logs/workers/`(各 worker 日志与 PID)。`clean` 仅删除 `*.log`,PID 文件保留以便 `stop` 精确杀进程。
|
|
228
|
+
|
|
229
|
+
---
|
|
230
|
+
|
|
231
|
+
## 6. Worker 管理(`start_workers.py`)
|
|
232
|
+
|
|
233
|
+
纯 Python、跨 Windows / Linux,**不依赖 `nohup`**。每个 worker 都是脚本的子进程,共享同一终端(不弹新窗口):
|
|
234
|
+
|
|
235
|
+
```bash
|
|
236
|
+
# 前台启动 4 个 worker 并持续监控(Ctrl+C 停止并带走全部 worker)
|
|
237
|
+
python start_workers.py start
|
|
238
|
+
python start_workers.py start 8 --no-restart --interval 2
|
|
239
|
+
|
|
240
|
+
# 其它操作(非监控场景)
|
|
241
|
+
python start_workers.py status # 查看运行状态
|
|
242
|
+
python start_workers.py logs 1 -f # 跟踪第 1 个 worker 日志
|
|
243
|
+
python start_workers.py stop # 从另一个终端停止(通知监控脚本退出)
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
### 启动与监控流程
|
|
247
|
+
|
|
248
|
+

|
|
249
|
+
|
|
250
|
+
行为要点:
|
|
251
|
+
|
|
252
|
+
- **多进程、同终端**:worker 作为脚本子进程启动,不弹新窗口;Windows 用 `DETACHED_PROCESS` 之外的独立进程组,控制台 Ctrl+C 由脚本统一接管。
|
|
253
|
+
- **崩溃自愈**:worker 异常退出自动重启(单个最多 5 次),超限后放弃并提示查日志。
|
|
254
|
+
- **日志落盘**:每个 worker 的日志写入 `logs/workers/_worker_{N}.log`,可用 `python start_workers.py logs N [-f]` 查看 / 跟踪;PID 文件同目录。
|
|
255
|
+
- **优雅停机**:Ctrl+C / `SIGTERM` → 先通过 broker 控制通道广播 `celery control shutdown`(warm shutdown,跑完当前任务再退出)→ 超时兜底信号 / 强杀 → 清理 PID 文件,**无残留**。
|
|
256
|
+
- **broker 自动跟随**:从 `flowerui.runtime.toml` 读取 `broker_url` / `broker_transport_options` / `result_backend`,后端切哨兵 / 单机后 worker 无需改配置。
|
|
257
|
+
|
|
258
|
+
### 与 `manage.sh workers` 的关系
|
|
259
|
+
|
|
260
|
+
`./manage.sh workers [N]` 等同于 `exec python start_workers.py start [N]`——只做前台透传,不再有 `start/stop/status/restart/logs` 子命令(那些直接用 `start_workers.py` 即可)。
|
|
261
|
+
|
|
262
|
+
---
|
|
263
|
+
|
|
264
|
+
## 7. 随机发任务(`send_tasks.py`)
|
|
265
|
+
|
|
266
|
+
用于快速制造任务流量,验证仪表盘与 worker 消费:
|
|
267
|
+
|
|
268
|
+
```bash
|
|
269
|
+
python send_tasks.py --count 10 # 随机发 10 个任务(经后端 API)
|
|
270
|
+
python send_tasks.py --count 50 --poll # 发完轮询直到全部完成
|
|
271
|
+
python send_tasks.py --seed 42 # 固定随机种子,复现特定任务组合
|
|
272
|
+
python send_tasks.py --list # 仅列出可用任务类型
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
---
|
|
276
|
+
|
|
277
|
+
## 8. 配置
|
|
278
|
+
|
|
279
|
+
### 8.1 配置文件(TOML)与环境变量
|
|
280
|
+
|
|
281
|
+
静态默认配置见同目录 [`flowerui-settings.toml`](flowerui-settings.toml)(**扁平** `KEY = VALUE`,
|
|
282
|
+
不要分节:分节写法会被 `extra="ignore"` 静默丢弃,且 TOML 没有 `null`)。
|
|
283
|
+
界面改动落盘到 `flowerui.runtime.toml`,重启生效。优先级:
|
|
284
|
+
**TOML 文件 → `FLOWER_*` 环境变量 → 代码默认值**。
|
|
285
|
+
|
|
286
|
+
用 `./manage.sh config` 可体检两个 TOML 是否可解析、有无分节误用、`result_backend`
|
|
287
|
+
是否被误写成空串,以及当前环境变量覆盖;服务运行时用 `./manage.sh status` 看真正生效值。
|
|
288
|
+
完整字段清单见 `flowerui-settings.toml` 与界面「配置」页。
|
|
289
|
+
|
|
290
|
+
常用环境变量:
|
|
291
|
+
|
|
292
|
+
| 变量 | 默认值 | 说明 |
|
|
293
|
+
| --- | --- | --- |
|
|
294
|
+
| `FLOWER_BROKER_URL` | `redis://127.0.0.1:6379/0` | 支持 `redis://` / `rediss://` / `sentinel://` |
|
|
295
|
+
| `FLOWER_BROKER_TRANSPORT_OPTIONS` | `{}` | **哨兵必填** `master_name` |
|
|
296
|
+
| `FLOWER_RESULT_BACKEND` | 空 | 任务结果查询 |
|
|
297
|
+
| `FLOWER_MAX_TASKS` | `100000` | 内存保留任务上限 |
|
|
298
|
+
| `FLOWER_INSPECT_TIMEOUT` | `3000` | Inspect 超时(毫秒) |
|
|
299
|
+
| `FLOWER_BASIC_AUTH` | 空 | `["user:pass"]`,留空不鉴权 |
|
|
300
|
+
| `FLOWER_SECRET_KEY` | 随机 | JWT 签名,生产必改 |
|
|
301
|
+
| `FLOWER_MOCK` | `false` | 强制演示模式 |
|
|
302
|
+
|
|
303
|
+
### 8.2 运行时配置
|
|
304
|
+
|
|
305
|
+
界面修改的配置自动落盘到 `flowerui.runtime.toml`(TOML 格式),**重启后端生效**。后端启动后可在 `/api/config/ui` 查看默认值。
|
|
306
|
+
|
|
307
|
+
- `result_backend` **非必须**:不提供结果查询时保持注释状态即可,生成模板只写注释行。写成
|
|
308
|
+
`result_backend = ""` 会让 Celery 认为「已配置但为空」并抛 `NotImplementedError: No result backend is configured`。
|
|
309
|
+
- 运行时文件按**当前工作目录**解析,所以 `manage.sh` 在本仓库根目录启动后端;从其它目录
|
|
310
|
+
直接 `python -m uvicorn ... --app-dir backend` 启动会读不到界面保存的配置。
|
|
311
|
+
- 恢复出厂配置:`POST /api/config/materialize`,或删除 `flowerui.runtime.toml` 后重启。
|
|
312
|
+
|
|
313
|
+
### 8.3 Redis 哨兵 vs 单机
|
|
314
|
+
|
|
315
|
+

|
|
316
|
+
|
|
317
|
+
**哨兵模式**(monitor 端与 worker 端都需配置):
|
|
318
|
+
|
|
319
|
+
> 下列地址、端口、密码与 `master_name` **均为示例占位**,请按实际环境替换;切勿把真实连接信息写进文档或提交到仓库。
|
|
320
|
+
|
|
321
|
+
```toml
|
|
322
|
+
# flowerui.runtime.toml(TOML 键名无 FLOWER_ 前缀)
|
|
323
|
+
broker_url = "sentinel://:YOUR_PASSWORD@sentinel1.example.com:26379;sentinel://sentinel2.example.com:26379;sentinel://sentinel3.example.com:26379/0"
|
|
324
|
+
broker_transport_options = { "master_name" = "mymaster" }
|
|
325
|
+
result_backend = "sentinel://sentinel1.example.com:26379;sentinel://sentinel2.example.com:26379;sentinel://sentinel3.example.com:26379/1"
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
- 多个哨兵节点用 `;` 分隔,每个都要带 `sentinel://` scheme;db 写在任意一段路径上(如 `/0`)。
|
|
329
|
+
- `master_name` 缺失时启动会**显式报错**,拒绝静默降级到演示模式。
|
|
330
|
+
|
|
331
|
+
**Worker 端**(示例见 `examples/demo_proj`,已内置同样的读取逻辑):
|
|
332
|
+
|
|
333
|
+
```bash
|
|
334
|
+
FLOWER_BROKER_URL='sentinel://:YOUR_PASSWORD@127.0.0.1:26379;sentinel://127.0.0.1:26380;sentinel://127.0.0.1:26381/0' \
|
|
335
|
+
FLOWER_RESULT_BACKEND='sentinel://:YOUR_PASSWORD@127.0.0.1:26379;sentinel://127.0.0.1:26380;sentinel://127.0.0.1:26381/1' \
|
|
336
|
+
FLOWER_BROKER_TRANSPORT_OPTIONS='{"master_name": "mymaster"}' \
|
|
337
|
+
python start_workers.py start 4
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
**切回单机**:把 `FLOWER_BROKER_URL` 改回 `redis://:YOUR_PASSWORD@127.0.0.1:6379/0`、删掉 `FLOWER_BROKER_TRANSPORT_OPTIONS` 即可,两种模式可在 `flowerui.runtime.toml` 中随时切换(重启生效)。
|
|
341
|
+
|
|
342
|
+
---
|
|
343
|
+
|
|
344
|
+
## 9. API 参考
|
|
345
|
+
|
|
346
|
+
启动后访问 <http://127.0.0.1:5555/docs> 查看交互式 Swagger 文档(ReDoc 见 `/redoc`)。
|
|
347
|
+
|
|
348
|
+
**查询**:`/api/workers`、`/api/workers/table`、`/api/worker/{name}`、`/api/tasks`、`/api/tasks/table`、`/api/task/info/{id}`、`/api/task/types`、`/api/task/registered`、`/api/queues/length`、`/api/broker`、`/api/dashboard/summary|timeline|filters|task-distribution`、`/api/system`、`/api/config`、`/api/config/ui`、`/api/themes`。
|
|
349
|
+
|
|
350
|
+
**控制**:`/api/worker/shutdown/{name}`、`/api/worker/pool/restart|grow|shrink|autoscale/{name}`、`/api/worker/queue/add-consumer|cancel-consumer/{name}`、`/api/task/revoke/{id}`、`/api/task/abort/{id}`、`/api/task/rate-limit|timeout/{taskname}`、`/api/task/apply|async-apply|send-task/{taskname}`、`/api/task/result/{id}`。
|
|
351
|
+
|
|
352
|
+
**配置 / 运维**:`PUT /api/config`、`POST /api/config/reset|materialize`、`POST /api/system/restart`、`GET /metrics`、`GET /healthcheck`、`WS /ws/events`。
|
|
353
|
+
|
|
354
|
+
---
|
|
355
|
+
|
|
356
|
+
## 10. 测试
|
|
357
|
+
|
|
358
|
+
```bash
|
|
359
|
+
# 1) 启动服务(演示模式零依赖)
|
|
360
|
+
./manage.sh demo
|
|
361
|
+
# 2) 另开终端运行端到端自测
|
|
362
|
+
.venv/Scripts/python.exe tests/functional_check.py http://127.0.0.1:5555
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
覆盖:系统 / 认证、仪表盘、Worker 列表与详情、任务下发与查询、任务控制(revoke / terminate / rate-limit / timeout)、Worker 池与队列控制、Broker / 队列长度、运行时配置、主题、系统重启接口。全部通过即代表核心链路健康。
|
|
366
|
+
|
|
367
|
+
> 已知约定:认证未启用时 `/api/auth/login` 对任意凭据返回 200(匿名 token),测试将其标记为预期失败属正常;`POST /api/system/restart` 需默认端口 5555 上运行才能验证服务恢复。
|
|
368
|
+
|
|
369
|
+
---
|
|
370
|
+
|
|
371
|
+
## 11. 故障排查
|
|
372
|
+
|
|
373
|
+
| 现象 | 原因 / 处理 |
|
|
374
|
+
| --- | --- |
|
|
375
|
+
| 启动即降级为演示模式 | broker 不可达,或哨兵模式缺 `master_name`。查日志确认报错;`master_name` 缺失会显式拒绝降级 |
|
|
376
|
+
| `NOAUTH Authentication required` | broker 密码不正确或未从 `flowerui.runtime.toml` 读取。两端(后端 / worker)密码需一致 |
|
|
377
|
+
| worker 频繁 `code=1` 且日志无明显报错 | 同名 `workerN@flowerui` 被另一 supervisor 踢掉——**不要在同一 broker 上重叠启动两个 `start_workers.py`**,停掉其一再起 |
|
|
378
|
+
| `./manage.sh workers` 启动后终端被占用 | 这是前台监控的预期行为;结束按 `Ctrl+C` 即可优雅收回全部 worker |
|
|
379
|
+
| Windows 下 `taskkill` 报“无效的参数” | 曾被 MSYS 路径转换坑过;脚本已全局 `MSYS_NO_PATHCONV=1`,无需手动处理 |
|
|
380
|
+
| 任务列表搜索无结果 | 检查搜索 DSL:`result:success`、`state:FAILURE`、`args:user_id`,多条件空格取交集 |
|
|
381
|
+
| 页面白屏 / `ERR_ADDRESS_INVALID` | 打开的是启动日志里的 `0.0.0.0`;它是网卡绑定值,请用启动日志 `页面地址` 行的 **<http://127.0.0.1:5555/>**(`--port` 改了就换端口) |
|
|
382
|
+
| 访问 5556 白屏 | 5556 是 Vite 开发端口,只有 `./manage.sh dev` 才启动;本方式由后端单端口托管前端,访问 5555 |
|
|
383
|
+
| 界面在但 Worker / 任务全 0 | 真实 broker 尚无 Worker 与任务时的正常空数据;加 `--mock` 或改用 `./manage.sh demo` |
|
|
384
|
+
| 只返回 `前端未构建` 的 JSON | `flowerui/static/index.html` 缺失;前端构建产物已随 `flowerui/static/` 分发(如需更新见 `flowerui-template` 仓库构建后同步至此) |
|
|
385
|
+
| 仍白屏但接口都 200 | `Ctrl+F5` / 无痕窗口排除浏览器缓存;再看 F12 Console,服务端用 `curl -I http://127.0.0.1:5555/` 确认 |
|
|
386
|
+
|
|
387
|
+
---
|
|
388
|
+
|
|
389
|
+
## 12. 许可证
|
|
390
|
+
|
|
391
|
+
MIT License
|