如果从 flask 创建并调用了 dash 应用程序,则 Dash 回调不起作用

Dash callbacks not working, if dash app is created and called from flask

Dash 应用程序在通过烧瓶服务器创建和调用时失败。 Dash 的“回调”无效,并给出 Post 请求 400。非常感谢任何帮助。

下面是重现问题的示例代码。我使用最新的 Dash 0.22.0、Dash HTML 组件 0.11.0、Dash 核心组件 0.24.1 和 Flask 1.0.2:

# file 'simple_flask.py'

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_wtf.csrf import CSRFProtect


# Initialise flask App 
app = Flask(__name__, instance_relative_config=True)
#app.config.from_object('config.Config')

db = SQLAlchemy()         # SQLAlchemy
csrf_protect = CSRFProtect()

def set_app(app):

    # Setup WTForms CSRFProtect
    app.secret_key = 'My super secret key'
    csrf_protect.init_app(app)

    # Setup Flask-SQLAlchemy
    db.init_app(app) 

    # run in app context
    with app.test_request_context():
        db.create_all()

        from simple_dash import create_dash
        create_dash(app)


if __name__ == '__main__':
    set_app(app)
    app.run(host='127.0.0.1', port=5002, debug=True) 


## file 'simple_dash.py'

import dash
import dash_html_components as html
import dash_core_components as dcc

def create_dash(app):
    dash_app = dash.Dash(__name__, server=app, 
                        #static_folder='/static',
                        #url_base_pathname='/app/oga/', 
                        # csrf_protect=False
                        )
    dash_app.layout = html.Div([
        dcc.Dropdown(
            id='my-dropdown',
            options=[
                {'label': 'New York City', 'value': 'NYC'},
                {'label': 'Montreal', 'value': 'MTL'},
                {'label': 'San Francisco', 'value': 'SF'}
            ],
            value='NYC'
        ),
        html.Div(id='output-container')
    ])


    @dash_app.callback(
        dash.dependencies.Output('output-container', 'children'),
        [dash.dependencies.Input('my-dropdown', 'value')])
    def update_output(value):
        return 'You have selected "{}"'.format(value)

加载页面后缺少的引用以及下拉列表中的任何后续更改是:“POST /_dash-update-component HTTP/1.1” 400.

根据 @T4rk1n 的 dash github 的指示,这是 CSRFProtect flask 扩展和 Dash 之间的冲突。下面展示了如何从 CSRFProtect 中排除 Dash:

csrf_protect = CSRFProtect() csrf_protect._exempt_views.add('dash.dash.dispatch')