Connexion: Unable to pass arguments to aiohttp web.Application()

Created on 8 Sep 2019  路  10Comments  路  Source: zalando/connexion

Description

I'm passing a large payload to one of the api endpoints and getting back an error from aiohttp

<class 'aiohttp.web_exceptions.HTTPRequestEntityTooLarge'>: Request Entity Too Large

But since this is service to service request, I'd like to bypass this limit by passing the documented parameter client_max_size:

web.Application(client_max_size=0)

However, connexion doesn't support passing an app options during initialization:

self.subapp = web.Application(
    middlewares=[
        problems_middleware,
        trailing_slash_redirect
    ]
)

Ref: https://github.com/zalando/connexion/blob/master/connexion/apis/aiohttp_api.py#L97

Expected behavior

Expected to be able to pass app specific configuration, specifically client_max_size

Actual behavior

Unable to configure the aiohttp app

Steps to reproduce

Make a POST request using an aiohttp initialized app and send a json payload that's larger than 1048576 Bytes (1 MB)

Additional info:

Allow users to pass app specific options as a map:

app = connexion.AioHttpApp(
  __name__,
  specification_dir='swagger',
  app_options={...} # or just options if there's no name conflict
)

Output of the commands:

  • python --version
    Python 3.7.3

  • pip show connexion | grep "^Version\:"
    Version: 2018.0.dev1

Most helpful comment

Resolved by #885

All 10 comments

How solve this problem? "web_request.Request" object taking "client_max_size" from web.Application, but it not working with connexion even if i use monkeypatch.

I suspect the options parameter in https://github.com/zalando/connexion/blob/34c7cb1/connexion/apps/aiohttp_app.py#L71 should be passed through to the web.run_app call - this would be consistent with the Flask app in https://github.com/zalando/connexion/blob/b0b83c4/connexion/apps/flask_app.py#L65.

There's some special-casing of the options parameter in the run method which I don't really understand, so I'm not confident submitting a PR.

I've managed to get monkey-patching working with

def run_app(**kwargs: Any) -> None:
    orig_run_app = web.run_app
    with mock.patch("connexion.apps.aiohttp_app.web.run_app") as mock_run_app:
        mock_run_app.side_effect = lambda *connexion_args, **connexion_kwargs: orig_run_app(
            *connexion_args, **{**connexion_kwargs, **kwargs}
        )
        app.run()

but I haven't tested with the client_max_size parameter. Also, this is a pretty nasty workaround!

@daxartio @tomwatson1024 This is my current workaround.

_api = connexion_app.add_api(os.path.join(os.getcwd(), API_SPECS_PATH),
    base_path='/api',
    strict_validation=True,
    pass_context_arg_name='request'
 )
# TODO temp hack to remove limit on request size. connexion does not allow passing of options to web.Application
_api._client_max_size = 0

While this works it's not a long term solution. I'm guessing it's straightforward to add an extra parameter to support supplying options.

@hjacobs Can you review the suggestions above? this is probably straightforward.

@simo-eskalera, its not working :).
I had to create another application and set parametr for AioHttpApp only_one_api=False (P.S. its default value)

For example

app = connexion.AioHttpApp(__name__, specification_dir=f'{BASE_DIR}/spec/', )
api = app.add_api('openapi.yaml',...)
app2 = web.Application(client_max_size=...)
app2.add_routes([web.post('/files', upload)])
app.app.add_subapp('/upload', app2)

Resolved by #885

Thanks @cognifloyd. When will it release?

I do not work for Zalando, and I don't know when the next release will be.

I'll try to cut a new release.

Was this page helpful?
0 / 5 - 0 ratings