From 50baf66d0733edf244e7e6e38f32c95717e00dd4 Mon Sep 17 00:00:00 2001 From: jlintott Date: Tue, 6 Apr 2021 10:11:38 +0100 Subject: [PATCH] Catch route parameter keywords from schema when parsing params --- .gitignore | 3 +++ spectree/utils.py | 57 ++++++++++++++++----------------------------- tests/common.py | 5 ++++ tests/test_utils.py | 47 +++++++++++++++++++++++++++++++++---- 4 files changed, 70 insertions(+), 42 deletions(-) diff --git a/.gitignore b/.gitignore index 894a44cc..8eb14013 100644 --- a/.gitignore +++ b/.gitignore @@ -102,3 +102,6 @@ venv.bak/ # mypy .mypy_cache/ + +# pycharm project files +.idea diff --git a/spectree/utils.py b/spectree/utils.py index 903f5524..67cfb081 100644 --- a/spectree/utils.py +++ b/spectree/utils.py @@ -44,44 +44,27 @@ def parse_params(func, params, models): """ get spec for (query, headers, cookies) """ - if hasattr(func, "query"): - query = models[func.query] - for name, schema in query["properties"].items(): - params.append( - { - "name": name, - "in": "query", - "schema": schema, - "required": name in query.get("required", []), - "description": schema.get("description", ""), + attr_to_spec_key = {"query": "query", "headers": "header", "cookies": "cookie"} + route_param_keywords = ("explode", "style", "allowReserved") + + for attr in attr_to_spec_key: + if hasattr(func, attr): + model = models[getattr(func, attr)] + for name, schema in model["properties"].items(): + # Route parameters keywords taken out of schema level + extra = { + kw: schema.pop(kw) for kw in route_param_keywords if kw in schema } - ) - - if hasattr(func, "headers"): - headers = models[func.headers] - for name, schema in headers["properties"].items(): - params.append( - { - "name": name, - "in": "header", - "schema": schema, - "required": name in headers.get("required", []), - "description": schema.get("description", ""), - } - ) - - if hasattr(func, "cookies"): - cookies = models[func.cookies] - for name, schema in cookies["properties"].items(): - params.append( - { - "name": name, - "in": "cookie", - "schema": schema, - "required": name in cookies.get("required", []), - "description": schema.get("description", ""), - } - ) + params.append( + { + "name": name, + "in": attr_to_spec_key[attr], + "schema": schema, + "required": name in model.get("required", []), + "description": schema.get("description", ""), + **extra, + } + ) return params diff --git a/tests/common.py b/tests/common.py index bbb96e10..6d965389 100644 --- a/tests/common.py +++ b/tests/common.py @@ -50,6 +50,11 @@ class DemoModel(BaseModel): name: str = Field(..., description="user name") +class DemoQuery(BaseModel): + names1: List[str] = Field(...) + names2: List[str] = Field(..., style="matrix", explode=True, non_keyword="dummy") + + def get_paths(spec): paths = [] for path in spec["paths"]: diff --git a/tests/test_utils.py b/tests/test_utils.py index b86e2981..8ba8e142 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -12,7 +12,7 @@ parse_resp, ) -from .common import DemoModel +from .common import DemoModel, DemoQuery api = SpecTree() @@ -30,6 +30,16 @@ def demo_func(): description""" +@api.validate(query=DemoQuery) +def demo_func_with_query(): + """ + a summary + + a description + """ + pass + + class DemoClass: @api.validate(query=DemoModel) def demo_method(self): @@ -104,9 +114,36 @@ def test_parse_params(): "in": "query", "required": True, "description": "", - "schema": { - "title": "Uid", - "type": "integer", - }, + "schema": {"title": "Uid", "type": "integer"}, } assert params[2]["description"] == "user name" + + +def test_parse_params_with_route_param_keywords(): + models = { + "DemoQuery": DemoQuery.schema(ref_template="#/components/schemas/{model}") + } + params = parse_params(demo_func_with_query, [], models) + assert params == [ + { + "name": "names1", + "in": "query", + "required": True, + "description": "", + "schema": {"title": "Names1", "type": "array", "items": {"type": "string"}}, + }, + { + "name": "names2", + "in": "query", + "required": True, + "description": "", + "schema": { + "title": "Names2", + "type": "array", + "items": {"type": "string"}, + "non_keyword": "dummy", + }, + "style": "matrix", + "explode": True, + }, + ]