From 5399ab793189b5aa7ccc15ed31c849b4e25e8aeb Mon Sep 17 00:00:00 2001 From: Chris Muthig Date: Sat, 11 May 2024 16:36:42 -0600 Subject: [PATCH] Use serialization aliases for responses in OpenAPI schema When generating JSON schemas from the Pydantic types, the `mode` must be set in order for the corret aliases to be used. The default is to generate the schema for validation mode, which means that for building response schemas, the mode needs to be explicitly set to serialization. --- ninja/openapi/schema.py | 6 +++++- tests/test_openapi_schema.py | 26 ++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/ninja/openapi/schema.py b/ninja/openapi/schema.py index 72226e770..cf3eee0b4 100644 --- a/ninja/openapi/schema.py +++ b/ninja/openapi/schema.py @@ -4,6 +4,8 @@ from http.client import responses from typing import TYPE_CHECKING, Any, Dict, Generator, List, Optional, Set, Tuple +from pydantic.json_schema import JsonSchemaMode + from ninja.constants import NOT_SET from ninja.operation import Operation from ninja.params.models import TModel, TModels @@ -207,6 +209,7 @@ def _create_schema_from_model( model: TModel, by_alias: bool = True, remove_level: bool = True, + mode: JsonSchemaMode = "validation", ) -> Tuple[DictStrAny, bool]: if hasattr(model, "__ninja_flatten_map__"): schema = self._flatten_schema(model) @@ -215,6 +218,7 @@ def _create_schema_from_model( ref_template=REF_TEMPLATE, by_alias=by_alias, schema_generator=NinjaGenerateJsonSchema, + mode=mode, ).copy() # move Schemas from definitions @@ -284,7 +288,7 @@ def responses(self, operation: Operation) -> Dict[int, DictStrAny]: if model not in [None, NOT_SET]: # ::TODO:: test this: by_alias == True schema = self._create_schema_from_model( - model, by_alias=operation.by_alias + model, by_alias=operation.by_alias, mode="serialization" )[0] details[status]["content"] = { self.api.renderer.media_type: {"schema": schema} diff --git a/tests/test_openapi_schema.py b/tests/test_openapi_schema.py index aec67f472..e4d683bb4 100644 --- a/tests/test_openapi_schema.py +++ b/tests/test_openapi_schema.py @@ -942,3 +942,29 @@ def get_employees(request): paged_employee_out = schema["components"]["schemas"]["PagedEmployeeOut"] # a default value shouldn't be specified automatically assert "default" not in paged_employee_out["properties"]["data"] + + +def test_renders_responses_with_serialization_alias(): + api = NinjaAPI(renderer=TestRenderer) + + class ResponseWithSerializationAlias(Schema): + my_field: str = Field(..., serialization_alias="myFieldName") + + @api.get( + "/test-with-serialization-alias/", + response=ResponseWithSerializationAlias, + by_alias=True, + ) + def method_test_with_serialization_alias( + request, + ): + return ResponseWithSerializationAlias(my_field="Field Value") + + schema = api.get_openapi_schema() + + assert ( + "myFieldName" + in schema["components"]["schemas"]["ResponseWithSerializationAlias"][ + "properties" + ] + )