From d019f2658d9930185225a8b1350a72e719335cc1 Mon Sep 17 00:00:00 2001 From: Saravanan Sathyanandha Date: Wed, 14 Aug 2024 13:30:13 +0100 Subject: [PATCH 1/3] Allow worker kwargs --- uvicorn/config.py | 4 +++- uvicorn/main.py | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/uvicorn/config.py b/uvicorn/config.py index 9aff8c968..e96eedb15 100644 --- a/uvicorn/config.py +++ b/uvicorn/config.py @@ -223,6 +223,7 @@ def __init__( headers: list[tuple[str, str]] | None = None, factory: bool = False, h11_max_incomplete_event_size: int | None = None, + worker_kwargs: dict | None = None, ): self.app = app self.host = host @@ -268,6 +269,7 @@ def __init__( self.encoded_headers: list[tuple[bytes, bytes]] = [] self.factory = factory self.h11_max_incomplete_event_size = h11_max_incomplete_event_size + self.worker_kwargs = worker_kwargs self.loaded = False self.configure_logging() @@ -437,7 +439,7 @@ def load(self) -> None: sys.exit(1) try: - self.loaded_app = self.loaded_app() + self.loaded_app = self.loaded_app(**self.worker_kwargs) except TypeError as exc: if self.factory: logger.error("Error loading ASGI app factory: %s", exc) diff --git a/uvicorn/main.py b/uvicorn/main.py index 4352efbca..718567b49 100644 --- a/uvicorn/main.py +++ b/uvicorn/main.py @@ -507,6 +507,7 @@ def run( app_dir: str | None = None, factory: bool = False, h11_max_incomplete_event_size: int | None = None, + worker_kwargs: dict, ) -> None: if app_dir is not None: sys.path.insert(0, app_dir) @@ -558,6 +559,7 @@ def run( use_colors=use_colors, factory=factory, h11_max_incomplete_event_size=h11_max_incomplete_event_size, + worker_kwargs=worker_kwargs, ) server = Server(config=config) From a0ef8ac902da2dbb476eef68289c42ef7e3050a3 Mon Sep 17 00:00:00 2001 From: Saravanan Sathyanandha Date: Tue, 20 Aug 2024 14:33:14 +0100 Subject: [PATCH 2/3] Add worker kwargs test --- tests/test_config.py | 21 +++++++++++++++++++++ uvicorn/config.py | 2 +- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/tests/test_config.py b/tests/test_config.py index e16cc5d56..a9f5f26df 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -54,6 +54,14 @@ def wsgi_app(environ: Environ, start_response: StartResponse) -> None: pass # pragma: nocover +def asgi_app_factory(**kwargs): + async def app(scope: Scope, receive: ASGIReceiveCallable, send: ASGISendCallable) -> None: + pass # pragma: nocover + + app.worker_kwargs = kwargs + return app + + @pytest.mark.parametrize( "app, expected_should_reload", [(asgi_app, False), ("tests.test_config:asgi_app", True)], @@ -545,3 +553,16 @@ def test_warn_when_using_reload_and_workers(caplog: pytest.LogCaptureFixture) -> Config(app=asgi_app, reload=True, workers=2) assert len(caplog.records) == 1 assert '"workers" flag is ignored when reloading is enabled.' in caplog.records[0].message + + +def test_config_worker_kwargs(): + config = Config( + app="tests.test_config:asgi_app_factory", + worker_kwargs={"alpha": 12, "beta": [3, 4, 5]}, + factory=True, + workers=4, + proxy_headers=False, + ) + config.load() + + assert config.loaded_app.worker_kwargs == {"alpha": 12, "beta": [3, 4, 5]} diff --git a/uvicorn/config.py b/uvicorn/config.py index e96eedb15..6749cf7e2 100644 --- a/uvicorn/config.py +++ b/uvicorn/config.py @@ -269,7 +269,7 @@ def __init__( self.encoded_headers: list[tuple[bytes, bytes]] = [] self.factory = factory self.h11_max_incomplete_event_size = h11_max_incomplete_event_size - self.worker_kwargs = worker_kwargs + self.worker_kwargs = worker_kwargs or {} self.loaded = False self.configure_logging() From 0eaaf06022286dc7a59a0ae58d012267ddadbb86 Mon Sep 17 00:00:00 2001 From: Saravanan Sathyanandha Date: Tue, 20 Aug 2024 14:36:07 +0100 Subject: [PATCH 3/3] Fix optional arg --- tests/test_config.py | 2 +- uvicorn/main.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_config.py b/tests/test_config.py index a9f5f26df..8dddd4e50 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -58,7 +58,7 @@ def asgi_app_factory(**kwargs): async def app(scope: Scope, receive: ASGIReceiveCallable, send: ASGISendCallable) -> None: pass # pragma: nocover - app.worker_kwargs = kwargs + app.worker_kwargs = kwargs # type: ignore return app diff --git a/uvicorn/main.py b/uvicorn/main.py index 718567b49..73feb64b5 100644 --- a/uvicorn/main.py +++ b/uvicorn/main.py @@ -507,7 +507,7 @@ def run( app_dir: str | None = None, factory: bool = False, h11_max_incomplete_event_size: int | None = None, - worker_kwargs: dict, + worker_kwargs: dict | None = None, ) -> None: if app_dir is not None: sys.path.insert(0, app_dir)