使用 Gradio 从 Google BigQuery 构建实时数据仪表盘:凭据配置、查询与定时刷新全指南
2026/9/9 19:31:57 网站建设 项目流程

使用 Gradio 从 Google BigQuery 构建实时数据仪表盘:凭据配置、查询与定时刷新全指南

【免费下载链接】gradioBuild and share delightful machine learning apps, all in Python. 🌟 Star to support our work!项目地址: https://gitcode.com/GitHub_Trending/gr/gradio

本指南演示如何用 Python +gradio查询 Google BigQuery 中的大规模数据集,并将结果实时呈现在网页仪表盘上:从 BigQuery 服务帐号凭据的获取、google-cloud-bigquery客户端的初始化,到用约 7 行 Gradio 代码同时渲染自动刷新的数据表格(gr.DataFrame)与散点图(gr.ScatterPlot)。读完本文,你将掌握 Gradio「组件函数值 +every定时重算」这一经典模式,并能将其复用到任意数据库或云端数据仓库的实时监控场景。

本指南以纽约时报公开的 COVID-19 美国县级数据(BigQuery 公共数据集covid19_nyt.us_counties,记录了各县累计确诊病例与死亡人数)为例展开。写作时建议读者先熟悉 Blocks 布局与事件机制;若从零开始,可先通读 快速入门指南。

整体思路:三种角色如何协同

整个实时仪表盘由三个层次组成,各司其职:

层次承担者职责
数据源Google BigQuery无服务器、可横向扩展的云端数据仓库,用类似 SQL 的语法分析大规模数据
查询层google-cloud-bigqueryPython 客户端使用服务帐号凭据完成鉴权,执行查询并把结果转为 pandasDataFrame
展示层gradio(Blocks + 数据组件)接收查询函数,定时触发重算并渲染表格与图表

值得强调的是:Gradio 本身并不感知 BigQuery,二者通过「一个返回 pandasDataFrame的普通 Python 函数」解耦。这让本指南展示的模式天然可移植——把查询函数换成 SQLite、PostgreSQL、Supabase 或 Google Sheets,界面代码几乎无需改动。

前置准备

运行本指南需要安装两部分依赖:

pip install gradio pip install "google-cloud-bigquery[pandas]"

第二行的[pandas]是 BigQuery 客户端的可选插件,安装后客户端可将查询结果直接转换为 pandasDataFrame,这是后续渲染表格与图表的前提。仓库中的相关仪表盘演示可参考 demo/dashboard/run.py,其依赖同样非常精简(demo/dashboard/requirements.txt 仅含plotlypandas)。

第一步:获取并设置 BigQuery 凭据

访问 BigQuery 需要服务帐号(service account)密钥文件。如果你手上已有一份.json格式的凭据文件,可直接跳到下一节;否则按以下步骤在 Google Cloud 控制台创建(免费可用):

  1. 登录 Google Cloud 账户并打开 Google Cloud 控制台。
  2. 点击左上角汉堡菜单,进入「API 与服务」(APIs & Services)。若无项目需先创建项目。
  3. 点击「+ 启用 API 与服务」(Enable APIs and Services),搜索并启用「BigQuery API」。若按钮显示为「管理」,说明该 API 已启用。
  4. 在同一菜单中打开「凭据」(Credentials)选项卡,点击「创建凭据」(Create Credentials)。
  5. 在创建凭据对话框中选择「服务帐号密钥」(Service Account Key)类型,为其命名;可同时为该服务帐号授予如「BigQuery 用户」(BigQuery User)角色,使其具备运行查询的权限。
  6. 选定服务帐号后,密钥类型选择「JSON」,点击「创建」。浏览器将下载包含凭据的 JSON 密钥文件,内容结构大致如下:
{ "type": "service_account", "project_id": "your project", "private_key_id": "your private key id", "private_key": "private key", "client_email": "email", "client_id": "client id", "auth_uri": "https://accounts.google.com/o/oauth2/auth", "token_uri": "https://accounts.google.com/o/oauth2/token", "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/email_id" }

安全提醒:该 JSON 文件包含私钥明文(private_key),等同于数据仓库的访问凭证。请勿将其提交进 Git 仓库、硬编码进公开脚本或暴露在共享目录中;推荐的做法是用环境变量指向文件路径(例如GOOGLE_APPLICATION_CREDENTIALS=/secure/path/key.json)并利用操作系统的权限机制限制访问,同时为服务帐号授予最小够用的角色(本场景只需要读取/查询权限,不需要写入权限)。

第二步:初始化客户端并编写查询函数

凭据就绪后,在代码中通过from_service_account_json指定密钥文件路径完成鉴权:

from google.cloud import bigquery client = bigquery.Client.from_service_account_json("path/to/key.json")

一旦鉴权通过,即可用该客户端对任意有权访问的数据集执行查询。下面是一个示例查询函数:从covid19_nyt.us_counties中按日期倒序取出「截至当前日期累计确诊病例数最多的前 20 个县」:

import numpy as np QUERY = ( 'SELECT * FROM `bigquery-public-data.covid19_nyt.us_counties` ' 'ORDER BY date DESC,confirmed_cases DESC ' 'LIMIT 20') def run_query(): query_job = client.query(QUERY) query_result = query_job.result() df = query_result.to_dataframe() # Select a subset of columns df = df[["confirmed_cases", "deaths", "county", "state_name"]] # Convert numeric columns to standard numpy types df = df.astype({"deaths": np.int64, "confirmed_cases": np.int64}) return df

这段代码有两处工程细节值得展开:

  • 同步等待查询完成client.query()是异步提交,真正的数据要等query_job.result()执行完成后才可用;to_dataframe()由安装的 pandas 插件提供,将结果集封装为DataFrame。对于小规模结果这足够直观,若要处理超大结果可改走分页或fetch_dataframe流式路径。
  • 显式转换数值列类型:BigQuery 返回的数值类型可能是数据库原生标量,未必与 pandas/后续绘图库完全兼容,因此这里用df.astype({"deaths": np.int64, "confirmed_cases": np.int64})统一转成标准的 numpy 整数类型。这一步对后续散点图的数值映射、坐标轴刻度计算尤其重要,可避免类型相关告警或隐式类型推断。

第三步:用约 7 行代码构建实时仪表盘

先验证数据:gr.DataFrame定时刷新表格

拿到返回DataFrame的查询函数后,最直接的展示方式是把它交给gr.DataFrame组件。其关键机制是:当组件的value是一个可调用对象(函数)时,Gradio 会在页面加载时立即调用它以填充组件。借助every参数可以进一步让它按固定周期自动重算。

import gradio as gr with gr.Blocks() as demo: gr.DataFrame(run_query, every=gr.Timer(60*60)) demo.queue().launch() # Run the demo using queuing

这里gr.Timer(60*60)表示每 3600 秒(即每小时)触发一次数据刷新。

关于everygr.Timer的底层行为,可以直接在仓库源码中找到依据:

  • every是组件的通用参数(声明于 gradio/components/base.py),类型为Timer | float | None。也就是说除了传gr.Timer,也可以直接传一个浮点数(如every=60)表示以秒为单位的刷新间隔。
  • gr.Timer定义于 gradio/components/timer.py:它是一个不可见的特殊组件,构造参数value表示两次 tick 之间的间隔秒数(默认 1 秒),另有active参数控制定时器是否激活(默认True)。文档注释明确指出其用途正是「按固定间隔触发事件」,所以这里传入的其实是语义化的定时器对象。

需要特别说明的是every参数的语义(同样记载在 gradio/components/native_plot.py 的NativePlot等组件文档字符串中):当且仅当value是函数时它才生效,用于持续重算value;如果value本身就是静态数据,every不会产生任何效果。另外,如果组件的刷新依赖其他控件(比如下拉选择某个县),可以额外传inputs参数,让value在这些输入变化时也同步重算。

数据可视化:gr.ScatterPlot加入散点图

表格适合核对明细,而洞察数据关系则需要可视化。gr.ScatterPlot组件可以直接消费同一个返回DataFrame的查询函数,把病例数与死亡数的关系画成散点图,用于探索与解读数据。它同样支持every参数实现自动刷新。

gr.ScatterPlot在仓库中继承自NativePlot(类定义见 gradio/components/native_plot.py),其构造参数相当丰富。就本教程用到的几个关键参数而言:

参数作用备注
value数据来源接受静态pd.DataFrame,也接受返回DataFrame函数(配合every实现定时刷新)
xX 轴对应列可为数值、日期时间或字符串/类别列
yY 轴对应列必须为数值列
color按某列着色分组必须为字符串/类别列(本示例未用)
tooltip悬停提示内容值为"axis""all""none",也支持传入列名字符串列表(本示例传入"county"以在悬停时显示县名)
width/height图表像素尺寸本示例将其设定为 500×500 的方形画布
every自动刷新传入Timer或浮点秒数

完整示例:表格 + 散点图同屏实时刷新

将两者放入 Blocks 的行布局中即可得到完整仪表盘:

import gradio as gr with gr.Blocks() as demo: gr.Markdown("# 💉 Covid Dashboard (Updated Hourly)") with gr.Row(): gr.DataFrame(run_query, every=gr.Timer(60*60)) gr.ScatterPlot(run_query, every=gr.Timer(60*60), x="confirmed_cases", y="deaths", tooltip="county", width=500, height=500) demo.queue().launch() # Run the demo with queuing enabled

各部分的实际效果:

  • gr.Markdown渲染页面大标题,标注「每小时更新」的语义;
  • gr.Row将表格与散点图并排布局,充分利用横向空间;
  • 两个组件共享同一个run_query与同一个gr.Timer(60*60),因此页面加载时会各执行一次查询,此后每小时一起自动刷新,无需用户手动操作;
  • 散点图悬停于某个点时,会通过tooltip="county"显示对应县名,便于把异常点(如确诊高但死亡低的县)定位到具体地理位置。

注意末尾必须调用demo.queue().launch()(而非直接launch()):定时刷新与后台重算依赖任务队列机制,开启队列才能保证周期性触发的查询被可靠调度与执行。

从被动刷新到主动交互:理解两种仪表盘形态

every驱动的仪表盘适合「按固定节奏自动更新」的监控场景。而在仓库的 demo/dashboard/run.py 中可以看到另一种常见的交互式仪表盘形态:它把数据获取绑定到按钮点击事件(fetch.click(...)),让用户在界面中通过CheckboxGroup勾选关心的指标库,再按需触发查询并更新gr.Plot图表,甚至支持gr.Plot(visible=False)动态控制图表显隐。

两种形态可在同一应用内自由组合,构成完整的仪表盘设计工具箱:

  • 自动刷新型:数据源更新频率稳定、无需人工干预(本教程的疫情数据即属此类),用every=gr.Timer(间隔秒数)
  • 按需查询型:用户想控制何时发起昂贵查询、或查询高度依赖用户输入,用事件监听(如Button.click)驱动函数执行。

将本教程的run_query换成一个每次返回当前时间戳或轮询最新流数据的函数,即可实现数据看板、网站监控面板、指标告警台等各类实时应用。

本地运行与后续部署建议

在本地验证仪表盘时,直接执行脚本即可(Gradio 会启动开发服务器并输出本地 URL)。需要分享给团队或部署到云端时,可结合demo.queue()的排队机制与 Gradio 的launch()参数(如share=True生成临时公网链接、或server_name/server_port绑定端口)配置运行环境。

关于安全与成本的两点提醒同样适用于本教程:

  • 把含有私钥的凭据文件存放在受保护的位置,切勿通过公网直接暴露;
  • BigQuery 按扫描数据量计费,公开数据集(以bigquery-public-data前缀命名的项目)免费查询,但接入自有数据集时,建议在 SQL 中通过WHERE分区裁剪与LIMIT限制每次刷新的扫描量,再结合较大的刷新间隔(如每小时)控制成本。

小结

本文完整走通了「BigQuery 凭据 → Python 客户端 → 查询函数 → Gradio 实时展示」的整条链路:

  1. 在 Google Cloud 控制台创建服务帐号并导出 JSON 密钥文件,安装google-cloud-bigquery[pandas]
  2. bigquery.Client.from_service_account_json(...)完成鉴权,编写返回 pandasDataFrame的查询函数;
  3. gr.Blocks中把查询函数作为组件value,配合gr.Timer驱动的every参数,即可让gr.DataFramegr.ScatterPlot按小时自动刷新,总计仅需数行核心代码。

这套「查询函数 + 组件 + 定时器」的写法是 Gradio 数据类仪表盘应用的通用范式。无论你的数据在 BigQuery、传统数据库还是任何能被 Python 读取的数据源中,都可以照此模式快速搭出专业、可分享的实时仪表盘。

【免费下载链接】gradioBuild and share delightful machine learning apps, all in Python. 🌟 Star to support our work!项目地址: https://gitcode.com/GitHub_Trending/gr/gradio

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询