Skip to content

Commit 297c911

Browse files
committed
✨ Add --reload-dir option to dev command
1 parent 403e26f commit 297c911

File tree

2 files changed

+49
-0
lines changed

2 files changed

+49
-0
lines changed

src/fastapi_cli/cli.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ def _run(
9595
host: str = "127.0.0.1",
9696
port: int = 8000,
9797
reload: bool = True,
98+
reload_dirs: Union[List[Path], None] = None,
9899
workers: Union[int, None] = None,
99100
root_path: str = "",
100101
command: str,
@@ -210,6 +211,10 @@ def _run(
210211
host=host,
211212
port=port,
212213
reload=reload,
214+
reload_dirs=(
215+
[str(directory.resolve()) for directory in reload_dirs]
216+
if reload_dirs else None
217+
),
213218
workers=workers,
214219
root_path=root_path,
215220
proxy_headers=proxy_headers,
@@ -246,6 +251,12 @@ def dev(
246251
help="Enable auto-reload of the server when (code) files change. This is [bold]resource intensive[/bold], use it only during development."
247252
),
248253
] = True,
254+
reload_dir: Annotated[
255+
Union[List[Path], None],
256+
typer.Option(
257+
help="Set reload directories explicitly, instead of using the current working directory."
258+
),
259+
] = None,
249260
root_path: Annotated[
250261
str,
251262
typer.Option(
@@ -309,6 +320,7 @@ def dev(
309320
host=host,
310321
port=port,
311322
reload=reload,
323+
reload_dirs=reload_dir,
312324
root_path=root_path,
313325
app=app,
314326
entrypoint=entrypoint,

tests/test_cli.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ def test_dev() -> None:
2727
"host": "127.0.0.1",
2828
"port": 8000,
2929
"reload": True,
30+
"reload_dirs": None,
3031
"workers": None,
3132
"root_path": "",
3233
"proxy_headers": True,
@@ -72,6 +73,7 @@ def test_dev_package() -> None:
7273
"host": "127.0.0.1",
7374
"port": 8000,
7475
"reload": True,
76+
"reload_dirs": None,
7577
"workers": None,
7678
"root_path": "",
7779
"proxy_headers": True,
@@ -121,6 +123,7 @@ def test_dev_args() -> None:
121123
"host": "192.168.0.2",
122124
"port": 8080,
123125
"reload": False,
126+
"reload_dirs": None,
124127
"workers": None,
125128
"root_path": "/api",
126129
"proxy_headers": False,
@@ -151,6 +154,7 @@ def test_dev_env_vars() -> None:
151154
"host": "127.0.0.1",
152155
"port": 8111,
153156
"reload": True,
157+
"reload_dirs": None,
154158
"workers": None,
155159
"root_path": "",
156160
"proxy_headers": True,
@@ -188,6 +192,7 @@ def test_dev_env_vars_and_args() -> None:
188192
"host": "127.0.0.1",
189193
"port": 8080,
190194
"reload": True,
195+
"reload_dirs": None,
191196
"workers": None,
192197
"root_path": "",
193198
"proxy_headers": True,
@@ -233,6 +238,7 @@ def test_run() -> None:
233238
"host": "0.0.0.0",
234239
"port": 8000,
235240
"reload": False,
241+
"reload_dirs": None,
236242
"workers": None,
237243
"root_path": "",
238244
"proxy_headers": True,
@@ -259,6 +265,7 @@ def test_run_trust_proxy() -> None:
259265
"host": "0.0.0.0",
260266
"port": 8000,
261267
"reload": False,
268+
"reload_dirs": None,
262269
"workers": None,
263270
"root_path": "",
264271
"proxy_headers": True,
@@ -305,6 +312,7 @@ def test_run_args() -> None:
305312
"host": "192.168.0.2",
306313
"port": 8080,
307314
"reload": False,
315+
"reload_dirs": None,
308316
"workers": 2,
309317
"root_path": "/api",
310318
"proxy_headers": False,
@@ -336,6 +344,7 @@ def test_run_env_vars() -> None:
336344
"host": "0.0.0.0",
337345
"port": 8111,
338346
"reload": False,
347+
"reload_dirs": None,
339348
"workers": None,
340349
"root_path": "",
341350
"proxy_headers": True,
@@ -369,6 +378,7 @@ def test_run_env_vars_and_args() -> None:
369378
"host": "0.0.0.0",
370379
"port": 8080,
371380
"reload": False,
381+
"reload_dirs": None,
372382
"workers": None,
373383
"root_path": "",
374384
"proxy_headers": True,
@@ -404,6 +414,7 @@ def test_dev_help() -> None:
404414
assert "The host to serve on." in result.output
405415
assert "The port to serve on." in result.output
406416
assert "Enable auto-reload of the server when (code) files change." in result.output
417+
assert "Set reload directories explicitly" in result.output
407418
assert "The root path is used to tell your app" in result.output
408419
assert "The name of the variable that contains the FastAPI app" in result.output
409420
assert "Use multiple worker processes." not in result.output
@@ -443,6 +454,30 @@ def test_version() -> None:
443454
assert "FastAPI CLI version:" in result.output
444455

445456

457+
def test_dev_reload_dir() -> None:
458+
with changing_dir(assets_path):
459+
with patch.object(uvicorn, "run") as mock_run:
460+
result = runner.invoke(
461+
app,
462+
[
463+
"dev",
464+
"single_file_app.py",
465+
"--reload-dir",
466+
"src",
467+
"--reload-dir",
468+
"lib",
469+
],
470+
)
471+
assert result.exit_code == 0, result.output
472+
assert mock_run.called
473+
assert mock_run.call_args
474+
# Paths are resolved to absolute paths
475+
reload_dirs = mock_run.call_args.kwargs["reload_dirs"]
476+
assert len(reload_dirs) == 2
477+
assert reload_dirs[0] == str((assets_path / "src").resolve())
478+
assert reload_dirs[1] == str((assets_path / "lib").resolve())
479+
480+
446481
def test_dev_with_import_string() -> None:
447482
with changing_dir(assets_path):
448483
with patch.object(uvicorn, "run") as mock_run:
@@ -456,6 +491,7 @@ def test_dev_with_import_string() -> None:
456491
"host": "127.0.0.1",
457492
"port": 8000,
458493
"reload": True,
494+
"reload_dirs": None,
459495
"workers": None,
460496
"root_path": "",
461497
"proxy_headers": True,
@@ -477,6 +513,7 @@ def test_run_with_import_string() -> None:
477513
"host": "0.0.0.0",
478514
"port": 8000,
479515
"reload": False,
516+
"reload_dirs": None,
480517
"workers": None,
481518
"root_path": "",
482519
"proxy_headers": True,

0 commit comments

Comments
 (0)