Data Formulator 与 Apache Superset 集成:本地测试环境搭建与插件联通指南
【免费下载链接】data-formulator🪄 Data Formulator is an interactive AI-powered data analysis system makes it easy to connect, explore and visualize data.项目地址: https://gitcode.com/GitHub_Trending/da/data-formulator
本文基于仓库
tests/database-dockers/superset/下的整套测试基建,完整讲解如何用一条命令在本机拉起一个带示例数据与预置仪表盘过滤器的 Apache Superset 实例,并将其接入 Data Formulator 的 Superset 数据插件。读完你将掌握:启动/停止脚本的四种用法、测试数据与 "DF Filter Test" 仪表盘的构造原理、预定义过滤器与令牌免密登录(SSO Bridge)两条端到端测试路径,以及不依赖脚本的手动部署方式与故障排查清单。
一、这套测试环境解决什么问题
Data Formulator 的 SupersetLoader 将 Apache Superset 视为一个分层数据源(dashboard → dataset),允许用户在 DF 中直接浏览仪表盘、加载数据集并应用预定义过滤器。而tests/database-dockers/superset/目录下的脚本与配置,正是为验证这一插件而准备的最小可复现测试环境:
- 启动一个官方
apache/superset容器(测试固定使用 4.1.1 镜像),自动完成数据库迁移、管理员创建、示例数据与自定义数据加载; - 通过
PLG_SUPERSET_URL环境变量让 DF 后端感知 Superset 地址并启用插件卡片; - 额外注入一个
/df-sso-bridge/端点(见 superset_config.py),用于测试"用户在 Superset 侧登录、DF 免密获取 JWT"的委托登录流程。
整套环境可以用一个脚本控制,无需手工敲docker compose与迁移命令。
二、快速开始:start.sh 的四种用法
核心入口是 start.sh。首次运行需要下载镜像并执行迁移,Superset 完整就绪约需2 分钟。
# 同时启动 Superset 与 DF 后端(首次运行 Superset 约需 2 分钟) ./tests/superset/start.sh # 或者分开启动: ./tests/superset/start.sh superset # 只启动 Superset ./tests/superset/start.sh df # 只启动 DF(假设 Superset 已在运行) # 查看状态 ./tests/superset/start.sh status # 停止并拆除 Superset 容器 ./tests/superset/start.sh stop脚本内部的执行逻辑(对应 start.sh 源码):
stop模式:执行docker compose -f "$COMPOSE_FILE" down拆除容器;- 加载环境变量:依次读取
tests/database-dockers/superset/.env.superset与仓库根目录.env(若存在),并设置默认值export PLG_SUPERSET_URL="${PLG_SUPERSET_URL:-http://localhost:8088}"; - 启动 Superset:若容器
df-test-superset未在运行,先docker rm -f清理同名残留容器避免端口/名称冲突,再docker compose -f ... up -d --force-recreate,随后以curl -sf http://localhost:8088/health轮询等待就绪; - 启动 DF 后端:优先用
uv run data_formulator --port 5567 --dev,无 uv 时回退到python -m data_formulator --port 5567 --dev。
提示:前端 Vite 开发服务器(默认 http://localhost:5173)需要另开终端自行
npx vite启动,脚本只负责后端与容器。
三、启动后你得到了什么
启动完成后,两大服务与凭据如下(摘自 README 的组件清单):
| 组件 | 地址 | 凭据 |
|---|---|---|
| Apache Superset | http://localhost:8088 | admin/admin |
| Data Formulator | http://localhost:5567 | — |
3.1 三个自定义示例数据集
init 流程 中的python /tmp/sample_data.py会在 Superset 的examplesSQLite 数据库中创建三张表(实现见 sample_data.py):
| 表名 | 行数 | 描述 |
|---|---|---|
df_test_sales | 100 | 含日期、区域、产品、数量、价格的销售数据 |
df_test_employees | 30 | 含部门、入职日期、薪资的员工目录 |
df_test_weather | 365 | 3 个城市的每日天气读数 |
如果superset load_examples --force成功,还会附带 Superset 内置的官方示例数据集。
3.2 预置测试仪表盘 "DF Filter Test"
容器启动时会自动创建一个 slug 为df-filter-test、名为DF Filter Test的仪表盘,并在其上配置了面向示例数据的原生过滤器(native filters),用于端到端验证插件中的预定义过滤器功能:
| 过滤器 | 类型 | 数据集 | 列 | 多选 | 默认值 |
|---|---|---|---|---|---|
| Region | filter_select | df_test_sales | region | 是 | North, South |
| Product | filter_select | df_test_sales | product | 否 | Widget A |
| Sale Date | filter_time | df_test_sales | date | — | 最近一季度 |
| Quantity Range | filter_range | df_test_sales | quantity | — | [5, 30] |
| Department | filter_select | df_test_employees | department | 是 | Engineering |
从源码实现看,sample_data.py采用了"纯 sqlite3 直写"的思路,不依赖任何 Superset 导入:create_tables()直接向/app/superset_home/examples.db写入表结构与random.Random(42)固定的伪随机数据(保证可复现);而add_native_filters_to_sales_dashboard()则直接修改/app/superset_home/superset.db中仪表盘记录的json_metadata,注入native_filter_configuration数组(每个元素含filterType、targets、controlValues、defaultDataMask等字段)。这解释了 README 中表格里filter_select/filter_time/filter_range三种过滤器类型的来源。
四、深入:容器初始化流程拆解
与直觉相反,init-superset.sh并不是真正的入口——它只是被挂载进容器留作参考的占位脚本。真正的初始化序列定义在 docker-compose.yml 的entrypoint/command中:
entrypoint: ["/bin/bash", "-c"] command: - | superset db upgrade # 1. 数据库迁移 superset fab create-admin \ # 2. 创建 admin 用户 --username admin --firstname Admin --lastname User \ --email admin@example.com --password admin || true superset init # 3. 初始化角色/权限 superset load_examples --force || echo "Examples load failed (non-fatal)" # 4. 内置示例 python /tmp/sample_data.py || echo "Custom sample data load failed (non-fatal)" # 5. 自定义数据 superset run -h 0.0.0.0 -p 8088 --with-threads --reload # 6. 启动服务其中第 5 步加载的是挂载进容器的./sample_data.py:/tmp/sample_data.py。容器还挂载了:
./init-superset.sh:/docker-entrypoint-initdb.d/init-superset.sh:ro(参考用);./superset_config.py:/app/pythonpath/superset_config.py:ro(关键,承载 SSO Bridge)。
健康检查healthcheck以curl -f http://localhost:8088/health为判据,start_period: 120s给足首次迁移时间。环境变量方面值得注意几点:
SUPERSET_SECRET_KEY已配置(测试用密钥);TALISMAN_ENABLED: "False"关闭安全头,允许弹窗嵌入;SUPERSET_CORS_ENABLED: "true"且SUPERSET_CORS_ORIGINS显式放行localhost:5567 / 127.0.0.1:5567 / localhost:5173 / 127.0.0.1:5173四个来源(DF 后端与 Vite 开发服务器);PUBLIC_ROLE_LIKE: "Gamma"允许访客以 Gamma 角色浏览数据(Gamma 是只读数据集访问的最低权限角色)。
五、测试插件连通:从 DF 加载 Superset 数据集
按 README 的操作路径,连接插件的完整步骤如下:
- 启动两个服务:
./tests/superset/start.sh - 浏览器打开 http://localhost:5567
- 点击Add Data(上传按钮)
- 在Connect to Live Data下应能看到Apache Superset卡片
- 点击卡片,用
admin/admin登录 - 浏览数据集并加载一个到 Data Formulator
这套流程背后的插件实现:SupersetLoader.auth_mode()返回"token",即 JWT 令牌认证(见 superset_data_loader.py)。连接时支持三层优先级的认证策略:
- 显式传入的
access_token(来自 SSO Bridge 弹窗或凭据库); sso_access_token触发_try_sso_exchange()调用POST /api/v1/df-token-exchange/(需 Superset 侧部署 TokenExchangeView,失败时静默降级);- 用户名/密码走 SupersetAuthBridge.login() 调
POST /api/v1/security/login,请求体为{"username", "password", "provider": "db", "refresh": true}。
登录后目录层级为dashboard → dataset(catalog_hierarchy()返回[{"key": "dashboard"}, {"key": "dataset"}]),未挂到任何仪表盘的数据集会出现在根目录的合成命名空间"All Datasets"下;数据集实际取数走 Superset 的Chart Data API(POST /api/v1/chart/data),只需datasource access权限并自动套用行级安全(RLS),source_table参数为数字形式的 dataset ID(如"42")。
如果你不想手动验证 UI,仓库还提供了纯 mock 的单元测试 test_superset_data_connector.py,用
MockSupersetClient模拟 Superset API,覆盖 connect/disconnect、目录浏览、元数据、取数、令牌刷新与前端配置下发等全部契约,无需真实实例即可回归。
六、预定义过滤器端到端测试
DF 插件的过滤面板会读取 Superset 仪表盘的原生过滤器配置并映射为对应的控件:
- 启动两个服务:
./tests/superset/start.sh - 打开 http://localhost:5567 并连接 Superset(
admin/admin登录) - 在 Superset 插件面板中切换到Dashboards视图
- 选择DF Filter Test仪表盘
- 挑选一个数据集(如
df_test_sales) - 应弹出包含预定义过滤器的对话框:
- Region:多选下拉,选项从 Superset 实时加载
- Product:单选下拉
- Sale Date:时间/日期范围选择器
- Quantity Range:数值范围输入
- 调整过滤值并点击 Load,验证加载的数据确实被正确过滤
这一能力在插件侧由两个方法支撑(见 superset_data_loader.py):
get_column_values():为下拉控件拉取列的去重值,采用三级回退策略——先试GET /api/v1/datasource/table/{id}/column/{col}/values/,再试GET /api/v1/dataset/distinct/{col},最后用 Chart Data API 的columns聚合(GROUP BY 等价 DISTINCT)兜底;_build_chart_data_filters():把 DF 侧统一的过滤器 DSL(如BETWEEN、IN、LIKE)翻译成 Chart Data API 的{"col","op","val"}格式,其中BETWEEN会被拆成>=与<=两条(因为 Chart Data API 没有原生 BETWEEN 操作符)。
七、令牌免密登录:SSO Bridge 流程
这是测试环境最有价值的部分:DF 不直接收集 Superset 密码,而是复用 Superset 侧已有的登录会话签发 JWT。
7.1 操作步骤
- 启动两个服务:
./tests/superset/start.sh - 先在 Superset UI(http://localhost:8088)用
admin/admin登录(建立会话) - 打开 http://localhost:5567(Vite 开发模式下为 http://localhost:5173)
- 在 Superset 登录面板点击Login via Superset按钮
- 弹出窗口打开 → Superset 识别已有会话 → 通过
postMessage回传 JWT 令牌 - DF 收到令牌后即完成登录,无需在 DF 侧输入任何凭据
注意:桥接依赖 Superset 侧的活跃会话(第 2 步)。若尚未登录 Superset,弹窗会先跳转到 Superset 登录页。
7.2 源码级实现
SSO Bridge 是一个注册进 Superset 的 Flask Blueprint,定义在 superset_config.py:
- 路由
GET /df-sso-bridge/,校验查询参数df_origin(DF 前端来源),来源必须命中白名单_DEFAULT_DF_ALLOWED_ORIGINS(含 5567/5173 的 localhost 与 127.0.0.1),也支持通过环境变量DF_ALLOWED_ORIGINS追加; - 未认证时使用
_safe_next_path()只允许站内相对路径,跳转到/login/?next=...,防止开放重定向; - 已认证时调用
flask_jwt_extended的create_access_token(identity=current_user.id, fresh=True)与create_refresh_token(...)签发令牌,拼装{"type": "df-sso-auth", "access_token", "refresh_token", "user": {...}}载荷; - 返回一个内联 HTML 页面,其
<script>通过window.opener.postMessage(payload, targetOrigin)把令牌投递给 DF 前端窗口,随后window.close()自动关闭弹窗。
DF 侧插件据此生成登录配置:auth_config()返回mode: "sso_exchange",login_url指向/df-sso-bridge/,exchange_url指向/api/v1/df-token-exchange/(PLG_SUPERSET_SSO_LOGIN_URL可覆盖默认登录地址)。令牌过期后,_ensure_token()会先解析 JWT 的exp声明判断是否过期(带 60 秒缓冲,无需请求 API),过期后优先用 refresh token 调POST /api/v1/security/refresh(注意 flask-jwt-extended 要求把 refresh token 放在Authorization: Bearer头而非 JSON body,见 superset_auth_bridge.py),失败再回退到用户名密码重新登录。
八、不依赖脚本的手动部署
如果不想用start.sh,可以拆开手动执行(等价流程):
# 1. 启动 Superset docker compose -f tests/superset/docker-compose.yml up -d # 2. 等待其健康就绪 docker logs -f df-test-superset # 3. 带插件环境变量启动 DF PLG_SUPERSET_URL=http://localhost:8088 python -m data_formulatorPLG_SUPERSET_URL是插件启用的开关——delegated_login_config()只有在检测到该变量非空时才返回登录配置,未设置时前端不会展示 Superset 登录入口。
九、故障排查清单
| 症状 | 排查方向 |
|---|---|
| Superset 启动太慢 | 首次运行需下载镜像并执行迁移,观察docker logs df-test-superset |
| 插件标签页不显示 | 确认PLG_SUPERSET_URL已设置,并用./tests/superset/start.sh status核对状态 |
| 登录失败 | 确认 Superset 健康:curl http://localhost:8088/health |
| 数据集不可见 | 打开 http://localhost:8088 在 Data → Datasets 中检查;若自动注册失败需手动添加df_test_*表 |
| 端口冲突 | 修改 docker-compose.yml 的端口映射,并同步更新.env.superset |
十、相关源码与测试索引
- 环境编排:docker-compose.yml、start.sh、init-superset.sh
- 数据与过滤器注入:sample_data.py
- SSO Bridge 与特性开关:superset_config.py
- 插件后端实现:superset_data_loader.py、superset_client.py、superset_auth_bridge.py
- 契约级单元测试:test_superset_data_connector.py
若需在 CI 或多人协作中复用,可先跑通 README 的快速开始命令,再用test_superset_data_connector.py做不依赖环境的回归验证,两条路径互为补充,覆盖从真实容器到 API 契约的完整插件质量闭环。
【免费下载链接】data-formulator🪄 Data Formulator is an interactive AI-powered data analysis system makes it easy to connect, explore and visualize data.项目地址: https://gitcode.com/GitHub_Trending/da/data-formulator
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考