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

Plotly Dash回调未触发,如何停止Python脚本执行?

Dash应用无法触发/shutdown回调的问题排查与解决

我遇到了和《How to stop execution after some time?》相同的需求,尝试了其中的Plotly Dash解决方案,但完全没效果——对应的回调代码根本没被执行到。

设置好app.layout后,我写了如下代码:

def shutdown():
    func = request.environ.get('werkzeug.server.shutdown')
    if func is None:
        raise RuntimeError('Not running with the Werkzeug Server')
    func()


@app.callback(dependencies.Output('page-content', 'children'), [dependencies.Input('url', 'pathname')])
def display_page(pathname):
    if pathname == '/shutdown':
        print('I\'m here')
        shutdown()
    return html.Div([html.H3('You are on page {}'.format(pathname))])

if __name__ == '__main__':
    app.title = "EOS Testing Dashboard"
    app.run_server(debug=False)

代码里的print('I\'m here')从未执行,甚至在最后一行加sys.exit()也没反应,请问这是什么原因?该如何解决?


问题原因

  • 缺少关键组件配置:如果app.layout里没加dcc.Location组件,或者组件参数不对,url的pathname输入根本不会触发回调,自然走不到/shutdown的判断逻辑。
  • Werkzeug shutdown方法已废弃:新版本Werkzeug移除了werkzeug.server.shutdown,就算回调触发了,调用这个方法会直接抛出异常,导致后续流程中断。
  • 回调阻塞问题:就算shutdown方法还能用,调用它会直接终止服务器,导致回调无法完成返回值的传递,Dash可能会因为回调未正常返回而跳过部分代码执行。

解决方法

1. 先确保路由触发的基础配置正确

在app.layout里必须包含dcc.Location组件,并且设置refresh=False避免页面刷新打断回调:

import dash_core_components as dcc
import dash_html_components as html

app.layout = html.Div([
    dcc.Location(id='url', refresh=False),
    html.Div(id='page-content')
])

配置完后访问http://localhost:8050/shutdown,回调才会被触发。

2. 替换废弃的shutdown方法,用线程异步停止服务器

改用app.server.shutdown(),并且通过线程异步执行,避免阻塞回调的返回流程:

import threading
import time
from dash import Dash, html, dcc, Input, Output

app = Dash(__name__)

app.layout = html.Div([
    dcc.Location(id='url', refresh=False),
    html.Div(id='page-content')
])

def stop_server():
    time.sleep(1)  # 留时间让回调返回结果给前端
    app.server.shutdown()

@app.callback(Output('page-content', 'children'), Input('url', 'pathname'))
def display_page(pathname):
    if pathname == '/shutdown':
        print("I'm here")
        # 开个线程执行停止操作,不阻塞当前回调
        threading.Thread(target=stop_server).start()
        return html.Div([html.H3('Server is shutting down...')])
    return html.Div([html.H3('You are on page {}'.format(pathname))])

if __name__ == '__main__':
    app.title = "EOS Testing Dashboard"
    app.run_server(debug=False)

3. 生产环境建议用外部管理方式

如果是生产环境部署,别在应用内部写shutdown逻辑,用Gunicorn、systemd这类进程管理工具,通过系统信号(比如Ctrl+C发送SIGINT)来启停服务器,更稳定可靠。


内容的提问来源于stack exchange,提问作者Anna Ramolini

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 05:50:28