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!
Some fields are missing from
__apispec__["responses"]The code for test:
Let's add some code to show the trouble.
aiohttp_apispec.py
middlewares.py
decorators/response.py
Let's run the test. Log:
There is no info about 'required' and 'name' in Response for GET. But this info is in Response for HEAD!