Plaita Console
Plaita 流程引擎可视化管理控制台
功能特性
- 服务拓扑视图 - 实时展示集群服务结构与关联关系
- 服务生命周期管理 - 启动/停止各类服务
- 执行实例管理 - 流程执行的查看、启动、停止
- 实时监控 - 执行状态、日志流、任务队列
- 可视化流程查看器 - 图形化展示流程执行进度
- 可视化 Flow 编排 - 浏览器内拖拽编排 Plaita 流程(节点面板 + 画布 + 配置抽屉 + 试跑),保存为带 semver 版本号的流程定义,支持草稿/发布版本管理
- 节点管理 - 查看内置节点 schema、注册/删除自定义节点描述
- 多租户 - 用户可属多个租户(成员制 + 会话内切换),流程/版本/执行/调度/凭据/自定义节点/审计按租户隔离;平台管理员跨租户管理与全量视角。本地单机档与集群档均支持(集群档经消息租户 + 键 namespace 隔离,见下方"多租户边界")
- 对外契约接口 - 暴露
/api/flowVersion/semver/detail(HMAC 鉴权),供plaita.PlaitaClient拉取已发布流程定义;支持按租户签发契约密钥(租户只能拉本租户流程),全局密钥仍兼容平台级拉取
多租户说明
- 模型:
tenants+tenant_members(用户↔租户多对多,租户内 admin/editor/viewer 角色);users.platform_admin为平台管理员(管理租户/成员,可带X-Tenant-ID头跨租户操作)。 - 会话:登录响应含
memberships与active_tenant;POST /api/auth/switch-tenant切换活跃租户;前端侧边栏提供租户切换器。成员变更即吊销该用户全部会话。 - 隔离:流程/版本/执行/调度/凭据/自定义节点/属性类型/Copilot 会话/审计/部署记录全部携带
tenant_id,查询按会话租户过滤,跨租户访问即 not-found。存量库首次多租户启动时自动迁移:建default租户、回填数据、legacy admin 提升为平台管理员。 - 租户内唯一:
flow_id、凭据名、自定义节点 type、属性类型名的唯一性均为租户内唯一(同名流程可共存于不同租户)。 - 契约密钥:每个租户一组
contract_secret_id/contract_secret_key(租户管理页创建/轮换,明文仅显示一次),只能拉取本租户已发布流程;全局PLAITA_CONSOLE_SECRET_ID/SECRET_KEY仍可用(平台上下文,可拉任意租户),存量集成不破坏。 - 多租户边界(如实说明):集群档的租户数据(流程定义、执行状态、resume 租约)按键 namespace 隔离(
plaita:{tenant}:*,default 租户保持历史前缀plaita:*以兼容存量数据),任务消息携带tenant_id(缺省视为 default),引擎日志/调度值/订阅内嵌租户字段供 console 过滤。仍保持平台级共享的:任务队列 Stream(机制通道,租户在消息内)、事件总线存储与 pubsub(跨租户事件总线,订阅按租户过滤)、服务注册/控制通道。本地档凭据按租户导出到旁文件(.plaita-credentials.<tenant>.json),default 租户沿用历史文件路径。 - 滚动升级兼容:消息缺
tenant_id按 default 处理;default 租户流量走历史键前缀——旧 worker + 新 console(或反向)混跑时 default 租户不受影响,非 default 租户需双侧升级。
快速开始
使用 Docker Compose
cd plaita-console/docker
docker-compose up -d
访问 http://localhost:5173 打开控制台。
本地单机档(无需 Redis)
不想装 Redis 时,后端可直接以本地单机模式跑起来(启动时 ping 不通 Redis 会自动降级,日志里会有明确提示):
cd plaita-console/backend
pip install -r requirements.txt
python run.py
流程定义、版本、执行历史、节点 trace 全部存 SQLite(默认 ./plaita_console.db,可用 PLAITA_CONSOLE_DB_URL 换库);流程在 console 进程内的后台线程执行。想强制本地档(即使本机有 Redis 也不连),把 Redis URL 指向一个不可达地址即可:
PLAITA_CONSOLE_REDIS_URL=redis://127.0.0.1:1/0 python run.py
本地档能力边界(与集群档的差异,如实说明):
- 可用:流程编排/发布、本地执行与节点级 trace、挂起-恢复(审批/事件节点,checkpoint 存 SQLite)、日志/执行页、内置调度循环(替代集群档的 schedule_service 进程)、HMAC 契约接口
/api/flowVersion/semver/detail。 - UI 入口:本地档只起后端 API;干净 clone 下
backend/webDist/不存在(gitignore),访问/不会有前端页面。要看控制台界面,另起前端开发服务(cd frontend && pnpm install && pnpm dev,访问 http://localhost:5173),或运行scripts/build_package.sh生成 webDist。 - 用 PlaitaClient 拉流程:需要
requests(pip install "plaita[http]"或pip install requests),缺依赖时 plaita 会给出可操作的安装指引。 - 不可用:集群/服务拓扑/服务启停、事件总线、任务队列视图——对应管理 API 返回 503。
- 限制:执行与恢复必须在同一个 console 进程内;进程重启后进程内事件订阅丢失,挂起的执行需显式 resume 继续;cancel 为尽力而为(只标记状态,不中断正在运行的线程);HMAC 重放保护退化为进程内 nonce 判定,仅单进程部署有效。
启动第三方依赖服务
Plaita Console 依赖 Redis 来存储服务注册信息。可以使用以下方式启动:
# 方式 1: 使用本地 Redis
redis-server
# 方式 2: 使用 Docker 仅启动依赖服务
cd plaita-console/docker
docker-compose -f docker-compose.deps.yml up -d
演示模式
如果你只是想测试 Plaita Console 的功能,可以运行演示脚本注册模拟服务:
# 确保 Redis 已启动,然后运行演示脚本
cd plaita-console
python scripts/demo_services.py
这会注册几个模拟服务(FlowWorker、DelayService 等),让你可以在控制台中看到服务拓扑和状态。
本地开发
后端
cd plaita-console/backend
# 安装依赖
pip install -r requirements.txt
# 方式 1: 使用启动脚本(推荐)
python run.py
# 方式 2: 使用 uvicorn
python -m uvicorn main:app --reload --port 8080
# 方式 3: 直接运行
python main.py
前端
cd plaita-console/frontend
# 安装依赖
pnpm install
# 启动开发服务器
pnpm dev
访问 http://localhost:5173 打开控制台。
项目结构
plaita-console/
├── frontend/ # 前端项目 (React + TypeScript + Vite)
│ ├── src/
│ │ ├── components/ # 可复用组件
│ │ ├── pages/ # 页面组件
│ │ ├── hooks/ # 自定义 Hooks
│ │ ├── services/ # API 调用
│ │ └── stores/ # 状态管理
│ ├── package.json
│ └── vite.config.ts
├── backend/ # 后端项目 (FastAPI)
│ ├── api/ # API 路由
│ ├── models/ # 数据模型
│ ├── services/ # 业务逻辑
│ └── main.py
├── docker/ # Docker 配置
│ ├── docker-compose.yml
│ ├── Dockerfile.frontend
│ └── Dockerfile.backend
└── README.md
API 文档
启动后端后,访问 http://localhost:8080/docs 查看 Swagger API 文档。
Swagger 按 tag 分面:admin(管理面)/ contract(契约面)/ health。
API 分面
Console 对外暴露两套鉴权面,路径前缀同为 /api,鉴权方式不同:
| 分面 | 调用方 | 鉴权 | 未配置密钥 |
|---|---|---|---|
| 管理面 (admin) | Console 前端 / 运维 | X-Admin-API-Key 或 Authorization: Bearer |
503(除非 ALLOW_INSECURE_ADMIN=true) |
| 契约面 (contract) | 外部 PlaitaClient |
HMAC(Authorization 头,与 plaita/client.py 对称) |
503 |
| 健康检查 | 探针 | 无 | — |
路由挂载见 backend/main.py:_mount_admin / _mount_contract。契约面不加 require_admin_auth。
管理面 API
| 端点 | 方法 | 描述 |
|---|---|---|
/api/services |
GET | 获取所有服务列表 |
/api/services/topology |
GET | 获取服务拓扑 |
/api/services/{id}/stop |
POST | 停止服务 |
/api/executions |
GET | 获取执行列表 |
/api/executions |
POST | 启动新执行 |
/api/executions/{id} |
DELETE | 取消执行 |
/api/queues |
GET | 获取队列状态 |
/api/logs |
GET | 获取日志 |
/api/logs/stream |
GET (SSE) | 实时日志流 |
/api/flows |
GET / POST | 流程列表 / 新建流程 |
/api/flows/{id} |
GET / DELETE | 流程详情(含版本列表)/ 删除流程 |
/api/flows/{id}/versions/{ver} |
GET / PUT / DELETE | 取版本 / 保存草稿(Flow 强校验)/ 删除版本 |
/api/flows/{id}/publish |
POST | 发布指定版本(draft → published) |
/api/flows/dry-run |
POST | 同步试跑 Flow JSON,返回节点级结果 |
/api/nodes |
GET / POST | 节点描述列表 / 注册自定义节点 |
/api/nodes/{type} |
DELETE | 删除自定义节点(内置不可删) |
/api/cluster/* |
— | 集群配置 / 启停(command 白名单) |
/api/events/* |
— | 事件订阅与查询 |
契约面 API
| 端点 | 方法 | 描述 |
|---|---|---|
/api/flowVersion/semver/detail |
POST | HMAC 鉴权;application/x-www-form-urlencoded(flowId/version);返回已发布流程定义供 PlaitaClient 拉取 |
技术栈
前端
- React 18
- TypeScript
- Vite
- TailwindCSS
- @xyflow/react 12 (流程编排画布与拓扑图)
- TanStack Query (数据获取)
- Zustand (状态管理)
后端
- FastAPI
- Pydantic
- Redis
- SQLAlchemy (流程定义/版本/节点描述持久化)
- SSE (Server-Sent Events)
环境变量
后端
| 变量名 | 默认值 | 描述 |
|---|---|---|
PLAITA_CONSOLE_REDIS_URL |
redis://localhost:6379/0 |
Redis 连接 URL |
PLAITA_CONSOLE_HOST |
0.0.0.0 |
监听地址 |
PLAITA_CONSOLE_PORT |
8080 |
监听端口 |
PLAITA_CONSOLE_DEBUG |
false |
调试模式 |
PLAITA_CONSOLE_DB_URL |
sqlite:///./plaita_console.db |
流程定义/版本/节点描述持久化(SQLAlchemy) |
PLAITA_CONSOLE_ADMIN_API_KEY |
空 | 管理面 API Key(X-Admin-API-Key / Bearer)。空且未放开 insecure 时管理 API 返回 503 |
PLAITA_CONSOLE_ALLOW_INSECURE_ADMIN |
false |
显式允许无管理密钥启动(仅本地开发) |
PLAITA_CONSOLE_SECRET_ID |
空 | 对外契约 HMAC secret-id(空则 /api/flowVersion 返回 503,不再接受空串签名) |
PLAITA_CONSOLE_SECRET_KEY |
空 | 对外契约 HMAC secret-key |
PLAITA_CONSOLE_LANGFUSE |
auto |
Langfuse 观测(plaita.obs):auto=配了 LANGFUSE_PUBLIC_KEY 即开;true 强制开;false 强制关。trace id = 执行实例 ID;缺 plaita[langfuse] 依赖自动降级为不观测(集群档对应 worker 的 --langfuse / PLAITA_WORKER_LANGFUSE=1)。另需 LANGFUSE_PROJECT_ID(如 proj-plaita-local)——执行详情页的「Langfuse」深链依赖它计算 trace URL |
前端管理面请求会自动带 X-Admin-API-Key:优先读 localStorage.plaita_admin_api_key,其次 VITE_PLAITA_ADMIN_API_KEY。
POST /api/flows/dry-run 拒绝含 code / python / javascript 等危险节点的流程,防止 console 进程 RCE。
开发指南
UI 旅程 e2e(语义化节点 id 可读性)
两个层次,覆盖同一旅程(画布语义名/desc、抽屉源码跳转、拖拽 + 保存 round-trip):
- argusai browser suite(CI 主路径,随
scripts/e2e-run.sh全量跑):tests/e2e/ui-semantic-ids.yaml——声明式 browser 步骤,单跑:scripts/e2e-run.sh ui-semantic-ids。数据播种经浏览器 evaluate + fetch (Bearer 取自 localStorage;ui-backend 容器不设 ALLOW_INSECURE_ADMIN)。 - 本地等价执行器(无需 Docker/mcp2cli/argusai-mcp):
BASE_URL=... ADMIN_PASSWORD=... python scripts/e2e-ui-semantic-ids-local.py——按同一份 YAML 逐 case 执行与断言,用于本机快速回归。
注意:console 前端 vite base: './'(dsht 子路径部署取舍),双层深链直刷会
白屏(如 /flows/<id>/edit)——两个 e2e 全程走客户端路由导航,不使用深链接刷新。
许可证
MIT
Metadata
Release files for plaita-console 0.6.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| plaita_console-0.6.1-py3-none-any.whl | Python 3 | none | any | Details |
Release files / plaita_console-0.6.1-py3-none-any.whl
| Download URL | plaita_console-0.6.1-py3-none-any.whl |
|---|---|
| Size | 5.7 MB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
d7999f23b19a17249700f9c7c8e093014468955ad6a5a373952946ca7136c4b2
|
|
BLAKE2b-256 checksum How to use checksums |
caae99fb6ef1bc9aa30a3b5b23101150c2a0594f574e0e8c2783121635e9839c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Security for plaita-console 0.6.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.