aiohttp-apispec
aiohttp-apispec copied to clipboard
Missing the fields from Response
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!