Closed chris-telemetry closed 1 year ago
After poking around for a bit I guess I'm somewhat confused as to why we care so much about the title being unique.
In litestar._openapi.schema_generation.schema
.
Revising this:
if schema.title and schema.type in (OpenAPIType.OBJECT, OpenAPIType.ARRAY):
if schema.title in self.schemas and hash(self.schemas[schema.title]) != hash(schema):
raise ImproperlyConfiguredException(
f"Two different schemas with the title {schema.title} have been defined.\n\n"
f"first: {encode_json(self.schemas[schema.title].to_schema()).decode()}\n"
f"second: {encode_json(schema.to_schema()).decode()}\n\n"
f"To fix this issue, either rename the base classes from which these titles are derived or manually"
f"set a 'title' kwarg in the route handler."
)
self.schemas[schema.title] = schema
return Reference(ref=f"#/components/schemas/{schema.title}")
return schema
To this:
if schema.title and schema.type in (OpenAPIType.OBJECT, OpenAPIType.ARRAY):
class_name = str(get_text_in_single_quotes(str(field.annotation)).replace(".", ""))
existing = self.schemas.get(class_name)
if existing:
return schema
self.schemas[name_title] = schema
return Reference(ref=f"#/components/schemas/{class_name}")
return schema
Seems to work. I'm sure I'm missing something here. Open to any input on it.
Thanks for the excellent report! Hopefully someone with more knowledge on this than me can chime in. Git blame is no help.
Do all tests pass with your change?
No, they would need to be updated to reflect the new naming scheme as they're currently hardcoded to the old one.
I'd make a PR for this but I'm afraid I'm not particularly familiar with the OpenAPI spec and I'm not quite sure if this was changed for compliance purposes?
@peterschutt My research leads me to believe my implementation would not be a violation of OpenAPI's spec. I've made an early PR pending feed back.
Thanks @chris-telemetry
Is there a workaround for this issue in the meantime?
Is there a workaround for this issue in the meantime?
@LonelyVikingMichael
The best workaround I've found is fudging the names of the schema using either the 'title' keyword on the Field
or by creating a dummy class:
class Player(BaseModel):
id: str
name: str
position: str
jersey: str
class PlayerWithDescription(Player):
pass
class Play(BaseModel):
id: str
ball_carrier: PlayerWithDescription = Field(description="Sub document representing player who carried the ball")
Description
We're getting an unexpected
ImproperlyConfiguredException
inlitestar/_openapi/schema_generation/schema.py", line 594, in process_schema_result
.In our app, we defined a base
Player
model using Pydantic. This model is returned on its own and also as a subdocument in other endpoints.Schema generation fails recognizes two different schemas with the same title. However, the schemas only differ in their description. The description itself is set as a field-level annotation when
Player
is used as a subdocument.This makes setting the
description
at the field level much less useful.I may be missing something. Looking at the code it hashes the schemas to ensure a 1-1 relationship between titles and schemas. I don't believe this was previously a constraint and schemas were produced based on the module path. I may not understand why this is now a requirement.
I've provided an example showing this behavior for both msgspec and Pydantic.
This behavior is new to Litestar 2.0 and did not exist in Litestar 1.51
URL to code causing the issue
No response
MCVE
Example using msgspec
Screenshots
No response
Logs
Litestar Version
Python 3.11 litestar[full] @ 2.2.1 pydantic @ 2.4.2
Platform