Skip to content

Commit 93063dd

Browse files
authored
Merge pull request #3987 from dajiaohuang/fix/3962-forward-fastapi-reload-options
Forward FastAPI reload scope options
2 parents 9c56933 + 1afde44 commit 93063dd

3 files changed

Lines changed: 57 additions & 0 deletions

File tree

‎CHANGELOG.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ This project adheres to [Semantic Versioning](https://semver.org/).
2020
- [#3646](https://github.com/plotly/dash/pull/3646) Remove React 16 support (`16.14.0` is no longer an accepted value for `REACT_VERSION` / `_set_react_version`).
2121

2222
### Changed
23+
- [#3987](https://github.com/plotly/dash/pull/3987) Forward FastAPI reload scope options (`reload_dirs`, `reload_excludes`, and `reload_includes`) to Uvicorn when reloading.
2324
- [#3986](https://github.com/plotly/dash/pull/3986) Adjust `_run_before_hooks` in the `fastapi` backend to honor a response returned by a `before_request` function, matching the `flask` backend's behavior.
2425

2526
### Fixed

‎dash/backends/_fastapi.py‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -508,6 +508,12 @@ def run(self, dash_app: Dash, host, port, debug, **kwargs): # pylint: disable=R
508508
]
509509
if kwargs.get("reload"):
510510
uvicorn_args.append("--reload")
511+
for directory in kwargs.get("reload_dirs") or []:
512+
uvicorn_args.extend(["--reload-dir", str(directory)])
513+
for pattern in kwargs.get("reload_excludes") or []:
514+
uvicorn_args.extend(["--reload-exclude", str(pattern)])
515+
for pattern in kwargs.get("reload_includes") or []:
516+
uvicorn_args.extend(["--reload-include", str(pattern)])
511517

512518
dev_tools = dash_app._dev_tools # pylint: disable=W0212
513519
config = dict(

‎tests/backend_tests/test_preconfig_backends.py‎

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,3 +353,53 @@ def test_fastapi_catchall_request_context(dash_duo):
353353

354354
resp = requests.get(f"{dash_duo.server_url}/some/non-dash/path", timeout=5)
355355
assert resp.status_code == 200
356+
357+
358+
def test_fastapi_run_forwards_reload_scope():
359+
"""Forward reload include, exclude, and directory options to uvicorn."""
360+
import inspect
361+
import os
362+
from types import SimpleNamespace
363+
from unittest.mock import patch
364+
from fastapi import FastAPI
365+
from dash.backends._fastapi import FastAPIDashServer
366+
367+
server = FastAPIDashServer(FastAPI())
368+
369+
class DashApp:
370+
_dev_tools = {}
371+
372+
app = DashApp()
373+
caller_frame = inspect.currentframe()
374+
stack_frame = SimpleNamespace(
375+
filename=os.path.join(os.getcwd(), "tests", "backend_tests", "test.py"),
376+
frame=caller_frame,
377+
)
378+
379+
with patch("dash.backends._fastapi.subprocess.Popen") as popen, patch(
380+
"dash.backends._fastapi.inspect.stack", return_value=[None, None, stack_frame]
381+
):
382+
server.run(
383+
dash_app=app,
384+
host="127.0.0.1",
385+
port=8050,
386+
debug=False,
387+
reload=True,
388+
reload_dirs=["app", "src"],
389+
reload_excludes=["tests/*"],
390+
reload_includes=["*.py"],
391+
)
392+
393+
args = popen.call_args.args[0]
394+
assert args[-9:] == [
395+
"--reload",
396+
"--reload-dir",
397+
"app",
398+
"--reload-dir",
399+
"src",
400+
"--reload-exclude",
401+
"tests/*",
402+
"--reload-include",
403+
"*.py",
404+
]
405+
popen.return_value.wait.assert_called_once_with()

0 commit comments

Comments
 (0)