I'm trying to stop a dash server within a thread, but it doesn't work:
Here's a minor example of the issue :
import threading
import requests
from dash import Dash, html
from flask import Flask, request
import logging
import time
# Setup Logger
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s [%(threadName)s, %(levelname)s] %(message)s",
handlers=[
logging.StreamHandler()
]
)
# Create Flask server and associate it with the Dash app
flask_app = Flask(__name__)
app = Dash(__name__, server=flask_app)
# Define a simple layout
app.layout = html.Div(children=[
html.H1(children='Hello Dash'),
html.P(children='This is a simple Dash app for testing.'),
html.Button('Click Me', id='button')
])
# Define a shutdown route
@app.server.route('/shutdown', methods=['POST'])
def shutdown():
shutdown_server = request.environ.get('werkzeug.server.shutdown')
if shutdown_server is None:
raise RuntimeError('Not running with the Werkzeug Server')
shutdown_server()
return 'Server shutting down...'
# Function to run the server
def run_server():
logging.info("Starting Dash server")
app.run_server(debug=True, use_reloader=False)
# Function to stop the server
def stop_server():
logging.info("Sending shutdown request")
try:
requests.post('http://127.0.0.1:8050/shutdown')
except requests.RequestException as e:
logging.error(f"Error sending shutdown request: {e}")
logging.info("Joining server thread")
server_thread.join()
# Start the server in a new thread
server_thread = threading.Thread(target=run_server)
server_thread.start()
# Start the server, wait a few seconds, then stop it
time.sleep(5)
stop_server()
logging.info("Server stopped")
When I run this script, the program hangs at server_thread.join() and does not exit. Using kill pid is not practical for me because I am running my program within a GUI application. Killing the pid would destroy the gui as well.
How about starting flask_app as a separate process instead of a thread. And then kill this process using pid.
from dash import Dash, html
from flask import Flask, request
import logging
import time
from multiprocessing import Process, current_process
import os
# Setup Logger
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s [%(threadName)s, %(levelname)s] %(message)s",
handlers=[
logging.StreamHandler()
]
)
# Create Flask server and associate it with the Dash app
flask_app = Flask(__name__)
app = Dash(__name__, server=flask_app)
# Define a simple layout
app.layout = html.Div(children=[
html.H1(children='Hello Dash'),
html.P(children='This is a simple Dash app for testing.'),
html.Button('Click Me', id='button')
])
# Define a shutdown route
@app.server.route('/shutdown', methods=['POST'])
def shutdown():
proc = current_process()
# Function to run the server
def run_server():
logging.info("Starting Dash server")
app.run_server(debug=True, use_reloader=False)
# Function to stop the server
def stop_server(pid):
logging.info("Sending shutdown request")
os.kill(pid, 9)
# requests.post('http://127.0.0.1:8050/shutdown')
if __name__ == '__main__':
# Start the server in a new thread
server_proc = Process(target=run_server,
name='dash_server',
daemon=True)
server_proc.start()
pid = server_proc.pid
# Start the server, wait a few seconds, then stop it
time.sleep(5)
stop_server(pid)
logging.info("Server stopped")
time.sleep(30)
To kill process on Windows try replacing with this lines:
import signal
os.kill(pid, signal.CTRL_C_EVENT)
# or signal.CTRL_BREAK_EVENT