spec-first / connexion

Connexion is a modern Python web framework that makes spec-first and api-first development easy.
https://connexion.readthedocs.io/en/latest/
Apache License 2.0
4.48k stars 762 forks source link

MethodViewResolver not work with AioHTTP #1128

Closed spinenkoia closed 2 years ago

spinenkoia commented 4 years ago

Description

Tried using aiohttp.web.View with MethodViewResolver, as in the example, but there is Flask (https://github.com/zalando/connexion/tree/master/examples/openapi3/methodresolver). Maybe I'm doing something wrong ?

Expected behaviour

The app started

Actual behaviour

Getting an error

ERROR:connexion.apis.abstract:Failed to add operation for GET /v1.0/pets
Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/connexion/apis/abstract.py", line 209, in add_paths
    self.add_operation(path, method)
  File "/usr/local/lib/python3.7/site-packages/connexion/apis/abstract.py", line 173, in add_operation
    pass_context_arg_name=self.pass_context_arg_name
  File "/usr/local/lib/python3.7/site-packages/connexion/operations/__init__.py", line 8, in make_operation
    return spec.operation_cls.from_spec(spec, *args, **kwargs)
  File "/usr/local/lib/python3.7/site-packages/connexion/operations/openapi.py", line 138, in from_spec
    **kwargs
  File "/usr/local/lib/python3.7/site-packages/connexion/operations/openapi.py", line 89, in __init__
    pass_context_arg_name=pass_context_arg_name
  File "/usr/local/lib/python3.7/site-packages/connexion/operations/abstract.py", line 96, in __init__
    self._resolution = resolver.resolve(self)
  File "/usr/local/lib/python3.7/site-packages/connexion/resolver.py", line 40, in resolve
    return Resolution(self.resolve_function_from_operation_id(operation_id), operation_id)
  File "/usr/local/lib/python3.7/site-packages/connexion/resolver.py", line 183, in resolve_function_from_operation_id
    view = view_cls()
TypeError: __init__() missing 1 required positional argument: 'request'

Steps to reproduce

Take an example https://github.com/zalando/connexion/tree/master/examples/openapi3/methodresolver, replace the Flask with AioHTTP

Additional info:

Output of the commands:

spinenkoia commented 4 years ago

This is because aiohttp creates a View for each request, and Flask when the application is initialized

dtkav commented 4 years ago

I wasn't able to reproduce this.

I took the methodresolver example as you suggested, replaced FlaskApp with AioHttpApp and it started and accepted requests from httpie.

spinenkoia commented 4 years ago

@dtkav Good day, I'm sorry, here is the repository with the error reproduced https://github.com/spinenkoia/connexion_aiohttp

dtkav commented 4 years ago

Thanks for the more complete example. You don't need to inherit aiohttp.web.View.

The following works for me:

from connexion import NoContent

class PetsView(object):
    method_decorators = []
    pets = {}

    async def search(self):
        return NoContent, 204
spinenkoia commented 4 years ago

Thanks for the more complete example. You don't need to inherit aiohttp.web.View.

The following works for me:

from connexion import NoContent

class PetsView(object):
    method_decorators = []
    pets = {}

    async def search(self):
        return NoContent, 204

This way you will just get a class with the get method. Here is the recommended method https://docs.aiohttp.org/en/stable/web_quickstart.html#class-based-views. There we lose self.request for example. And since aiohttp initializes this class not once but at each request and it turns out that connexion/resolver.py initializes it early

spinenkoia commented 4 years ago

@dtkav ?

spinenkoia commented 4 years ago

@jmcs please take a look

RobbeSneyders commented 2 years ago

Outdated since #1491