From 7b771ac44d3dc5d72120301eb76f4c947da059be Mon Sep 17 00:00:00 2001 From: dajiaohuang Date: Fri, 18 Sep 2026 02:44:59 +0800 Subject: [PATCH] Forward FastAPI reload scope options --- dash/backends/_fastapi.py | 6 +++ .../backend_tests/test_preconfig_backends.py | 50 +++++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/dash/backends/_fastapi.py b/dash/backends/_fastapi.py index daec8fbc8c..b50f0d56ee 100644 --- a/dash/backends/_fastapi.py +++ b/dash/backends/_fastapi.py @@ -463,6 +463,12 @@ def run(self, dash_app: Dash, host, port, debug, **kwargs): # pylint: disable=R ] if kwargs.get("reload"): uvicorn_args.append("--reload") + for directory in kwargs.get("reload_dirs") or []: + uvicorn_args.extend(["--reload-dir", str(directory)]) + for pattern in kwargs.get("reload_excludes") or []: + uvicorn_args.extend(["--reload-exclude", str(pattern)]) + for pattern in kwargs.get("reload_includes") or []: + uvicorn_args.extend(["--reload-include", str(pattern)]) dev_tools = dash_app._dev_tools # pylint: disable=W0212 config = dict( diff --git a/tests/backend_tests/test_preconfig_backends.py b/tests/backend_tests/test_preconfig_backends.py index 2e4b28ea1c..2c492658e4 100644 --- a/tests/backend_tests/test_preconfig_backends.py +++ b/tests/backend_tests/test_preconfig_backends.py @@ -353,3 +353,53 @@ def test_fastapi_catchall_request_context(dash_duo): resp = requests.get(f"{dash_duo.server_url}/some/non-dash/path", timeout=5) assert resp.status_code == 200 + + +def test_fastapi_run_forwards_reload_scope(): + """Forward reload include, exclude, and directory options to uvicorn.""" + import inspect + import os + from types import SimpleNamespace + from unittest.mock import patch + from fastapi import FastAPI + from dash.backends._fastapi import FastAPIDashServer + + server = FastAPIDashServer(FastAPI()) + + class DashApp: + _dev_tools = {} + + app = DashApp() + caller_frame = inspect.currentframe() + stack_frame = SimpleNamespace( + filename=os.path.join(os.getcwd(), "tests", "backend_tests", "test.py"), + frame=caller_frame, + ) + + with patch("dash.backends._fastapi.subprocess.Popen") as popen, patch( + "dash.backends._fastapi.inspect.stack", return_value=[None, None, stack_frame] + ): + server.run( + dash_app=app, + host="127.0.0.1", + port=8050, + debug=False, + reload=True, + reload_dirs=["app", "src"], + reload_excludes=["tests/*"], + reload_includes=["*.py"], + ) + + args = popen.call_args.args[0] + assert args[-9:] == [ + "--reload", + "--reload-dir", + "app", + "--reload-dir", + "src", + "--reload-exclude", + "tests/*", + "--reload-include", + "*.py", + ] + popen.return_value.wait.assert_called_once_with()