Skip to content

Commit

Permalink
Merge pull request #115 from jonathanlintott/allow-extra-keywords
Browse files Browse the repository at this point in the history
Catch route parameter keywords from schema when parsing params
  • Loading branch information
kemingy authored Apr 7, 2021
2 parents cefc9f4 + 50baf66 commit d41f4a1
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 42 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -102,3 +102,6 @@ venv.bak/

# mypy
.mypy_cache/

# pycharm project files
.idea
57 changes: 20 additions & 37 deletions spectree/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
5 changes: 5 additions & 0 deletions tests/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"]:
Expand Down
47 changes: 42 additions & 5 deletions tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
parse_resp,
)

from .common import DemoModel
from .common import DemoModel, DemoQuery

api = SpecTree()

Expand All @@ -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):
Expand Down Expand Up @@ -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,
},
]

0 comments on commit d41f4a1

Please sign in to comment.