【Flask】测试平台开发,数据看板开发-第二十一篇:TaoToken 统一 Key 接入 Echarts/G2Plot 图表数据链路

发布时间:2026/9/28 11:27:58

【Flask】测试平台开发,数据看板开发-第二十一篇:TaoToken 统一 Key 接入 Echarts/G2Plot 图表数据链路 1. 从一次看板联调说起数据链路为什么总在 Key 上卡住做 Flask 测试平台到第二十一篇产品、应用、需求提测这些模块都跑通了但每周提测了多少需求、哪些产品在动光看列表不直观于是要加数据看板。看板本身不复杂后端聚合出「周 × 应用」的提测数量前端用 Echarts 画堆叠面积图、用 G2Plot 画分组柱状图。真正让人反复返工的不是图表配置而是数据链路里的模型调用凭证管理。我试过的场景是这样的看板里想加一个「智能摘要」入口把本周提测趋势丢给模型生成一句话结论同时本地还用着 Claude Code 做代码补全、用另一个脚本做数据清洗。结果每个工具一套 Key、一套 base_url散落在.env、settings.json、config.toml里改一次要翻五个文件联调时经常出现「图表接口通了、模型调用 401」的割裂状态。这篇就把这条链路收拢Flask 后端聚合接口 Echarts/G2Plot 渲染 TaoToken 统一 Key 接入目标是一次配置跑通后面加图表、加模型能力都不用再动凭证。适合谁看正在用 Flask 写测试平台、前端用 Vue Element 做看板、并且希望把多个 AI 工具的调用凭证统一管理的同学。你需要有基本的 Flask 蓝图概念和 Vue 组件使用经验图表部分我会给完整可复制的代码。2. TaoToken 前置把分散的 Key 收成一个入口TaoToken 在这里扮演的角色是「统一模型调用入口」。它提供 OpenAI 兼容的接口形态也就是说你原来用openaiSDK 或requests直接发 chat completions 请求的代码只需要改base_url和api_key两个值其余请求体结构不变。对看板场景来说这意味着后端聚合接口里想加模型能力时不用再引入新的 SDK 或新的鉴权逻辑。先明确几个地址后面配置里会反复用到官网入口https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentAPI 基址https://taotoken.net/api 注意这个不带查询参数代码里填这个模型对话页https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_contentmodel_chatutm_campaignrewriteCoding Plan 页https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding_planutm_campaignrewrite控制台https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewriteAPI Keys 管理https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi_keysutm_campaignrewrite接入文档https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewriteClaudeCodeAnthropic 接入https://taotoken.net/claudecode-anthropic?utm_sourcetaotoken_aicg_blog_endutm_contentclaudecodeutm_campaignrewrite操作顺序建议这样先进控制台创建 Key然后在 API Keys 页面复制出来如果你同时用 Claude Code 这类编码工具可以在 ClaudeCodeAnthropic 页面看对应的接入方式把同一套 Key 复用过去。看板后端只需要一个 Key前端不直接持有 Key所有模型调用都走 Flask 后端转发这样前端打包产物里不会泄露凭证。注意Key 只放在后端环境变量或配置文件里不要写进 Vue 的.env或前端源码。看板前端只调用你自己的 Flask 接口。3. 可复制配置config.toml 与 settings.json 骨架统一配置的核心思路是「一份凭证、多处引用」。后端用config.toml管数据库和模型入口本地工具用settings.json管编码助手两者都指向同一个 Key 来源。下面是可以直接抄的骨架。3.1 后端 config.toml# configs/config.toml [mysql] host 127.0.0.1 port 3306 user root password your_db_password database test_platform [taotoken] # 统一模型调用入口所有 AI 能力都走这里 base_url https://taotoken.net/api api_key sk-你的TaoTokenKey default_model gpt-4o-mini timeout 30 [dashboard] # 看板聚合接口的默认时间跨度天 default_range_days 30对应的 Python 读取逻辑放在configs/__init__.py里用tomllibPython 3.11或tomli# configs/__init__.py import tomllib from pathlib import Path _config_path Path(__file__).parent / config.toml with open(_config_path, rb) as f: _cfg tomllib.load(f) class Config: MYSQL_HOST _cfg[mysql][host] MYSQL_PORT _cfg[mysql][port] MYSQL_USER _cfg[mysql][user] MYSQL_PASSWORD _cfg[mysql][password] MYSQL_DATABASE _cfg[mysql][database] TAOTOKEN_BASE_URL _cfg[taotoken][base_url] TAOTOKEN_API_KEY _cfg[taotoken][api_key] TAOTOKEN_DEFAULT_MODEL _cfg[taotoken][default_model] TAOTOKEN_TIMEOUT _cfg[taotoken][timeout] DASHBOARD_DEFAULT_RANGE_DAYS _cfg[dashboard][default_range_days] config Config()3.2 本地工具 settings.json如果你同时用编码助手类工具把同一套 Key 写进它的settings.json避免两处维护{ env: { ANTHROPIC_BASE_URL: https://taotoken.net/api, ANTHROPIC_API_KEY: sk-你的TaoTokenKey }, model: claude-sonnet-4-20250514, permissions: { allow: [Read, Write, Bash] } }这样后端config.toml和本地settings.json指向同一个 Key 来源改 Key 时两处同步即可不会出现「看板接口能调、编码工具报 401」的错位。3.3 后端聚合接口复用现有蓝图看板的堆叠数据接口沿用你已有的test_dashboard蓝图这里补一个带模型摘要的版本展示统一 Key 怎么接进来# apis/dashboard.py import requests from flask import Blueprint, request, current_app from configs import config, format from apis.product import pool test_dashboard Blueprint(test_dashboard, __name__) test_dashboard.route(/api/dashboard/stacked, methods[POST]) def get_request_stacked(): connection None try: connection pool.connection() with connection.cursor() as cursor: sql SELECT DATE_FORMAT(r.createDate, %%Y%%u) AS weeks, COALESCE(a.note, No_App) AS note, COUNT(a.id) AS counts FROM request r LEFT JOIN apps a ON r.appId a.id GROUP BY weeks, note cursor.execute(sql) rows cursor.fetchall() weeks, notes, key_value [], [], {} for row in rows: week row[weeks] or No_Week note row[note] or No_App counts row[counts] or 0 if week not in weeks: weeks.append(week) if note not in notes: notes.append(note) key_value[f{week}_{note}] counts weeks.sort() series {note: [key_value.get(f{week}_{note}, 0) for week in weeks] for note in notes} resp format.resp_format_success resp[data] {weeks: weeks, notes: notes, series: series} return resp except Exception as e: current_app.logger.error(fstacked error: {e}) resp format.resp_format_error resp[message] Failed to process stacked data return resp, 500 finally: if connection: connection.close()模型摘要接口单独一个路由调用 TaoTokentest_dashboard.route(/api/dashboard/summary, methods[POST]) def get_dashboard_summary(): body request.get_json() or {} weeks body.get(weeks, []) totals body.get(totals, []) prompt f以下是最近几周的提测数量周 {weeks}数量 {totals}。用一句话总结趋势不超过40字。 try: resp requests.post( f{config.TAOTOKEN_BASE_URL}/v1/chat/completions, headers{ Authorization: fBearer {config.TAOTOKEN_API_KEY}, Content-Type: application/json, }, json{ model: config.TAOTOKEN_DEFAULT_MODEL, messages: [{role: user, content: prompt}], temperature: 0.3, }, timeoutconfig.TAOTOKEN_TIMEOUT, ) resp.raise_for_status() summary resp.json()[choices][0][message][content] return {code: 20000, message: success, data: {summary: summary}} except requests.RequestException as e: current_app.logger.error(fsummary error: {e}) return {code: 50000, message: summary failed, data: {}}, 500注意base_url后面拼的是/v1/chat/completions这是 OpenAI 兼容路径。如果你的接入文档里写的是别的路径以文档为准。4. 验证请求从 curl 到 Echarts/G2Plot 渲染配置写完先别急着开前端用 curl 把后端接口和模型入口分别打一遍确认链路通。4.1 验证模型入口curl -X POST https://taotoken.net/api/v1/chat/completions \ -H Authorization: Bearer sk-你的TaoTokenKey \ -H Content-Type: application/json \ -d { model: gpt-4o-mini, messages: [{role: user, content: 回复 ok}] }返回里能看到choices[0].message.content就说明 Key 和 base_url 都对。如果返回 401先检查 Key 有没有多余空格返回 404 就检查路径是不是/v1/chat/completions。4.2 验证看板聚合接口curl -X POST http://127.0.0.1:5000/api/dashboard/stacked \ -H Content-Type: application/json \ -d {}期望返回结构{ code: 20000, message: success, data: { weeks: [202601, 202602], notes: [提测平台, 性能测试], series: { 提测平台: [12, 18], 性能测试: [3, 5] } } }4.3 前端 Echarts 堆叠面积图在src/views/dashboard/index.vue里Echarts 部分沿用你原来的写法关键是series动态生成import * as echarts from echarts import { requestStacked } from /api/board export default { name: Dashboard, mounted() { this.getStackedData() }, methods: { getStackedData() { requestStacked().then(resp { this.initStackedChart(resp.data) }) }, initStackedChart(data) { const chartDom this.$refs[LineChartBoard] const myChart echarts.init(chartDom) const series [] for (const key in data.series) { series.push({ name: key, type: line, stack: Total, areaStyle: {}, emphasis: { focus: series }, data: data.series[key] }) } const option { title: { text: 周需求提测趋势 }, tooltip: { trigger: axis }, legend: { data: data.notes }, xAxis: [{ type: category, boundaryGap: false, data: data.weeks }], yAxis: [{ type: value }], series } myChart.setOption(option) } } }4.4 G2Plot 分组柱状图G2Plot 的数据绑定更直接接口返回的[{weeks, note, counts}]数组可以直接喂给Columnimport { Column } from antv/g2plot import { requestMetaData } from /api/board export default { data() { return { stackedColumnPlot: undefined, stackedColumnData: [], stackedColumnMode: true } }, mounted() { this.stackedColumnPlot new Column(ColumnBoard, { data: this.stackedColumnData, xField: weeks, yField: counts, seriesField: note, isGroup: true, columnStyle: { radius: [20, 20, 0, 0] } }) this.stackedColumnPlot.render() this.getMetaData() }, methods: { getMetaData() { requestMetaData({ date: [] }).then(resp { this.stackedColumnData resp.data this.stackedColumnPlot.changeData(this.stackedColumnData) }) } } }两个图表都渲染出来后再调一次/api/dashboard/summary把模型返回的一句话摘要显示在卡片头部整条链路就算跑通了。5. 本篇常见错排查图表空白但接口有数据Echarts 初始化必须在 DOM 挂载后用mounted而不是createdG2Plot 的容器id要确保在new Column之前已经存在否则render()找不到节点。series 里出现 undefined后端拼key_value时如果 week 或 note 为 NULL键名会变成None_None前端遍历时对不上。用or No_Week/or No_App兜底和上面代码一致。模型接口 401先确认Authorization头是Bearer sk-xxx格式再确认base_url没有多写/v1配置里填https://taotoken.net/api请求时再拼/v1/chat/completions。如果本地settings.json和后端config.toml用了不同 Key也会出现一边通一边不通。G2Plot 切换分组/累积模式不生效update方法传的是增量配置isGroup要传字符串true/false传布尔值在部分版本里不触发重绘。跨域报错前端开发服务器调 Flask 接口时在 Flask 侧加flask-cors或者用 Vue 的devServer.proxy转发不要在前端直接请求 TaoToken 的地址。6. 后续怎么接按场景分流看板数据链路跑通后如果你要继续加模型能力按用途选入口会更省事。只是想在页面上试模型效果、对比不同模型的摘要质量去模型对话页直接试不用改代码https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_contentmodel_chatutm_campaignrewrite如果是长期在编码工具里用、或者要把 Agent 接到看板的自动化流程里看 Coding Plan 的额度方式https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding_planutm_campaignrewrite接入过程中遇到 401、路径不对、Key 管理混乱这类问题直接翻接入文档和 API Keys 页面最快https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 和 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi_keysutm_campaignrewrite我自己的习惯是后端config.toml只留一个[taotoken]段所有模型调用都从这里读base_url和api_key前端永远不碰 Key。这样看板加多少个图表、加多少个模型入口凭证都只有一处要改。
延伸阅读

更多相关文章

2026/9/28 11:27:58

网络拓扑图怎么画?一文讲透需求梳理、工具选型与实操规范

在技术社区泡久了,隔三差五就能看到这样一个帖子:"各位大佬帮我画一个拓扑图"。下面跟着一张模糊的截图,或者干脆就是一句话需求。说句实话,这种帖子我一般不会直接甩一张图画过去,因为网络拓扑图这东西&…

2026/9/28 20:03:44

Trae AI 能力实战:用 Remote-SSH 打通跨系统开发与远程协作

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/28 3:03:23

东莞市品牌网站建设报价常见报错与解决

东莞品牌网站建设报价单背后:一份保姆级建站教程避坑实录 网站做好了没人访问,这大概是很多老板最头疼的事。花了大几万做的品牌站,上线后流量惨淡,比路边摊还冷清。别急着骂外包公司,很多“东莞品牌网站建设报价”里藏着不少猫腻,比如用模板站冒充定制…

2026/9/28 6:05:15

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解 【免费下载链接】spirula-studio Cross-vendor 3D Gaussian Splatting trainer - video to splat to mesh, Vulkan or CUDA. 项目地址: https://gitcode.com/GitHub_Trending/sp/spirula-studio Sp…

2026/9/28 6:07:41

SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南 模板网站太丑不够用?别急着加滤镜,那是治标不治本。很多老板盯着后台流量掉得眼红,却还在纠结首页Banner的圆角是不是3像素。这就像穿着西装去挖土,姿势不对,努力白费。我整理这份 速查手册…

2026/9/28 0:02:03

广州外贸网站建设推广:从零搭建全流程拆解与真实报价避坑

广州外贸网站建设推广:从零搭建全流程拆解与真实报价避坑 改个需求建站公司拖一周,后台改个文案还得再交一笔“技术维护费”。这种憋屈事儿,做外贸的朋友太熟悉了。很多老板在找广州外贸网站建设推广服务商时,光盯着首页好不好看,却忽略了从零搭建一个能…

2026/9/28 0:02:04

搞懂百度竞价推广价格,网站性能优化别掉链子

搞懂百度竞价推广价格,网站性能优化别掉链子 网站突然打不开,浏览器弹出红色警告“此网站存在安全风险”,后台一看全是乱码代码和奇怪的跳转链接。这种网站被黑挂马的绝望感,很多刚转行做网站的朋友都经历过,尤其是那些为了省几百块钱服务器费用的新手。…

2026/9/25 20:55:38

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/26 19:58:38

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/28 1:59:25

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑