feat: add support for definition in query param

This commit is contained in:
Georg K 2022-08-04 23:01:04 +03:00
parent 207204fe53
commit 1dd98d2752
3 changed files with 60 additions and 6 deletions

View File

@ -126,6 +126,10 @@ def _add_http_method_to_oas(
ref_template="#/components/schemas/{model}" ref_template="#/components/schemas/{model}"
) )
# move definitions
if def_sub_schemas := oas_operation.parameters[i].schema.pop("definitions", None):
oas.components.schemas.update(def_sub_schemas)
return_type = get_type_hints(handler).get("return") return_type = get_type_hints(handler).get("return")
if return_type is not None: if return_type is not None:
_OASResponseBuilder(oas, oas_operation, status_code_descriptions).build( _OASResponseBuilder(oas, oas_operation, status_code_descriptions).build(

View File

@ -20,6 +20,11 @@ class Color(str, Enum):
PINK = "pink" PINK = "pink"
class Lang(str, Enum):
EN = 'en'
FR = 'fr'
class Toy(BaseModel): class Toy(BaseModel):
name: str name: str
color: Color color: Color
@ -33,7 +38,7 @@ class Pet(BaseModel):
class PetCollectionView(PydanticView): class PetCollectionView(PydanticView):
async def get( async def get(
self, format: str, name: Optional[str] = None, *, promo: Optional[UUID] = None self, format: str, lang: Lang = Lang.EN, name: Optional[str] = None, *, promo: Optional[UUID] = None
) -> r200[List[Pet]]: ) -> r200[List[Pet]]:
""" """
Get a list of pets Get a list of pets
@ -51,11 +56,11 @@ class PetCollectionView(PydanticView):
class PetItemView(PydanticView): class PetItemView(PydanticView):
async def get( async def get(
self, self,
id: int, id: int,
/, /,
size: Union[int, Literal["x", "l", "s"]], size: Union[int, Literal["x", "l", "s"]],
day: Union[int, Literal["now"]] = "now", day: Union[int, Literal["now"]] = "now",
) -> Union[r200[Pet], r404]: ) -> Union[r200[Pet], r404]:
return web.json_response() return web.json_response()
@ -116,6 +121,12 @@ async def test_generated_oas_should_have_components_schemas(generated_oas):
"title": "Color", "title": "Color",
"type": "string", "type": "string",
}, },
'Lang': {
'description': 'An enumeration.',
'enum': ['en', 'fr'],
'title': 'Lang',
'type': 'string'
},
"Toy": { "Toy": {
"properties": { "properties": {
"color": {"$ref": "#/components/schemas/Color"}, "color": {"$ref": "#/components/schemas/Color"},
@ -143,6 +154,16 @@ async def test_pets_route_should_have_get_method(generated_oas):
"required": True, "required": True,
"schema": {"title": "format", "type": "string"}, "schema": {"title": "format", "type": "string"},
}, },
{
'in': 'query',
'name': 'lang',
'required': False,
'schema': {
'allOf': [{'$ref': '#/components/schemas/Lang'}],
'default': 'en',
'title': 'lang'
}
},
{ {
"in": "query", "in": "query",
"name": "name", "name": "name",

View File

@ -1,5 +1,6 @@
from __future__ import annotations from __future__ import annotations
from enum import Enum
from typing import Optional, List from typing import Optional, List
from pydantic import Field from pydantic import Field
from aiohttp import web from aiohttp import web
@ -54,6 +55,20 @@ class ArticleViewWithPaginationGroup(PydanticView):
) )
class Lang(str, Enum):
EN = 'en'
FR = 'fr'
class ArticleViewWithEnumInQuery(PydanticView):
async def get(self, lang: Lang):
return web.json_response(
{
"lang": lang
}
)
async def test_get_article_without_required_qs_should_return_an_error_message( async def test_get_article_without_required_qs_should_return_an_error_message(
aiohttp_client, event_loop aiohttp_client, event_loop
): ):
@ -236,6 +251,20 @@ async def test_get_article_with_page_and_page_size(aiohttp_client, event_loop):
assert resp.content_type == "application/json" assert resp.content_type == "application/json"
async def test_get_article_with_enum_in_query(aiohttp_client, event_loop):
app = web.Application()
app.router.add_view("/article", ArticleViewWithEnumInQuery)
client = await aiohttp_client(app)
resp = await client.get(
"/article", params={"lang": Lang.EN.value}
)
assert await resp.json() == {'lang': Lang.EN}
assert resp.status == 200
assert resp.content_type == "application/json"
async def test_get_article_with_page_and_wrong_page_size(aiohttp_client, event_loop): async def test_get_article_with_page_and_wrong_page_size(aiohttp_client, event_loop):
app = web.Application() app = web.Application()
app.router.add_view("/article", ArticleViewWithPaginationGroup) app.router.add_view("/article", ArticleViewWithPaginationGroup)