如果从 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')
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')