You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Python Dash回调间持久化数据实现告警功能

问题说明

我在首页设置了若干徽章,用颜色标识后台进程状态,通过dcc.Interval每30秒从Redis拉取进程信息更新徽章颜色。现在需要实现徽章变为红色(danger)时触发告警音,但难点是如何保存上一次的颜色数据,以便和新生成的颜色列表对比,且避免重复查询Redis。

当前回调代码仅能更新徽章颜色,无法留存历史状态:

def initialise_callbacks(app):
    @app.callback(
        [Output("{}".format(file), "color") for file in files],
        [Input("live-update2", "n_intervals")],
    )
    def update_greeks(interval):

        # default to list of "danger"
        color_list = ["danger" for i in files]

        i = 0
        for file in files:
            update_time = conn.get("{}_update".format(file.upper())) #get status from database
            if update_time:
                if update_time.isOld: 
                    color_list[i] = "success"
                else:
                    color_list[i] = "danger"
            else:
                color_list[i] = "danger"
        i = i + 1
        return color_list

尝试过用dcc.Store但遇到同一变量既做输入又做输出的报错,不想用两个回调重复查询Redis。

解决方案

可以通过单个回调同时处理Redis查询、状态对比、徽章更新和存储更新,利用dcc.Store的State获取旧状态,同时将其作为Output更新为新状态,避免重复查询。

步骤1:添加dcc.Store组件

在布局中添加一个dcc.Store用于存储历史颜色列表,设置初始值为全"danger"的列表:

dcc.Store(id='color-history-store', data=["danger"]*len(files))

步骤2:修改回调逻辑

更新回调,同时接收dcc.Store的旧状态作为State,并将新状态作为Output之一。在回调内完成一次Redis查询,生成新颜色列表后和旧列表对比,触发告警逻辑,最后返回徽章颜色和新的存储数据:

def initialise_callbacks(app):
    @app.callback(
        # 输出:所有徽章的颜色 + 存储的新状态
        [Output(f"{file}", "color") for file in files] + [Output('color-history-store', 'data')],
        # 输入:定时器触发
        [Input("live-update2", "n_intervals")],
        # 状态:上一次的颜色列表
        [State('color-history-store', 'data')]
    )
    def update_greeks(interval, old_color_list):
        # 1. 单次Redis查询生成新颜色列表
        new_color_list = ["danger" for _ in files]
        for idx, file in enumerate(files):
            update_time = conn.get(f"{file.upper()}_update")
            if update_time:
                new_color_list[idx] = "success" if update_time.isOld else "danger"
        
        # 2. 对比新旧状态,触发告警逻辑
        # 遍历检查每个徽章是否从非danger变为danger
        for idx, (old_color, new_color) in enumerate(zip(old_color_list, new_color_list)):
            if old_color != "danger" and new_color == "danger":
                # 此处添加告警音触发逻辑,例如调用前端音频播放函数
                play_alert_sound()
        
        # 3. 返回徽章颜色和新的存储数据
        return new_color_list + [new_color_list]

关键说明

  • 仅需一次Redis查询即可获取所有进程状态,避免重复操作;
  • dcc.Store同时作为State(获取旧值)和Output(更新新值)在Dash中是合法的,只要不同时将其设为Input和Output即可;
  • 告警逻辑可根据需求实现,比如通过clientside_callback在前端直接播放音频,减少后端交互。

内容的提问来源于stack exchange,提问作者Marcelo ARK

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 14:30:57