fix: handle discriminated model with root definition
This commit is contained in:
parent
be944ac98e
commit
26fd6fa19f
@ -68,7 +68,10 @@ class BodyGetter(AbstractInjector):
|
|||||||
|
|
||||||
def __init__(self, args_spec: dict, default_values: dict):
|
def __init__(self, args_spec: dict, default_values: dict):
|
||||||
self.arg_name, self.model = next(iter(args_spec.items()))
|
self.arg_name, self.model = next(iter(args_spec.items()))
|
||||||
self._expect_object = self.model.schema()["type"] == "object"
|
schema = self.model.schema()
|
||||||
|
if "type" not in schema:
|
||||||
|
schema["type"] = "object"
|
||||||
|
self._expect_object = schema["type"] == "object"
|
||||||
|
|
||||||
async def inject(self, request: BaseRequest, args_view: list, kwargs_view: dict):
|
async def inject(self, request: BaseRequest, args_view: list, kwargs_view: dict):
|
||||||
try:
|
try:
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
from typing import List, Optional, Union, Literal
|
from typing import List, Optional, Union, Literal, Annotated
|
||||||
from uuid import UUID
|
from uuid import UUID
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
@ -42,6 +42,20 @@ class Error(BaseModel):
|
|||||||
text: str
|
text: str
|
||||||
|
|
||||||
|
|
||||||
|
class Cat(BaseModel):
|
||||||
|
pet_type: Literal['cat']
|
||||||
|
meows: int
|
||||||
|
|
||||||
|
|
||||||
|
class Dog(BaseModel):
|
||||||
|
pet_type: Literal['dog']
|
||||||
|
barks: float
|
||||||
|
|
||||||
|
|
||||||
|
class Animal(BaseModel):
|
||||||
|
__root__: Annotated[Union[Cat, Dog], Field(discriminator='pet_type')]
|
||||||
|
|
||||||
|
|
||||||
class PetCollectionView(PydanticView):
|
class PetCollectionView(PydanticView):
|
||||||
async def get(
|
async def get(
|
||||||
self, format: str, lang: Lang = Lang.EN, name: Optional[str] = None, *, promo: Optional[UUID] = None
|
self, format: str, lang: Lang = Lang.EN, name: Optional[str] = None, *, promo: Optional[UUID] = None
|
||||||
@ -91,6 +105,11 @@ class ViewResponseReturnASimpleType(PydanticView):
|
|||||||
return web.json_response()
|
return web.json_response()
|
||||||
|
|
||||||
|
|
||||||
|
class DiscriminatedView(PydanticView):
|
||||||
|
async def post(self, /, request: Animal) -> r200[int]:
|
||||||
|
return web.json_response()
|
||||||
|
|
||||||
|
|
||||||
async def ensure_content_durability(client):
|
async def ensure_content_durability(client):
|
||||||
"""
|
"""
|
||||||
Reload the page 2 times to ensure that content is always the same
|
Reload the page 2 times to ensure that content is always the same
|
||||||
@ -115,6 +134,7 @@ async def generated_oas(aiohttp_client, event_loop) -> web.Application:
|
|||||||
app.router.add_view("/pets", PetCollectionView)
|
app.router.add_view("/pets", PetCollectionView)
|
||||||
app.router.add_view("/pets/{id}", PetItemView)
|
app.router.add_view("/pets/{id}", PetItemView)
|
||||||
app.router.add_view("/simple-type", ViewResponseReturnASimpleType)
|
app.router.add_view("/simple-type", ViewResponseReturnASimpleType)
|
||||||
|
app.router.add_view("/animals", DiscriminatedView)
|
||||||
oas.setup(app)
|
oas.setup(app)
|
||||||
|
|
||||||
return await ensure_content_durability(await aiohttp_client(app))
|
return await ensure_content_durability(await aiohttp_client(app))
|
||||||
@ -122,12 +142,26 @@ async def generated_oas(aiohttp_client, event_loop) -> web.Application:
|
|||||||
|
|
||||||
async def test_generated_oas_should_have_components_schemas(generated_oas):
|
async def test_generated_oas_should_have_components_schemas(generated_oas):
|
||||||
assert generated_oas["components"]["schemas"] == {
|
assert generated_oas["components"]["schemas"] == {
|
||||||
|
'Cat': {'properties': {'meows': {'title': 'Meows', 'type': 'integer'},
|
||||||
|
'pet_type': {'enum': ['cat'],
|
||||||
|
'title': 'Pet Type',
|
||||||
|
'type': 'string'}},
|
||||||
|
'required': ['pet_type', 'meows'],
|
||||||
|
'title': 'Cat',
|
||||||
|
'type': 'object'},
|
||||||
"Color": {
|
"Color": {
|
||||||
"description": "An enumeration.",
|
"description": "An enumeration.",
|
||||||
"enum": ["red", "green", "pink"],
|
"enum": ["red", "green", "pink"],
|
||||||
"title": "Color",
|
"title": "Color",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
},
|
},
|
||||||
|
'Dog': {'properties': {'barks': {'title': 'Barks', 'type': 'number'},
|
||||||
|
'pet_type': {'enum': ['dog'],
|
||||||
|
'title': 'Pet Type',
|
||||||
|
'type': 'string'}},
|
||||||
|
'required': ['pet_type', 'barks'],
|
||||||
|
'title': 'Dog',
|
||||||
|
'type': 'object'},
|
||||||
'Error': {
|
'Error': {
|
||||||
'properties': {
|
'properties': {
|
||||||
'code': {'title': 'Code', 'type': 'integer'},
|
'code': {'title': 'Code', 'type': 'integer'},
|
||||||
|
Loading…
x
Reference in New Issue
Block a user