Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions faust/types/settings/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ def __init__(
canonical_url: URLArg = None,
web: URLArg = None,
web_bind: Optional[str] = None,
web_application_options: typing.Mapping[str, typing.Any] = None,
web_cors_options: typing.Mapping[str, ResourceOptions] = None,
web_enabled: Optional[bool] = None,
web_host: Optional[str] = None,
Expand Down Expand Up @@ -1857,6 +1858,34 @@ def web_bind(self) -> str:
not by passing it as a keyword argument to :class:`app`.
"""

@sections.WebServer.setting(
params.Dict[Any],
version_introduced="0.11.4",
)
def web_application_options(self) -> Mapping[str, Any]:
"""Extra keyword arguments passed to the web framework's application.

Use this to configure the underlying web application object that the
web driver creates. For the default :pypi:`aiohttp` driver these are
forwarded straight to :class:`aiohttp.web.Application`, so you can set
things like ``client_max_size`` or install middlewares:

.. sourcecode:: python

from aiohttp.web import middleware

@middleware
async def error_middleware(request, handler):
...

app = App(..., web_application_options={
'client_max_size': 1024 ** 2 * 20,
'middlewares': [error_middleware],
})

The accepted keys depend on the configured web driver.
"""

@sections.WebServer.setting(
params.Dict[ResourceOptions],
version_introduced="1.5",
Expand Down
4 changes: 3 additions & 1 deletion faust/web/drivers/aiohttp.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,9 @@ class Web(base.Web):

def __init__(self, app: AppT, **kwargs: Any) -> None:
super().__init__(app, **kwargs)
self.web_app: Application = Application()
self.web_app: Application = Application(
**(app.conf.web_application_options or {})
)
self.cors_options = _prepare_cors_options(app.conf.web_cors_options or {})
self._runner: AppRunner = AppRunner(self.web_app, access_log=None)
self._transport_handlers = {
Expand Down
4 changes: 4 additions & 0 deletions tests/functional/test_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -552,6 +552,7 @@ def test_defaults(self):
assert conf.web_bind == "0.0.0.0"
assert conf.web_port == 6066
assert conf.web_transport == Settings.web_transport.default
assert conf.web_application_options is None
assert conf.web_cors_options is None
assert conf.worker_redirect_stdouts
assert conf.worker_redirect_stdouts_level == "WARN"
Expand Down Expand Up @@ -666,6 +667,7 @@ def assert_config_equivalent(
web_host="localhost",
web_transport="udp://",
web_in_thread=True,
web_application_options={"client_max_size": 1024}, # noqa: B006
web_cors_options={ # noqa: B006
"http://example.com": ResourceOptions( # noqa: B008
allow_credentials=True,
Expand Down Expand Up @@ -742,6 +744,7 @@ def assert_config_equivalent(
web_host=web_host,
web_transport=web_transport,
web_in_thread=web_in_thread,
web_application_options=web_application_options,
web_cors_options=web_cors_options,
worker_redirect_stdouts=worker_redirect_stdouts,
worker_redirect_stdouts_level=worker_redirect_stdouts_level,
Expand Down Expand Up @@ -806,6 +809,7 @@ def assert_config_equivalent(
assert conf.web_port == web_port
assert conf.web_host == web_host
assert conf.web_transport == URL(web_transport)
assert conf.web_application_options == web_application_options
assert conf.web_cors_options == web_cors_options
assert conf.worker_redirect_stdouts == worker_redirect_stdouts
assert conf.worker_redirect_stdouts_level == worker_redirect_stdouts_level
Expand Down
20 changes: 20 additions & 0 deletions tests/unit/web/drivers/test_aiohttp.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
NON_OPTIONS_METHODS,
Server,
ServerThread,
Web,
_prepare_cors_options,
)
from tests.helpers import AsyncMock
Expand Down Expand Up @@ -127,6 +128,25 @@ async def test_on_stop(self, *, server, web):


class Test_Web:
@pytest.mark.conf(web_application_options={"client_max_size": 1234})
def test_web_application_options(self, *, app):
# web_application_options are forwarded to aiohttp.web.Application.
# See issue #551.
with (
patch("faust.web.drivers.aiohttp.Application") as Application,
patch("faust.web.drivers.aiohttp.AppRunner"),
):
Web(app)
Application.assert_called_once_with(client_max_size=1234)

def test_web_application_options__default(self, *, app):
with (
patch("faust.web.drivers.aiohttp.Application") as Application,
patch("faust.web.drivers.aiohttp.AppRunner"),
):
Web(app)
Application.assert_called_once_with()

def test_cors(self, *, web):
assert web.cors is web.cors
assert isinstance(web.cors, aiohttp_cors.CorsConfig)
Expand Down
Loading