From 7b771ac44d3dc5d72120301eb76f4c947da059be Mon Sep 17 00:00:00 2001 From: dajiaohuang Date: Fri, 18 Sep 2026 02:44:59 +0800 Subject: [PATCH 1/2] 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() From 89563d048195a77fff45d3ca0ede34191d6c7e8b Mon Sep 17 00:00:00 2001 From: dajiaohuang Date: Thu, 24 Sep 2026 13:16:27 +0800 Subject: [PATCH 2/2] docs: add FastAPI reload scope changelog entry --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c26ffcade3..7f2b20fbe7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -42,6 +42,7 @@ This project adheres to [Semantic Versioning](https://semver.org/). - [#3948](https://github.com/plotly/dash/issues/3948) Fix page getting progressively slower as callbacks append children ### Changed +- [#3987](https://github.com/plotly/dash/pull/3987) Forward FastAPI reload scope options (`reload_dirs`, `reload_excludes`, and `reload_includes`) to Uvicorn when reloading. - [#3986](https://github.com/plotly/dash/pull/3986) Adjusted the `_run_before_hooks` inf `fastapi` backend to allow for a return value in the event that a `before_request` function returns a response. This is more aligned with how the `before_request` hooks work in the `flask` backend. ## [4.4.1] - 2026-07-21