如何使用线程和 debug=True 运行 Dash 应用程序?

问题描述 投票:0回答:1

此演示应用程序使用 Plotly / Dash 用户界面运行 python 进程。当使用

app.run_server(debug=True)
启动 Dash 时,会出现以下错误:

Exception in thread Thread-1 (dashfun):
Traceback (most recent call last):
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/threading.py", line 1016, in _bootstrap_inner
    self.run()

. . . some more source files threading --> dash --> flask --> werkzeug . . .

  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/signal.py", line 56, in signal
    handler = _signal.signal(_enum_to_int(signalnum), _enum_to_int(handler))
ValueError: signal only works in main thread of the main interpreter

程序启动两个线程,一个运行 Dash,另一个执行实际工作。两个队列,一个用于将命令传输到进程,一个用于响应 Dash 查询。

关于如何解决此问题和/或如何将 Dash 用户界面添加到后台运行的程序的建议值得赞赏。

这是程序:

''' Dash in Thread
'''

import time
import queue
import threading
from dash import Dash, html, dcc, callback, Output, Input, State
from dash.exceptions import PreventUpdate

# Make queues
comqueue = queue.Queue() # commands from dash to process
respqueue = queue.Queue() # response from process to dash

# Dash Function
def dashfun(comqueue, respqueue):
    app = Dash('ThreadTest')
    app.layout = html.Div([
        html.H1('Dash Thread Test'),
        dcc.Interval(id='valsinter', interval = 2000, n_intervals=0),
        html.Slot(id='valsout'),
        html.Div(['Set Delta: ',
                  dcc.Input(id='deltain', type='number', value = 0.0, debounce=True),
                  html.Slot(id='dump')])
    ])

    @callback(
        Output('valsout','children'),
        Input('valsinter','n_intervals'),
        State('valsout','children')
        )
    def update_value(n,value):
        print('Update_Value ' + repr(value))
        try:
            # WARNING: This won't work if more than one dash is open
            resp = respqueue.get(timeout = 0.01)
            print('dash - got resp = '+resp)
        except queue.Empty:
            resp = None
        if resp:
            value = 'Value = %.2f' % float(resp.strip())
        return value

    @callback(
        Output('dump','children'),
        Input('deltain','value')
        )
    def new_delta(delta):
        print('New Delta: ' + repr(delta))
        comqueue.put('%.2f' % delta)
        raise PreventUpdate
        return repr(delta)
    
    app.run_server(debug=True) # Debug doesn't seem to be working :-\

# Process function
def profun(comqueue, respqueue):
    value = 0.0
    delta = 0.1
    while True:
        # Check for new delta in command queue
        try:
            resp = comqueue.get(timeout = 0.01)
            print('process - got command = '+resp)
        except queue.Empty:
            resp = None
        if resp:
            delta = float(resp.strip())
        # Update value, print and send to response queue
        value += delta
        print('Val = %.1f' % value )
        respqueue.put('%.2f' % value)
        time.sleep(4.0)

# Start threads
dthread = threading.Thread(target = dashfun, args = (comqueue, respqueue))
pthread = threading.Thread(target = profun, args = (comqueue, respqueue))

dthread.start()
pthread.start()

该程序在

app.run_server(debug=False)
下大部分运行良好。但是当客户端连接时它仍然会引发错误:

Error importing optional module IPython.core.display
Traceback (most recent call last):
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/_plotly_utils/optional_imports.py", line 30, in get_module
    return import_module(name)

. . . importlib --> IPython --> futures . . .

  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/threading.py", line 1504, in _register_atexit
    raise RuntimeError("can't register atexit after shutdown")
RuntimeError: can't register atexit after shutdown

目标是在 Dash

debug=True
模式下无错误运行,并且 Dash 在线程中运行。

在主线程中运行

dashfun(comqueue,respqueue)
时(而不是为 Dash 使用第二个线程),它似乎无需
debug=True
即可工作。主线程中的
debug=True
dashfun()
似乎有两个 pthreads 同时运行。

python python-3.x multithreading plotly-dash python-multithreading
1个回答
0
投票
github上的

Sanskar Biswal回答了问题plotly/dash-core-components/issues/952#issuecomment-2015163046

引用他的话:

尝试使用以下方法

app.run_server(debug=True, use_reloader=False)

© www.soinside.com 2019 - 2024. All rights reserved.