fix: handle discriminated model with root definition

This commit is contained in:
Georg K 2023-02-09 12:25:28 +03:00
parent be944ac98e
commit 26fd6fa19f
2 changed files with 39 additions and 2 deletions

View File

@ -68,7 +68,10 @@ class BodyGetter(AbstractInjector):
def __init__(self, args_spec: dict, default_values: dict):
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):
try:

View File

@ -1,7 +1,7 @@
from __future__ import annotations
from enum import Enum
from typing import List, Optional, Union, Literal
from typing import List, Optional, Union, Literal, Annotated
from uuid import UUID
import pytest
@ -42,6 +42,20 @@ class Error(BaseModel):
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):
async def get(
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()
class DiscriminatedView(PydanticView):
async def post(self, /, request: Animal) -> r200[int]:
return web.json_response()
async def ensure_content_durability(client):
"""
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/{id}", PetItemView)
app.router.add_view("/simple-type", ViewResponseReturnASimpleType)
app.router.add_view("/animals", DiscriminatedView)
oas.setup(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):
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": {
"description": "An enumeration.",
"enum": ["red", "green", "pink"],
"title": "Color",
"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': {
'properties': {
'code': {'title': 'Code', 'type': 'integer'},