Python 为Flask服务器提供服务的Dash应用程序出现内部服务器错误:蓝图之间发生名称冲突
我正在使用Flask服务器中的Dash应用程序 这是我如何实例化Flask服务器的:Python 为Flask服务器提供服务的Dash应用程序出现内部服务器错误:蓝图之间发生名称冲突,python,flask,web-applications,plotly-dash,Python,Flask,Web Applications,Plotly Dash,我正在使用Flask服务器中的Dash应用程序 这是我如何实例化Flask服务器的: from flask import Flask, redirect server = Flask(__name__, template_folder="../frontend/templates", instance_relative_config=True) 这是“创建短跑应用程序”功能: import dash def create_dash_app(server):
from flask import Flask, redirect
server = Flask(__name__, template_folder="../frontend/templates",
instance_relative_config=True)
这是“创建短跑应用程序”功能:
import dash
def create_dash_app(server):
dash_app = dash.Dash(
__name__,
server=server,
url_base_pathname='/dash/',
external_stylesheets=['https://codepen.io/chriddyp/pen/bWLwgP.css']
)
dash_app.config['suppress_callback_exceptions'] = True
dash_app.layout = html.H3("Lorem ipsum... ")
return dash_app.server
在我的一条服务器路由上,我有以下内容:
@server.route('/filter')
def filter_stuff():
<some code>
create_dash_app()
redirect("/dash")
> AssertionError: A name collision occurred between blueprints
> <flask.blueprints.Blueprint object at 0x11905bcd0> and
> <flask.blueprints.Blueprint object at 0x118acbad0>. Both share the
> same name "_dash_dash_assets". Blueprints that are created on the fly
> need unique names.
@server.route(“/filter”)
def filter_stuff():
创建_dash_app()
重定向(“/dash”)
关键是,对于我的用例,用户可能希望看到dash应用程序,返回过滤器路径,应用一些过滤器并检查dash应用程序中的变化。
不幸的是,当我这样做时,我得到了以下信息:
@server.route('/filter')
def filter_stuff():
<some code>
create_dash_app()
redirect("/dash")
> AssertionError: A name collision occurred between blueprints
> <flask.blueprints.Blueprint object at 0x11905bcd0> and
> <flask.blueprints.Blueprint object at 0x118acbad0>. Both share the
> same name "_dash_dash_assets". Blueprints that are created on the fly
> need unique names.
>AssertionError:蓝图之间发生名称冲突
>及
> . 双方都有共同的利益
>同名“\u dash\u dash\u资产”。动态创建的蓝图
>需要唯一的名称。
考虑到我在烧瓶和短跑方面的一点经验,我想我遗漏了一些琐碎的东西。请告诉我您是否需要其他信息
编辑:我找到了一个让我感到羞耻的解决办法
第二次编辑:包括一个回调示例
from flask import Flask, redirect
from multiprocessing import Value
counter = Value('i', 0)
server = Flask(__name__, template_folder="../frontend/templates",
instance_relative_config=True)
@server.route('/filter')
def filter_stuff():
with counter.get_lock():
counter.value += 1
out = counter.value
<some code>
dash_address = "/dash"+str(out)+"/"
create_dash_app(server, dash_address, nodes_cyto, edges_cyto)
redirect(dash_address)
import dash
from dash_core_components import *
from dash.dependencies import Input, Output
def create_dash_app(server, dash_address, nodes_cyto, edges_cyto):
dash_app = dash.Dash(
__name__,
server=server,
url_base_pathname=dash_address,
external_stylesheets=['https://codepen.io/chriddyp/pen/bWLwgP.css']
)
dash_app.config['suppress_callback_exceptions'] = True
dash_app.layout = html.Div([
cyto.Cytoscape(
id='cytoscape_net',
elements=nodes_cyto + edges_cyto,
zoomingEnabled=True,
zoom=0.8,
layout={'name': 'klay'},
style={'width': '80%', 'height': '700px', 'float': 'left'},
stylesheet=my_stylesheet
),
dcc.Tabs([
dcc.Tab(label='Dettaglio Interazioni', style=tab_style, selected_style=tab_selected_style, children=[
dash_table.DataTable(
id='edge-table',
columns=[],
style_header={
'backgroundColor': 'rgb(230, 230, 230)',
'fontWeight': 'bold'
},
fixed_rows={'headers': True},
style_data = {'whiteSpace': 'normal',
'height': 'auto',
'lineHeight': '15px'},
style_data_conditional=[
{
'if': {'row_index': 'odd'},
'backgroundColor': 'rgb(248, 248, 248)'
},
{
'if': {'column_id': 'Info'},
'textAlign': 'right'
}
],
style_cell={
'height': 'auto',
'minWidth': '180px', 'width': '180px', 'maxWidth': '180px',
'whiteSpace': 'normal',
'fontSize':14
},
style_table={'width': '50%',
'overflowY': 'auto',
'overflowX': 'auto'},
data=[])
])
init_callbacks(dash_app)
return dash_app.server
def init_callbacks(app):
@app.callback([Output('edge-table', 'data'),
Output('edge-table', 'columns')],
[Input('cytoscape_net', 'tapEdgeData')])
def populateEdgeTable(data):
json_data = json.loads(json.dumps(data, indent=2))
if data is None:
return [], []
dict_data = dict(json_data)
dict_data_1 = {your_key.replace("_1", ""): dict_data[your_key] for your_key in
[j for j in dict_data.keys() if "_1" in j] + ["tipo_interazione"]}
dict_data_2 = {your_key.replace("_2", ""): dict_data[your_key] for your_key in
[j for j in dict_data.keys() if "_2" in j] + ["tipo_interazione"]}
columns = [{'name': 'Info', 'id': 'Info'},
{'name': 'Source', 'id': 'Source'},
{'name': 'Target', 'id': 'Target'}]
return pd.DataFrame({'Info': list(dict_data_1.keys()),
'Source': list(dict_data_1.values()),
'Target': list(dict_data_2.values())}).to_dict(orient='records'), columns
从烧瓶导入烧瓶,重定向
从多处理导入值
计数器=值('i',0)
server=Flask(_name__,template_folder=“../frontend/templates”,
实例\相对\配置=真)
@server.route(“/filter”)
def filter_stuff():
带计数器。获取锁定()
计数器值+=1
out=计数器值
破折号地址=“/dash”+str(out)+“/”
创建应用程序(服务器、地址、节点、边缘)
重定向(破折号地址)
导入破折号
从dash_核心组件导入*
从dash.dependencies导入输入,输出
def创建破折号应用程序(服务器、破折号地址、节点、边缘):
破折号应用程序=破折号(
__姓名,
服务器=服务器,
url\u base\u pathname=dash\u地址,
外部_样式表=['https://codepen.io/chriddyp/pen/bWLwgP.css']
)
dash_app.config['suppress_callback_exceptions']=True
dash_app.layout=html.Div([
细胞景观(
id='cytoscape\u net',
元素=节点\细胞+边缘\细胞,
zoomingEnabled=True,
缩放=0.8,
布局={'name':'klay'},
样式={'width':'80%,'height':'700px','float':'left'},
样式表=我的样式表
),
dcc.选项卡([
dcc.Tab(label='Dettaglio Interazioni',style=Tab\u style,selected\u style=Tab\u selected\u style,children=[
dash_table.DataTable(
id='edge-table',
列=[],
样式标题={
“背景色”:“rgb(230230230)”,
“fontWeight”:“bold”
},
修复了_行={'headers':True},
style_data={'whiteSpace':'normal',
“高度”:“自动”,
“线宽”:“15px”},
样式\数据\条件=[
{
'if':{'row_index':'odd'},
“背景色”:“rgb(248248248248)”
},
{
'if':{'column_id':'Info'},
“textAlign”:“右”
}
],
花式细胞={
“高度”:“自动”,
“minWidth”:“180px”,“width”:“180px”,“maxWidth”:“180px”,
“空白”:“正常”,
“字体大小”:14
},
样式表={'width':'50%,
“溢出”:“自动”,
'overflowX':'auto'},
数据=[])
])
init_回调(dash_应用程序)
返回dash_应用程序服务器
def init_回调(应用程序):
@app.callback([Output('edge-table','data'),
输出('edge-table','columns')],
[输入('cytoscape_net','tapEdgeData'))
def populateEdgeTable(数据):
json_data=json.loads(json.dumps(data,indent=2))
如果数据为无:
返回[],[]
dict_data=dict(json_数据)
dict_data_1={your_key.replace(“_1”,”):dict_data[your_key]作为您的_key in
[j表示dict_data.keys()中的j,如果j中的“_1”+[“tipo_interazione”]}
dict_data_2={your_key.replace(“_2”,”):dict_data[your_key]用于您的_key in
[j表示dict_data.keys()中的j,如果j中的“_2”+[“tipo_interazione”]}
列=[{'name':'Info','id':'Info'},
{'name':'Source','id':'Source'},
{'name':'Target','id':'Target'}]
返回pd.DataFrame({'Info':list(dict_data_1.keys()),
“源”:列表(dict_data_1.values()),
“目标”:列表(dict_data_2.values())}.to_dict(orient='records'),列
正如你所看到的,我每次都用一个计数器重定向到一个新的页面。我想知道是否有人会在读这篇文章时死去
谢谢
< P>但DASH应用程序可以动态实例化,在我的经验中,这是一个应该避免的设计模式。关于这个问题的具体用例,我会考虑两个主要途径, 将过滤器与Dash应用程序集成 最简单和一致的解决方案是将过滤器作为Dash应用程序本身的一部分。通过这种方法,可以将过滤器值作为状态
参数传递给页面呈现回调,从而将过滤器应用于其他页面。它们可以直接传递(如果没有太多的过滤器)或通过存储
组件聚合。下面是一个代码片段来说明这个概念
@app.callback(Output("store", "data"), [Input("filter{}".format(i), "value") for i in range(100)])
def aggregate_filters(*args):
return list(args)
@app.callback(Output("page", "children"), [Input(...)], [State("store", "data")])
def render_page(*args, filters):
...
将过滤器选择传递到Dash应用程序
如果无法将筛选器页面本身移植到Dash,则可以序列化筛选器