Skip to content

Commit

Permalink
Add PYDANTIC_V2 check to __root__ check. Use type alias in basic test
Browse files Browse the repository at this point in the history
  • Loading branch information
MarkusSintonen committed Apr 24, 2024
1 parent 2df55f2 commit 52841df
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 19 deletions.
8 changes: 6 additions & 2 deletions fastapi/encoders.py
Original file line number Diff line number Diff line change
Expand Up @@ -230,10 +230,14 @@ def jsonable_encoder(
exclude_none=exclude_none,
exclude_defaults=exclude_defaults,
)

if (
isinstance(serialized, dict) and "__root__" in serialized
): # TODO: remove when deprecating Pydantic v1
not PYDANTIC_V2
and isinstance(serialized, dict)
and "__root__" in serialized
):
serialized = serialized["__root__"]

return jsonable_encoder(
serialized,
exclude_none=exclude_none,
Expand Down
37 changes: 20 additions & 17 deletions tests/test_root_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@
if PYDANTIC_V2:
from pydantic import ConfigDict, Field, RootModel, field_validator, model_serializer

class Basic(RootModel[int]):
pass
Basic = RootModel[int]

class FieldWrap(RootModel[str]):
model_config = ConfigDict(
Expand Down Expand Up @@ -385,11 +384,12 @@ def test_root_model_dictwrap_422():


@pytest.mark.parametrize(
"model, model_schema",
"model, path_name, model_schema",
[
(Basic, {"title": "Basic", "type": "integer"}),
(Basic, "basic", {"title": "RootModel[int]", "type": "integer"}),
(
FieldWrap,
"fieldwrap",
{
"title": "FieldWrap",
"type": "string",
Expand All @@ -399,6 +399,7 @@ def test_root_model_dictwrap_422():
),
(
CustomParsed,
"customparsed",
{
"title": "CustomParsed",
"type": "string",
Expand All @@ -407,31 +408,33 @@ def test_root_model_dictwrap_422():
),
],
)
def test_openapi_schema(model: Type, model_schema: Dict[str, Any]):
def test_openapi_schema(model: Type, path_name: str, model_schema: Dict[str, Any]):
response = client.get("/openapi.json")
assert response.status_code == 200, response.text

paths = response.json()["paths"]
ref = {"schema": {"$ref": f"#/components/schemas/{model.__name__}"}}
assert paths[f"/query/{model.__name__.lower()}"]["get"]["parameters"] == [
{"in": "query", "name": "q", "required": True, **ref}
ref_name = model.__name__.replace("[", "_").replace("]", "_")
schema_ref = {"schema": {"$ref": f"#/components/schemas/{ref_name}"}}

assert paths[f"/query/{path_name}"]["get"]["parameters"] == [
{"in": "query", "name": "q", "required": True, **schema_ref}
]
assert paths[f"/path/{model.__name__.lower()}/{{p}}"]["get"]["parameters"] == [
{"in": "path", "name": "p", "required": True, **ref}
assert paths[f"/path/{path_name}/{{p}}"]["get"]["parameters"] == [
{"in": "path", "name": "p", "required": True, **schema_ref}
]
assert paths[f"/body/{model.__name__.lower()}"]["post"]["requestBody"] == {
"content": {"application/json": ref},
assert paths[f"/body/{path_name}"]["post"]["requestBody"] == {
"content": {"application/json": schema_ref},
"required": True,
}
assert paths[f"/body_default/{model.__name__.lower()}"]["post"]["requestBody"] == {
"content": {"application/json": ref},
assert paths[f"/body_default/{path_name}"]["post"]["requestBody"] == {
"content": {"application/json": schema_ref},
"required": True,
}
assert paths[f"/echo/{model.__name__.lower()}"]["get"]["responses"]["200"] == {
"content": {"application/json": ref},
assert paths[f"/echo/{path_name}"]["get"]["responses"]["200"] == {
"content": {"application/json": schema_ref},
"description": "Successful Response",
}
assert response.json()["components"]["schemas"][model.__name__] == {
assert response.json()["components"]["schemas"][ref_name] == {
"title": model.__name__,
**model_schema,
}
Expand Down

0 comments on commit 52841df

Please sign in to comment.