diff --git a/src/fastapi_cli/cli.py b/src/fastapi_cli/cli.py index 28afa297..5b0daeea 100644 --- a/src/fastapi_cli/cli.py +++ b/src/fastapi_cli/cli.py @@ -100,6 +100,7 @@ def _run( entrypoint: Union[str, None] = None, proxy_headers: bool = False, forwarded_allow_ips: Union[str, None] = None, + log_config: Union[Path, None] = None, ) -> None: with get_rich_toolkit() as toolkit: server_type = "development" if command == "dev" else "production" @@ -186,7 +187,7 @@ def _run( root_path=root_path, proxy_headers=proxy_headers, forwarded_allow_ips=forwarded_allow_ips, - log_config=get_uvicorn_log_config(), + log_config=get_uvicorn_log_config() if not log_config else str(log_config), ) @@ -250,6 +251,12 @@ def dev( help="Comma separated list of IP Addresses to trust with proxy headers. The literal '*' means trust everything." ), ] = None, + log_config: Annotated[ + Union[Path, None], + typer.Option( + help="Logging configuration file. Supported formats: .ini, .json, .yaml. be tried." + ), + ] = None, ) -> Any: """ Run a [bold]FastAPI[/bold] app in [yellow]development[/yellow] mode. ๐Ÿงช @@ -287,6 +294,7 @@ def dev( command="dev", proxy_headers=proxy_headers, forwarded_allow_ips=forwarded_allow_ips, + log_config=log_config, ) @@ -356,6 +364,12 @@ def run( help="Comma separated list of IP Addresses to trust with proxy headers. The literal '*' means trust everything." ), ] = None, + log_config: Annotated[ + Union[Path, None], + typer.Option( + help="Logging configuration file. Supported formats: .ini, .json, .yaml." + ), + ] = None, ) -> Any: """ Run a [bold]FastAPI[/bold] app in [green]production[/green] mode. ๐Ÿš€ @@ -394,6 +408,7 @@ def run( command="run", proxy_headers=proxy_headers, forwarded_allow_ips=forwarded_allow_ips, + log_config=log_config, ) diff --git a/tests/assets/log_config.yaml b/tests/assets/log_config.yaml new file mode 100644 index 00000000..1678d761 --- /dev/null +++ b/tests/assets/log_config.yaml @@ -0,0 +1,34 @@ +version: 1 +disable_existing_loggers: False +formatters: + default: + # "()": uvicorn.logging.DefaultFormatter + format: '%(asctime)s - %(name)s - %(levelname)s - %(message)s' + access: + # "()": uvicorn.logging.AccessFormatter + format: '%(asctime)s - %(name)s - %(levelname)s - %(message)s' +handlers: + default: + formatter: default + class: logging.StreamHandler + stream: ext://sys.stderr + access: + formatter: access + class: logging.StreamHandler + stream: ext://sys.stdout +loggers: + uvicorn.error: + level: DEBUG + handlers: + - default + propagate: no + uvicorn.access: + level: DEBUG + handlers: + - access + propagate: no +root: + level: INFO + handlers: + - default + propagate: no diff --git a/tests/test_cli.py b/tests/test_cli.py index b87a811a..5bec0879 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -96,6 +96,8 @@ def test_dev_args() -> None: "--app", "api", "--no-proxy-headers", + "--log-config", + "log_config.yaml", ], ) assert result.exit_code == 0, result.output @@ -110,7 +112,7 @@ def test_dev_args() -> None: "root_path": "/api", "proxy_headers": False, "forwarded_allow_ips": None, - "log_config": get_uvicorn_log_config(), + "log_config": "log_config.yaml", } assert "Using import string: single_file_app:api" in result.output assert "Starting development server ๐Ÿš€" in result.output @@ -263,6 +265,8 @@ def test_run_args() -> None: "--app", "api", "--no-proxy-headers", + "--log-config", + "log_config.yaml", ], ) assert result.exit_code == 0, result.output @@ -277,7 +281,7 @@ def test_run_args() -> None: "root_path": "/api", "proxy_headers": False, "forwarded_allow_ips": None, - "log_config": get_uvicorn_log_config(), + "log_config": "log_config.yaml", } assert "Using import string: single_file_app:api" in result.output @@ -375,6 +379,10 @@ def test_dev_help() -> None: assert "The root path is used to tell your app" in result.output assert "The name of the variable that contains the FastAPI app" in result.output assert "Use multiple worker processes." not in result.output + assert ( + "Logging configuration file. Supported formats: .ini, .json, .yaml." + in result.output + ) def test_run_help() -> None: @@ -396,6 +404,10 @@ def test_run_help() -> None: assert "The root path is used to tell your app" in result.output assert "The name of the variable that contains the FastAPI app" in result.output assert "Use multiple worker processes." in result.output + assert ( + "Logging configuration file. Supported formats: .ini, .json, .yaml." + in result.output + ) def test_callback_help() -> None: