Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Missing the fields from Response #98

Open
Sanchoyzer opened this issue Aug 2, 2020 · 0 comments
Open

Missing the fields from Response #98

Sanchoyzer opened this issue Aug 2, 2020 · 0 comments

Comments

@Sanchoyzer
Copy link

Some fields are missing from __apispec__["responses"]

The code for test:

class ResponseSchema(Schema):
    msg = fields.Str()
    data = fields.Dict()


@pytest.fixture()
def aiohttp_app(loop, aiohttp_client, request):

    @response_schema(ResponseSchema, 200, description="GET")
    async def handler_get(request):
        return web.json_response({"msg": "done", "data": {}})

    app = web.Application()
    setup_aiohttp_apispec(app=app)
    app.router.add_routes([web.get("/test", handler_get)])
    app.middlewares.extend([validation_middleware])

    return loop.run_until_complete(aiohttp_client(app))


async def test_response_200_get(aiohttp_app):
    res = await aiohttp_app.get("/test", params={"id": 1, "name": "max"})
    assert res.status == 200

Let's add some code to show the trouble.
aiohttp_apispec.py

    def _register_route(
        self, route: web.AbstractRoute, method: str, view: _AiohttpView
    ):

        if not hasattr(view, "__apispec__"):
            return None

        # --- start adding ---
        print(route.__dict__)
        print(view.__apispec__["responses"], '\n')
        # --- end adding ---

        url_path = get_path(route)
        ...

middlewares.py

@web.middleware
async def validation_middleware(request: web.Request, handler) -> web.Response:
    orig_handler = request.match_info.handler
    if not hasattr(orig_handler, "__schemas__"):
        ...
        schemas = sub_handler.__schemas__
    else:
        schemas = orig_handler.__schemas__

    # --- start adding ---
    if "responses" in orig_handler.__apispec__:
        for info in orig_handler.__apispec__["responses"].values():
            assert "schema" in info
            assert "description" in info
            assert "required" in info or "name" in info
    # --- end adding ---

    result = {}
    ...

decorators/response.py

def response_schema(schema, code=200, required=False, description=None):
    if callable(schema):
        schema = schema()

    def wrapper(func):
        if not hasattr(func, "__apispec__"):
            func.__apispec__ = {"schemas": [], "responses": {}, "parameters": []}
            func.__schemas__ = []
        func.__apispec__["responses"]["%s" % code] = {
            "schema": schema,
            "required": required,
            "description": description,
            "name": func.__name__,  # --- added ---
        }
        return func

    return wrapper

Let's run the test. Log:

aiohttp_app = <aiohttp.test_utils.TestClient object at 0x7f8257eeb978>

    async def test_response_200_get(aiohttp_app):
        res = await aiohttp_app.get("/test", params={"id": 1, "name": "max"})
>       assert res.status == 200
E       assert 500 == 200
E         +500
E         -200

tests/test_web_app.py:3: AssertionError
---------------------------------------------------------------------- Captured stdout setup -----------------------------------------------------------------------
{'_method': 'HEAD', '_handler': <function aiohttp_app.<locals>.handler_get at 0x7f825ab63158>, '_expect_handler': <function _default_expect_handler at 0x7f8259936378>, '_resource': <PlainResource  /test>}
{'200': {'schema': <ResponseSchema(many=False)>, 'required': False, 'description': 'GET', 'name': 'handler_get'}} 

{'_method': 'GET', '_handler': <function aiohttp_app.<locals>.handler_get at 0x7f825ab63158>, '_expect_handler': <function _default_expect_handler at 0x7f8259936378>, '_resource': <PlainResource  /test>}
{'200': {'schema': <ResponseSchema(many=False)>, 'description': 'GET'}} 

------------------------------------------------------------------------ Captured log call -------------------------------------------------------------------------
ERROR    aiohttp.server:web_protocol.py:355 Error handling request
Traceback (most recent call last):
  ...
  File ".../aiohttp_apispec/middlewares.py", line 38, in validation_middleware
    assert "required" in info or "name" in info
AssertionError

There is no info about 'required' and 'name' in Response for GET. But this info is in Response for HEAD!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant