diff --git a/docs/settings.md b/docs/settings.md index b9055a94f..3edf4b3c3 100644 --- a/docs/settings.md +++ b/docs/settings.md @@ -7,6 +7,13 @@ equivalent keyword arguments, eg. `uvicorn.run("example:app", port=5000, reload= Please note that in this case, if you use `reload=True` or `workers=NUM`, you should put `uvicorn.run` into `if __name__ == '__main__'` clause in the main module. +You can also configure Uvicorn using environment variables with the prefix `UVICORN_`. +For example, in case you want to run the app on port `5000`, just set the environment variable `UVICORN_PORT` to `5000`. + +!!! note + CLI options and the arguments for `uvicorn.run()` take precedence over environment variables. + + ## Application * `APP` - The ASGI application to run, in the format `"<module>:<attribute>"`. diff --git a/mkdocs.yml b/mkdocs.yml index 040e8cd0e..ed833a10c 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -29,6 +29,7 @@ nav: - Contributing: "contributing.md" markdown_extensions: + - admonition - codehilite: css_class: highlight - toc: diff --git a/tests/test_cli.py b/tests/test_cli.py index 9255e5424..4df47b495 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -1,4 +1,5 @@ import importlib +import os import platform import sys from pathlib import Path @@ -17,6 +18,10 @@ main = importlib.import_module("uvicorn.main") +class App: + pass + + def test_cli_print_version() -> None: runner = CliRunner() @@ -131,5 +136,26 @@ def test_cli_reloader_incomplete_app_parameter( ) in captured.err -class App: - pass +@pytest.fixture() +def load_env_h11_protocol(): + old_environ = dict(os.environ) + os.environ["UVICORN_HTTP"] = "h11" + yield + os.environ.clear() + os.environ.update(old_environ) + + +def test_env_variables(load_env_h11_protocol: None): + runner = CliRunner(env=os.environ) + with mock.patch.object(main, "run") as mock_run: + runner.invoke(cli, ["tests.test_cli:App"]) + _, kwargs = mock_run.call_args + assert kwargs["http"] == "h11" + + +def test_mistmatch_env_variables(load_env_h11_protocol: None): + runner = CliRunner(env=os.environ) + with mock.patch.object(main, "run") as mock_run: + runner.invoke(cli, ["tests.test_cli:App", "--http=httptools"]) + _, kwargs = mock_run.call_args + assert kwargs["http"] == "httptools" diff --git a/uvicorn/main.py b/uvicorn/main.py index 947a75330..95174d34a 100644 --- a/uvicorn/main.py +++ b/uvicorn/main.py @@ -50,7 +50,7 @@ def print_version(ctx: click.Context, param: click.Parameter, value: bool) -> No ctx.exit() -@click.command() +@click.command(context_settings={"auto_envvar_prefix": "UVICORN"}) @click.argument("app") @click.option( "--host",