- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在使用 Dash 2.0,我有 interval.py
内apps
文件夹:
import numpy as np
import dash
import pandas as pd
import plotly.express as px
from dash.dependencies import Output, Input
from dash import dcc
from dash import html
external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
app = dash.Dash(__name__, external_stylesheets=external_stylesheets) # call flask server
app.layout = html.Div(className='row', children=[
html.Div(children=[dcc.Graph(id='a-graph', style={'display': 'flex'}),
dcc.Graph(id='b-graph', style={'display': 'flex'}),
dcc.Interval(id='interval-component', interval=1000)])])
@app.callback(
[
Output('a-graph', 'figure'),
Output('b-graph', 'figure')
],
[
Input('interval-component', 'n_intervals')
]
)
def update_graphs(n):
print(f'callback happened: {n}')
df = pd.DataFrame({"time":pd.Series(pd.date_range("1-nov-2021","2-nov-2021", freq="S")).sample(30), "bacteria_count":np.random.randint(0,500, 30), "bacteria_type":np.random.choice(list("AB"),30)})
df["epoch_time_ms"] = df["time"].astype(int) / 1000
df = df.sort_values("time")
a_fig = px.line(df, x="time", y="bacteria_count", line_shape="hv", markers=True, color='bacteria_type')
a_fig.update_traces(mode="markers+lines", hovertemplate=None)
a_fig.update_layout(hovermode='x unified')
b_fig = px.line(df, x="epoch_time_ms", y="bacteria_count", line_shape="hv", markers=True, color='bacteria_type')
b_fig.update_traces(mode="markers+lines", hovertemplate=None)
b_fig.update_layout(hovermode='x unified')
return a_fig, b_fig
if __name__ == '__main__':
app.run_server(debug=True)
update_graphs()
如果我运行
python3 interval.py
,就会按预期定期调用.
index.py
):
from dash import dcc
from dash import html
from dash.dependencies import Input, Output
from app import app
from apps import interval
app.layout = html.Div([
# represents the URL bar, doesn't render anything
dcc.Location(id='url', refresh=False),
dcc.Link('Top | ', href='/'),
dcc.Link('Interval | ', href='/apps/interval'),
# content will be rendered in this element
html.Div(id='page-content')
])
server = app.server
@app.callback(Output('page-content', 'children'),
Input('url', 'pathname'))
def display_page(pathname):
if pathname == '/apps/interval':
return interval.app.layout
else:
return ''
if __name__ == '__main__':
app.run_server(debug=True)
和
app.py
:
import dash
app = dash.Dash(__name__, suppress_callback_exceptions=True)
server = app.server
然后我开始使用
gunicorn index:server -b :8086
.即使我加载了间隔页面,它也开始没有任何错误。但是,回调永远不会被调用。
app = dash.Dash(__name__, external_stylesheets=...)
在
interval.py
与从应用程序导入应用程序。一旦我点击
/apps/interval
索引页上的链接,进入无限循环 -- 继续打印
Top | Interval
在我的浏览器上。
最佳答案
使用 gunicorn
部署 Dash 应用程序与破折号 dcc.Interval
† 以及 dcc.Location
⁂(即多页应用程序)功能存在*
* Refs to Dash Docs for mentioned components:
†
Interval
dcc (dash core components) components allow for auto source data updating (and thus auto-updates for certain components on a page) at specified intervals.⁂
Location
dcc components allow for access to the current href/pathname/URL and thus enabling of multi-page Dash apps.
max_intervals=5
为
dcc.Interval
组件,否则它只会无休止地更新图形(也许这就是您想要的行为,但是,设置此限制只会有助于简化此演示)。
.
|-- app
| |-- __init__.py
| |-- gunicorn
| | `-- logs
| | `-- 20211101
| | `-- 20211101.access.log
| `-- interval.py
|-- index.py
`-- launch_gunicorn.sh
4 directories, 5 files
坚持使用您最关注的方法,即本质上将布局、回调和应用程序都声明在一个文件中——“
interval.py
”。然后,只有一个额外的 Python 文件“
index.py
”(再次与您的帖子保持一致)控制应用程序的多页面布局处理,也是
gunicorn
来自的文件。将获得对 Dash 应用程序对象(特别是应用程序的服务器子属性;即,在这种情况下,即
app.interval.app.server
)的所需引用。最后,我创建了另外三分之一的额外文件,它只是一个 bash
launch_gunicorn.sh
有助于执行应用程序的非开发/调试(即生产 [虽然可能也想添加 nginx 但这是另一个问题])部署的 shell 脚本。
app/interval.py
import dash
import numpy as np
import pandas as pd
import plotly.express as px
from dash import dcc
from dash import html
from dash.dependencies import Input
from dash.dependencies import Output
external_stylesheets = ["https://codepen.io/chriddyp/pen/bWLwgP.css"]
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
interval_layout = html.Div(
className="row",
children=[
html.Div(
children=[
html.Div(id="interval-update"),
dcc.Graph(id="a-graph", style={"display": "flex"}),
dcc.Graph(id="b-graph", style={"display": "flex"}),
dcc.Interval(
id="interval-component", interval=1000, max_intervals=5
),
]
)
],
)
@app.callback(
[
Output("a-graph", "figure"),
Output("b-graph", "figure"),
Output("interval-update", "children"),
],
[Input("interval-component", "n_intervals")],
)
def update_graphs(n):
app.logger.info(f"callback happened: {n}")
df = pd.DataFrame(
{
"time": pd.Series(
pd.date_range("1-nov-2021", "2-nov-2021", freq="S")
).sample(30),
"bacteria_count": np.random.randint(0, 500, 30),
"bacteria_type": np.random.choice(list("AB"), 30),
}
)
df["epoch_time_ms"] = df["time"].astype(int) / 1000
df = df.sort_values("time")
a_fig = px.line(
df,
x="time",
y="bacteria_count",
line_shape="hv",
markers=True,
color="bacteria_type",
)
a_fig.update_traces(mode="markers+lines", hovertemplate=None)
a_fig.update_layout(hovermode="x unified")
b_fig = px.line(
df,
x="epoch_time_ms",
y="bacteria_count",
line_shape="hv",
markers=True,
color="bacteria_type",
)
b_fig.update_traces(mode="markers+lines", hovertemplate=None)
b_fig.update_layout(hovermode="x unified")
interval_update = [html.H1(f"Interval Update - {n}")]
return a_fig, b_fig, interval_update
if __name__ == "__main__":
app.run_server(debug=True)
2)
index.py
""" ## Primary Application Deployment Script
------------------------------------
> 𝕯𝖊𝖕𝖑𝖔𝖞𝖒𝖊𝖓𝖙
_____
ᵂʳⁱᵗᵗᵉⁿ ᵇʸ
[your name]
Purpose / Overview:
------------------
This script serves as the de facto WSGI Production-level deployment module (in this case, fed to Gunicorn).
For Development-level deployment (DEBUG),
simply run this script, like so:
$ python index.py
: : : ::::::: : : :
"""
import logging
from dash import dcc
from dash import html
from dash import no_update
from dash.dependencies import Input
from dash.dependencies import Output
from dash.dependencies import State
from dash.exceptions import PreventUpdate
from app import interval
from app.interval import app
app.layout = html.Div(
[
# represents the URL bar, doesn't render anything
dcc.Location(id="url", refresh=False),
dcc.Link("Top | ", href="/"),
dcc.Link("Interval | ", href="/apps/interval"),
# content will be rendered in this element
html.Div(id="page-content"),
]
)
@app.callback(Output("page-content", "children"), Input("url", "pathname"))
def display_page(pathname):
if pathname == "/apps/interval":
return interval.interval_layout
elif pathname == "/":
return no_update
else:
return html.Div(
[html.H1("404 Page Not Found")],
style={"margin": "10%", "textAlign": "center"},
)
if __name__ == "__main__":
app.run_server(debug=True)
############################################
# # DEPLOY* MODE: PRODUCTION # #
# # [*WSGI import (e.g. Gunicorn+Nginx)] # #
############################################
if __name__ != "__main__":
logger = logging.getLogger(__name__)
logging.getLogger("matplotlib.font_manager").disabled = True
logging.basicConfig(
format="%(asctime)s %(name)-12s %(module)s.%(funcName)s %(processName)s %(levelname)-8s %(relativeCreated)d %(message)s",
level=logging.INFO,
)
gunicorn_logger = logging.getLogger("gunicorn.error")
app.logger.handlers = logger.handlers
app.logger.setLevel(logger.level)
app.logger.info(
"Initializing dash-webapp-template (App) `app.server` for handoff..."
)
server = app.server
3)
launch_gunicorn.sh
#!/bin/bash
# Gunicorn Launch script for Flask-based Dash app,
# ran concurrently, & in parallel.
TODAY=$(date "+%Y%m%d")
TIMESTAMP=$(date | tr -d "[[:punct:]]" | tr -d ' ')
PORT=${1:-9001}
NUM_WORKERS=${2:-4}
THREADS=${3:-8}
GUNICORN_PROD_LOGS="./app/gunicorn/logs/${TODAY}"
mkdir -p $GUNICORN_PROD_LOGS
gunicorn \
-b 0.0.0.0:$PORT \
-w $NUM_WORKERS \
--worker-class gthread \
--threads $THREADS \
--name "dash-webapp-demo${TODAY}" \
--max-requests 100 \
--max-requests-jitter 10 \
--access-logfile "${GUNICORN_PROD_LOGS}/${TODAY}.access.log" \
index:server
通过
Gunicorn 部署应用程序
launch_gunicorn.sh
,您应该会在终端中看到以下输出:
[...]$ ./launch_gunicorn.sh
[2021-11-01 22:51:28 -0700] [23576] [INFO] Starting gunicorn 20.1.0
[2021-11-01 22:51:28 -0700] [23576] [INFO] Listening at: http://0.0.0.0:9001 (23576)
[2021-11-01 22:51:28 -0700] [23576] [INFO] Using worker: gthread
[2021-11-01 22:51:28 -0700] [23580] [INFO] Booting worker with pid: 23580
[2021-11-01 22:51:28 -0700] [23581] [INFO] Booting worker with pid: 23581
[2021-11-01 22:51:28 -0700] [23582] [INFO] Booting worker with pid: 23582
[2021-11-01 22:51:28 -0700] [23583] [INFO] Booting worker with pid: 23583
2021-11-01 22:51:30,464 app.interval index.<module> MainProcess INFO 2686 Initializing dash-webapp-template (App) `app.server` for handoff...
2021-11-01 22:51:30,489 app.interval index.<module> MainProcess INFO 2712 Initializing dash-webapp-template (App) `app.server` for handoff...
2021-11-01 22:51:30,560 app.interval index.<module> MainProcess INFO 2783 Initializing dash-webapp-template (App) `app.server` for handoff...
2021-11-01 22:51:30,621 app.interval index.<module> MainProcess INFO 2844 Initializing dash-webapp-template (App) `app.server` for handoff...
这是因为我已将 worker 数量设置为默认值 4。您可以在
launch_gunicorn.sh
中更改此设置。文件,或者,作为参数传递。如您所见,该脚本接受三个可选参数:分别是端口、工作线程数和线程数。
dcc.Interval
主组件
interval.py
应用程序布局 + 回调(您采用了多合一方法 - 效果很好!)文件。
2021-11-01 23:11:26,140 app.interval interval.update_graphs MainProcess INFO 175805 callback happened: None
2021-11-01 23:11:26,190 numexpr.utils utils._init_num_threads MainProcess INFO 175854 NumExpr defaulting to 4 threads.
2021-11-01 23:11:27,270 app.interval interval.update_graphs MainProcess INFO 176935 callback happened: 1
2021-11-01 23:11:28,131 app.interval interval.update_graphs MainProcess INFO 177796 callback happened: 2
2021-11-01 23:11:29,129 app.interval interval.update_graphs MainProcess INFO 178793 callback happened: 3
2021-11-01 23:11:30,136 app.interval interval.update_graphs MainProcess INFO 179801 callback happened: 4
2021-11-01 23:11:31,133 app.interval interval.update_graphs MainProcess INFO 180797 callback happened: 5
而在
app/gunicorn/logs/[today's date]/[today's date].access.log
文件自动创建,你会发现信息,如:
127.0.0.1 - - [01/Nov/2021:23:08:43 -0700] "GET / HTTP/1.1" 200 1781 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36"
127.0.0.1 - - [01/Nov/2021:23:08:43 -0700] "GET /_dash-layout HTTP/1.1" 200 462 "http://0.0.0.0:9001/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36"
127.0.0.1 - - [01/Nov/2021:23:08:43 -0700] "GET /_dash-dependencies HTTP/1.1" 200 357 "http://0.0.0.0:9001/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36"
127.0.0.1 - - [01/Nov/2021:23:08:44 -0700] "POST /_dash-update-component HTTP/1.1" 204 0 "http://0.0.0.0:9001/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36"
127.0.0.1 - - [01/Nov/2021:23:08:53 -0700] "GET /_dash-component-suites/dash/dcc/dash_core_components-shared.js.map HTTP/1.1" 200 26038 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36"
127.0.0.1 - - [01/Nov/2021:23:08:53 -0700] "GET /_dash-component-suites/dash/html/dash_html_components.min.js.map HTTP/1.1" 200 687871 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36"
127.0.0.1 - - [01/Nov/2021:23:08:53 -0700] "GET /_dash-component-suites/dash/dash_table/bundle.js.map HTTP/1.1" 200 154018 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36"
127.0.0.1 - - [01/Nov/2021:23:08:53 -0700] "GET /_dash-component-suites/dash/dcc/dash_core_components.js.map HTTP/1.1" 200 1996412 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36"
127.0.0.1 - - [01/Nov/2021:23:11:26 -0700] "POST /_dash-update-component HTTP/1.1" 200 651 "http://0.0.0.0:9001/apps/interval" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36"
127.0.0.1 - - [01/Nov/2021:23:11:26 -0700] "GET /_dash-component-suites/dash/dcc/async-graph.js HTTP/1.1" 304 0 "http://0.0.0.0:9001/apps/interval" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36"
127.0.0.1 - - [01/Nov/2021:23:11:26 -0700] "GET /_dash-component-suites/dash/dcc/async-graph.js.map HTTP/1.1" 200 75008 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36"
127.0.0.1 - - [01/Nov/2021:23:11:26 -0700] "GET /_dash-component-suites/dash/dcc/async-plotlyjs.js HTTP/1.1" 200 3594037 "http://0.0.0.0:9001/apps/interval" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36"
127.0.0.1 - - [01/Nov/2021:23:11:27 -0700] "POST /_dash-update-component HTTP/1.1" 200 16924 "http://0.0.0.0:9001/apps/interval" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36"
127.0.0.1 - - [01/Nov/2021:23:11:27 -0700] "POST /_dash-update-component HTTP/1.1" 200 16915 "http://0.0.0.0:9001/apps/interval" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36"
127.0.0.1 - - [01/Nov/2021:23:11:28 -0700] "POST /_dash-update-component HTTP/1.1" 200 16909 "http://0.0.0.0:9001/apps/interval" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36"
127.0.0.1 - - [01/Nov/2021:23:11:29 -0700] "POST /_dash-update-component HTTP/1.1" 200 16911 "http://0.0.0.0:9001/apps/interval" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36"
127.0.0.1 - - [01/Nov/2021:23:11:30 -0700] "POST /_dash-update-component HTTP/1.1" 200 16903 "http://0.0.0.0:9001/apps/interval" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36"
127.0.0.1 - - [01/Nov/2021:23:11:31 -0700] "POST /_dash-update-component HTTP/1.1" 200 16915 "http://0.0.0.0:9001/apps/interval" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36"
显示服务器收到的请求。
htop
并过滤(在这种情况下,我只是过滤了“破折号”,因为在 gunicorn 命令选项中的
launch_gunicorn.sh
文件中,有配置可以为您的 gunicorn 工作进程提供特定名称;见下文)我们可以看到实际的枪械 worker :
关于python - 防止无限回调循环部署带有 Gunicorn 的 Dash 应用程序,其中存在 `dcc.Interval` 和 `dcc.Location`(即多页应用程序)组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69785448/
我正在研究 learnyounode 的 HTTP 客户端作业。 我想知道为什么控制台记录来自response.on(“end”,callback)的数据仅输出预期输出的最后一部分,而控制台记录来自r
我正在尝试创建一个对象列表(在我的示例中为 List),我在其中使用 json 将对象添加到此列表,但该列表仍为空。这是我的代码: public List readCardsFromJson() {
我有一个 JavaScript 函数“print_something”,它在大约 300 个 jsp 帮助页面中实现。我发现这个“print_something”函数必须被纠正。所以我正在寻找一个不更
有 2 个 HTML 下拉列表,一个用于 12 小时时间,一个用于每小时 5 分钟的时间间隔。 .. 1 .. 12 .. 0 .. 55 .. 一直在尝试使用 if/
我有一个 A 类,我打算在它与设备驱动程序交互时将其放入共享库中。 我有一个 B 类,将来可能是 C、D、E...,它将使用共享库中的 A 类。 我想要在类 A 中设置回调函数的功能,以便当特定事件发
我需要能够在处理完 Observable.next() 之后执行回调。 我有一个组件“A”,它有一个主题使用 Subject.next() 发送通知。我有一个组件“B”,它订阅了 Subject.as
我有一张在顶部和底部单元格下方带有阴影的表格(此处使用 Matt Gallagher 的解决方案:http://cocoawithlove.com/2009/08/adding-shadow-effe
有人可以向我解释一下为什么这段代码有效 renderSquare(i) { return ( this.handleClick(i)} /> ); } 但
我可以让两个不同的客户端监听相同的 WCF 回调并让它们都接收相同的数据而不必进行两次处理吗? 最佳答案 不是真的 - 至少不是直接的。你所描述的听起来很像发布/订阅模式。 WCF 服务基本上在任何给
我是 SignalR 的新手,如果这个问题太明显,我深表歉意,但我在文档中找不到任何答案。 这是我的代码。 /*1*/ actions.client.doActionA = function (r
我有这个应用程序,您可以在其中输入一些文本并按下一个按钮,将此文本添加到自定义小部件中。这是代码: import 'dart:core'; import 'package:flutter/materi
我读到当您还想使用模型回调时不能使用 Keras 进行交叉验证,但是 this post表明这毕竟是可能的。但是,我很难将其纳入我的上下文。 为了更详细地探讨这个问题,我正在关注 machinelea
我尝试在重力表单中提交表单失败后运行一些 jQuery 代码,也就是验证发现错误时。 我尝试使用 Ajax:complete 回调,但它根本不触发。 我尝试运行的代码基本上将监听器添加到选择下拉列表中
我有一个 $image,我 .fadeIn 和 .fadeOut,然后 .remove .fadeOut 完成。这是我的代码: $image .fadeIn() .fadeOut(func
我正在处理一个自定义文件路径类,它应该始终执行一个函数 写入相应的系统文件及其文件对象后 关闭。该函数将文件路径的内容上传到远程位置。 我希望上传功能完全在用户的幕后发生 透视,即用户可以像使用其他任
这里是 javascript 新手,所以回调在我的大脑中仍然有点不确定。 我想做的是:给定一个“菜单”,它是一个 objectId 数组,查询与该 objectId 相对应的每个 foodItem,获
我正在学习回调,我编写了以下代码: var http = require('http'); var str = ""; var count = 2; function jugglingAsync(ca
这是我的困境,我有一系列被调用的函数,我正在使用回调函数在它们完成时执行函数。回调返回一个值并且效果也很好,我的问题是当我向回调添加参数时我无法再访问返回值。这是一个有效的例子: function m
This question already has answers here: Explanation of function pointers (4个答案) 上个月关闭。 如何将函数指针作为参数传递
我无法让以下代码工作。假设 ajax 调用有效,并且 msg['username'] 预设为 'john'。我想我对如何将变量传递给回调感到困惑。编辑:我认为我的主要困惑是如何从 Ajax 中获取“m
我是一名优秀的程序员,十分优秀!