-
-
Notifications
You must be signed in to change notification settings - Fork 444
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use serialization aliases for responses in OpenAPI schema #1162
base: master
Are you sure you want to change the base?
Conversation
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.
This might be the same thing as #1139 |
@pmdevita thanks for calling that out. There is some duplication here in that both pulls depend on leveraging the I'm open to closing the pull request, but considering the other one is also facing some open questions of backwards compatibility, I don't want to slow down this fix because of those unrelated topics. |
@camuthig So, what about this PR? |
@nstonic I'm not sure what the situation here is. @vitalik would you consider this pull request as an simpler version of the referenced #1139, that one is tackling a much deeper problem. This pull request has a smaller scope and only makes sure that the alias configurations are respected in the JSON schema generation. I think the other PR can still be considered as a progression of what this one accomplishes. |
@vitalik any update on this? |
Had to solve this at work, here's the monkey patch I applied to make it work. # pyright: basic
from http.client import responses
from typing import Any
import ninja
import pydantic
from ninja.constants import NOT_SET
from ninja.openapi.schema import REF_TEMPLATE
from ninja.openapi.schema import OpenAPISchema
from ninja.schema import NinjaGenerateJsonSchema
from pydantic.json_schema import JsonSchemaMode
def _create_schema_from_model(
self,
model: pydantic.BaseModel,
by_alias: bool = True, # noqa: FBT001, FBT002
remove_level: bool = True, # noqa: FBT001, FBT002
mode: JsonSchemaMode = "validation",
) -> tuple[dict[str, Any], bool]:
if hasattr(model, "__ninja_flatten_map__"):
schema = self._flatten_schema(model)
else:
schema = model.model_json_schema(
ref_template=REF_TEMPLATE,
by_alias=by_alias,
schema_generator=NinjaGenerateJsonSchema,
mode=mode,
).copy()
# schema = _rewrite_schema(self.schemas, schema, mode)
if schema.get("$defs"):
self.add_schema_definitions(schema.pop("$defs"))
if remove_level and len(schema["properties"]) == 1:
name, details = next(iter(schema["properties"].items()))
required = name in schema.get("required", {})
return details, required
return schema, True
def _responses(self, operation: Any) -> dict[int, dict[str, Any]]:
assert bool(operation.response_models), f"{operation.response_models} empty"
result = {}
for status, model in operation.response_models.items():
if status == Ellipsis:
continue # it's not yet clear what it means if user wants to output any other code
description = responses.get(status, "Unknown Status Code")
details: dict[int, Any] = {status: {"description": description}}
if model not in [None, NOT_SET]:
schema = self._create_schema_from_model(
model,
by_alias=operation.by_alias,
mode="serialization",
)[0]
details[status]["content"] = {self.api.renderer.media_type: {"schema": schema}}
result.update(details)
return result
def apply_ninja_monkey_patch():
version_tuple = tuple(map(int, ninja.__version__.split(".")))
if version_tuple > (1, 3, 0):
msg = "This monkey patch is only tested for ninja<=1.3.0"
raise ImportError(msg)
OpenAPISchema._create_schema_from_model = _create_schema_from_model # noqa: SLF001
OpenAPISchema.responses = _responses # settings.py
# ...
from my_package.ninja_api_schema_monkey_patch import apply_ninja_monkey_patch
apply_ninja_monkey_patch() |
When generating JSON schemas from the Pydantic types, the
mode
must be set in order for the correct 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.This fixes issues I brought up in discussion #1132