Bug: schema_extra does not recognize upstream JSONSchema property/key names
charles-dyfis-net opened this issue · 1 comments
charles-dyfis-net commented
Description
With code generated for other (non-litestar) JSONSchema consumers, using upstream names (such as uniqueItems
instead of unique_items
) inside of schema_extra
results in a ValueError.
URL to code causing the issue
No response
MCVE
from typing import Annotated, Any, Dict
import pydantic
from litestar import Litestar, get
# Presume that this type's JSONSchema is used by consumers other than litestar, and needs to be spec-compliant
class RandomType(pydantic.BaseModel):
# uniqueItems is per spec -- see https://json-schema.org/understanding-json-schema/reference/array
unique_items: Annotated[list[str], pydantic.Field(json_schema_extra={"uniqueItems": True})]
@get("/")
async def hello_world() -> RandomType:
"""Route Handler that outputs hello world."""
return RandomType(unique_items=["hi", "bye"])
app = Litestar(route_handlers=[hello_world])
Steps to reproduce
1. Run `litestar --app app:app run --debug`
2. Load `http://localhost:8000/schema`
3. Watch the resulting stack trace
Screenshots
No response
Logs
ERROR - 2024-09-29 21:52:29,271 - litestar - config - Uncaught exception (connection_type=http, path=/schema):
Traceback (most recent call last):
File "/nix/store/abpcb2xnkhh64yh30nkc6nv19nv720y4-python3-3.12.4-env/lib/python3.12/site-packages/litestar/middleware/_internal/exceptions/middleware.py", line 159, in __call__
await self.app(scope, receive, capture_response_started)
File "/nix/store/abpcb2xnkhh64yh30nkc6nv19nv720y4-python3-3.12.4-env/lib/python3.12/site-packages/litestar/_asgi/asgi_router.py", line 100, in __call__
await asgi_app(scope, receive, send)
File "/nix/store/abpcb2xnkhh64yh30nkc6nv19nv720y4-python3-3.12.4-env/lib/python3.12/site-packages/litestar/routes/http.py", line 80, in handle
response = await self._get_response_for_request(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/nix/store/abpcb2xnkhh64yh30nkc6nv19nv720y4-python3-3.12.4-env/lib/python3.12/site-packages/litestar/routes/http.py", line 132, in _get_response_for_request
return await self._call_handler_function(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/nix/store/abpcb2xnkhh64yh30nkc6nv19nv720y4-python3-3.12.4-env/lib/python3.12/site-packages/litestar/routes/http.py", line 152, in _call_handler_function
response_data, cleanup_group = await self._get_response_data(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/nix/store/abpcb2xnkhh64yh30nkc6nv19nv720y4-python3-3.12.4-env/lib/python3.12/site-packages/litestar/routes/http.py", line 195, in _get_response_data
data = route_handler.fn(**parsed_kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/nix/store/abpcb2xnkhh64yh30nkc6nv19nv720y4-python3-3.12.4-env/lib/python3.12/site-packages/litestar/_openapi/plugin.py", line 161, in _handler
return plugin_.render(request, self.provide_openapi_schema())
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/nix/store/abpcb2xnkhh64yh30nkc6nv19nv720y4-python3-3.12.4-env/lib/python3.12/site-packages/litestar/_openapi/plugin.py", line 99, in provide_openapi_schema
self._openapi_schema = self.provide_openapi().to_schema()
^^^^^^^^^^^^^^^^^^^^^^
File "/nix/store/abpcb2xnkhh64yh30nkc6nv19nv720y4-python3-3.12.4-env/lib/python3.12/site-packages/litestar/_openapi/plugin.py", line 94, in provide_openapi
self._openapi = self._build_openapi()
^^^^^^^^^^^^^^^^^^^^^
File "/nix/store/abpcb2xnkhh64yh30nkc6nv19nv720y4-python3-3.12.4-env/lib/python3.12/site-packages/litestar/_openapi/plugin.py", line 83, in _build_openapi
path_item = create_path_item_for_route(context, route)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/nix/store/abpcb2xnkhh64yh30nkc6nv19nv720y4-python3-3.12.4-env/lib/python3.12/site-packages/litestar/_openapi/path_item.py", line 139, in create_path_item_for_route
return path_item_factory.create_path_item()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/nix/store/abpcb2xnkhh64yh30nkc6nv19nv720y4-python3-3.12.4-env/lib/python3.12/site-packages/litestar/_openapi/path_item.py", line 44, in create_path_item
operation = self.create_operation_for_handler_method(route_handler, HttpMethod(http_method))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/nix/store/abpcb2xnkhh64yh30nkc6nv19nv720y4-python3-3.12.4-env/lib/python3.12/site-packages/litestar/_openapi/path_item.py", line 73, in create_operation_for_handler_method
responses = create_responses_for_handler(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/nix/store/abpcb2xnkhh64yh30nkc6nv19nv720y4-python3-3.12.4-env/lib/python3.12/site-packages/litestar/_openapi/responses.py", line 340, in create_responses_for_handler
return ResponseFactory(context, route_handler).create_responses(raises_validation_error=raises_validation_error)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/nix/store/abpcb2xnkhh64yh30nkc6nv19nv720y4-python3-3.12.4-env/lib/python3.12/site-packages/litestar/_openapi/responses.py", line 91, in create_responses
str(self.route_handler.status_code): self.create_success_response(),
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/nix/store/abpcb2xnkhh64yh30nkc6nv19nv720y4-python3-3.12.4-env/lib/python3.12/site-packages/litestar/_openapi/responses.py", line 150, in create_success_response
result = self.schema_creator.for_field_definition(field_def)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/nix/store/abpcb2xnkhh64yh30nkc6nv19nv720y4-python3-3.12.4-env/lib/python3.12/site-packages/litestar/_openapi/schema_generation/schema.py", line 333, in for_field_definition
result = self.for_plugin(field_definition, plugin_for_annotation)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/nix/store/abpcb2xnkhh64yh30nkc6nv19nv720y4-python3-3.12.4-env/lib/python3.12/site-packages/litestar/_openapi/schema_generation/schema.py", line 515, in for_plugin
schema = plugin.to_openapi_schema(field_definition=field_definition, schema_creator=self)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/nix/store/abpcb2xnkhh64yh30nkc6nv19nv720y4-python3-3.12.4-env/lib/python3.12/site-packages/litestar/contrib/pydantic/pydantic_schema_plugin.py", line 235, in to_openapi_schema
return self.for_pydantic_model(field_definition=field_definition, schema_creator=schema_creator)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/nix/store/abpcb2xnkhh64yh30nkc6nv19nv720y4-python3-3.12.4-env/lib/python3.12/site-packages/litestar/contrib/pydantic/pydantic_schema_plugin.py", line 252, in for_pydantic_model
return schema_creator.create_component_schema(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/nix/store/abpcb2xnkhh64yh30nkc6nv19nv720y4-python3-3.12.4-env/lib/python3.12/site-packages/litestar/_openapi/schema_generation/schema.py", line 645, in create_component_schema
schema.properties = {k: self.for_field_definition(v) for k, v in property_fields.items()}
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/nix/store/abpcb2xnkhh64yh30nkc6nv19nv720y4-python3-3.12.4-env/lib/python3.12/site-packages/litestar/_openapi/schema_generation/schema.py", line 361, in for_field_definition
return self.process_schema_result(field_definition, result) if isinstance(result, Schema) else result
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/nix/store/abpcb2xnkhh64yh30nkc6nv19nv720y4-python3-3.12.4-env/lib/python3.12/site-packages/litestar/_openapi/schema_generation/schema.py", line 596, in process_schema_result
raise ValueError(
ValueError: `schema_extra` declares key `uniqueItems` which does not exist in `Schema` object
> /nix/store/abpcb2xnkhh64yh30nkc6nv19nv720y4-python3-3.12.4-env/lib/python3.12/site-packages/litestar/_openapi/schema_generation/schema.py(596)process_schema_result()
Litestar Version
2.12.1
Platform
- Linux
- Mac
- Windows
- Other (Please specify in the description above)
Note
While we are open for sponsoring on GitHub Sponsors and
OpenCollective, we also utilize Polar.sh to engage in pledge-based sponsorship.
Check out all issues funded or available for funding on our Polar.sh dashboard
- If you would like to see an issue prioritized, make a pledge towards it!
- We receive the pledge once the issue is completed & verified
- This, along with engagement in the community, helps us know which features are a priority to our users.
github-actions commented
A fix for this issue has been released in v2.13.0