Skip to content

Commit edb6454

Browse files
authored
Allow app-dir parameter on the run() function (#1271)
* Allow app-dir parameter on the run() function * Add default value to pop() call * Update GitHub templates with new forms * Add test
1 parent 9c1b88c commit edb6454

File tree

2 files changed

+28
-3
lines changed

2 files changed

+28
-3
lines changed

tests/test_cli.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import platform
44
import sys
55
from pathlib import Path
6+
from textwrap import dedent
67
from unittest import mock
78

89
import pytest
@@ -159,3 +160,25 @@ def test_mistmatch_env_variables(load_env_h11_protocol: None):
159160
runner.invoke(cli, ["tests.test_cli:App", "--http=httptools"])
160161
_, kwargs = mock_run.call_args
161162
assert kwargs["http"] == "httptools"
163+
164+
165+
def test_app_dir(tmp_path: Path, caplog: pytest.LogCaptureFixture) -> None:
166+
app_dir = tmp_path / "dir" / "app_dir"
167+
app_file = app_dir / "main.py"
168+
app_dir.mkdir(parents=True)
169+
app_file.touch()
170+
app_file.write_text(
171+
dedent(
172+
"""
173+
async def app(scope, receive, send):
174+
...
175+
"""
176+
)
177+
)
178+
runner = CliRunner()
179+
with mock.patch.object(Server, "run") as mock_run:
180+
result = runner.invoke(cli, ["main:app", "--app-dir", f"{str(app_dir)}"])
181+
182+
assert result.exit_code == 3
183+
mock_run.assert_called_once()
184+
assert sys.path[0] == str(app_dir)

uvicorn/main.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,6 @@ def print_version(ctx: click.Context, param: click.Parameter, value: bool) -> No
320320
)
321321
@click.option(
322322
"--app-dir",
323-
"app_dir",
324323
default=".",
325324
show_default=True,
326325
help="Look for APP in the specified directory, by adding this to the PYTHONPATH."
@@ -379,8 +378,6 @@ def main(
379378
app_dir: str,
380379
factory: bool,
381380
) -> None:
382-
sys.path.insert(0, app_dir)
383-
384381
kwargs = {
385382
"host": host,
386383
"port": port,
@@ -424,11 +421,16 @@ def main(
424421
"headers": [header.split(":", 1) for header in headers],
425422
"use_colors": use_colors,
426423
"factory": factory,
424+
"app_dir": app_dir,
427425
}
428426
run(app, **kwargs)
429427

430428

431429
def run(app: typing.Union[ASGIApplication, str], **kwargs: typing.Any) -> None:
430+
app_dir = kwargs.pop("app_dir", None)
431+
if app_dir is not None:
432+
sys.path.insert(0, app_dir)
433+
432434
config = Config(app, **kwargs)
433435
server = Server(config=config)
434436

0 commit comments

Comments
 (0)