Skip to content
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

Bug: OpenAPI docs fail to generate with certain validators and pydantic v1 #3471

Closed
2 of 4 tasks
sergeyk93 opened this issue May 5, 2024 · 4 comments · Fixed by #3476
Closed
2 of 4 tasks

Bug: OpenAPI docs fail to generate with certain validators and pydantic v1 #3471

sergeyk93 opened this issue May 5, 2024 · 4 comments · Fixed by #3476
Labels
Bug 🐛 This is something that is not working as expected

Comments

@sergeyk93
Copy link

sergeyk93 commented May 5, 2024

Description

OpenAPI docs fail to generate when a request payload is a pydantic v1 model and has a str field with a validator combination of a default(or default_factory) and max_length. Removing any of the validators resolves the issue; it's only reproducible with their combination.
Reproducible with:
Python: 3.11.6
Litestar: 2.8.2
Pydantic: 1.10.15

URL to code causing the issue

No response

MCVE

from litestar import Controller, post
from pydantic.fields import Field
from pydantic.main import BaseModel

OPENAPI_CONTROLLER_TAG = "OpenApiTest"


class TestDto(BaseModel):
    test_str: str = Field(default="some_default", max_length=100)


class OpenApiTestController(Controller):
    path = "/test-openapi"

    @post(
        path="/test",
        tags=[OPENAPI_CONTROLLER_TAG],
        summary="Test",
    )
    async def test(self, data: TestDto) -> str:
        return "success"

Steps to reproduce

1. Add the above controller to your litestar app.
2. Load any variation of OpenAPI UI(I reproduced with swagger, redoc, rapiddoc).

Screenshots

"![SCREENSHOT_DESCRIPTION](SCREENSHOT_LINK.png)"

Logs

ERROR - 2024-05-05 09:36:30,092 - litestar - config - exception raised on http connection to route /schema/redoc

Traceback (most recent call last):
  File "{project_parent_dir}/litestar-playground/.venv/lib/python3.11/site-packages/litestar/serialization/msgspec_hooks.py", line 141, in encode_json
    return msgspec.json.encode(value, enc_hook=serializer) if serializer else _msgspec_json_encoder.encode(value)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "{project_parent_dir}/litestar-playground/.venv/lib/python3.11/site-packages/litestar/serialization/msgspec_hooks.py", line 88, in default_serializer
    raise TypeError(f"Unsupported type: {type(value)!r}")
TypeError: Unsupported type: <class 'method_descriptor'>

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "{project_parent_dir}/litestar-playground/.venv/lib/python3.11/site-packages/litestar/middleware/exceptions/middleware.py", line 219, in __call__
    await self.app(scope, receive, send)
  File "{project_parent_dir}/litestar-playground/.venv/lib/python3.11/site-packages/litestar/routes/http.py", line 82, in handle
    response = await self._get_response_for_request(
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "{project_parent_dir}/litestar-playground/.venv/lib/python3.11/site-packages/litestar/routes/http.py", line 134, in _get_response_for_request
    return await self._call_handler_function(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "{project_parent_dir}/litestar-playground/.venv/lib/python3.11/site-packages/litestar/routes/http.py", line 154, in _call_handler_function
    response_data, cleanup_group = await self._get_response_data(
                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "{project_parent_dir}/litestar-playground/.venv/lib/python3.11/site-packages/litestar/routes/http.py", line 205, in _get_response_data
    data = route_handler.fn(**parsed_kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "{project_parent_dir}/litestar-playground/.venv/lib/python3.11/site-packages/litestar/_openapi/plugin.py", line 161, in _handler
    return plugin_.render(request, self.provide_openapi_schema())
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "{project_parent_dir}/litestar-playground/.venv/lib/python3.11/site-packages/litestar/openapi/plugins.py", line 310, in render
    self.render_json(request, openapi_schema),
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "{project_parent_dir}/litestar-playground/.venv/lib/python3.11/site-packages/litestar/openapi/plugins.py", line 70, in render_json
    return encode_json(openapi_schema, serializer=get_serializer(request.route_handler.resolve_type_encoders()))
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "{project_parent_dir}/litestar-playground/.venv/lib/python3.11/site-packages/litestar/serialization/msgspec_hooks.py", line 143, in encode_json
    raise SerializationException(str(msgspec_error)) from msgspec_error
litestar.exceptions.base_exceptions.SerializationException: Unsupported type: <class 'method_descriptor'>
Traceback (most recent call last):
  File "{project_parent_dir}/litestar-playground/.venv/lib/python3.11/site-packages/litestar/serialization/msgspec_hooks.py", line 141, in encode_json
    return msgspec.json.encode(value, enc_hook=serializer) if serializer else _msgspec_json_encoder.encode(value)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "{project_parent_dir}/litestar-playground/.venv/lib/python3.11/site-packages/litestar/serialization/msgspec_hooks.py", line 88, in default_serializer
    raise TypeError(f"Unsupported type: {type(value)!r}")
TypeError: Unsupported type: <class 'method_descriptor'>

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "{project_parent_dir}/litestar-playground/.venv/lib/python3.11/site-packages/litestar/middleware/exceptions/middleware.py", line 219, in __call__
    await self.app(scope, receive, send)
  File "{project_parent_dir}/litestar-playground/.venv/lib/python3.11/site-packages/litestar/routes/http.py", line 82, in handle
    response = await self._get_response_for_request(
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "{project_parent_dir}/litestar-playground/.venv/lib/python3.11/site-packages/litestar/routes/http.py", line 134, in _get_response_for_request
    return await self._call_handler_function(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "{project_parent_dir}/litestar-playground/.venv/lib/python3.11/site-packages/litestar/routes/http.py", line 154, in _call_handler_function
    response_data, cleanup_group = await self._get_response_data(
                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "{project_parent_dir}/litestar-playground/.venv/lib/python3.11/site-packages/litestar/routes/http.py", line 205, in _get_response_data
    data = route_handler.fn(**parsed_kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "{project_parent_dir}/litestar-playground/.venv/lib/python3.11/site-packages/litestar/_openapi/plugin.py", line 161, in _handler
    return plugin_.render(request, self.provide_openapi_schema())
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "{project_parent_dir}/litestar-playground/.venv/lib/python3.11/site-packages/litestar/openapi/plugins.py", line 310, in render
    self.render_json(request, openapi_schema),
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "{project_parent_dir}/litestar-playground/.venv/lib/python3.11/site-packages/litestar/openapi/plugins.py", line 70, in render_json
    return encode_json(openapi_schema, serializer=get_serializer(request.route_handler.resolve_type_encoders()))
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "{project_parent_dir}/litestar-playground/.venv/lib/python3.11/site-packages/litestar/serialization/msgspec_hooks.py", line 143, in encode_json
    raise SerializationException(str(msgspec_error)) from msgspec_error
litestar.exceptions.base_exceptions.SerializationException: Unsupported type: <class 'method_descriptor'>
INFO:     127.0.0.1:61936 - "GET /schema/redoc HTTP/1.1" 500 Internal Server Error
INFO:     127.0.0.1:61936 - "GET /favicon.ico HTTP/1.1" 404 Not Found
ERROR - 2024-05-05 09:36:30,309 - litestar - config - exception raised on http connection to route /favicon.ico

Traceback (most recent call last):
  File "{project_parent_dir}/litestar-playground/.venv/lib/python3.11/site-packages/litestar/_asgi/routing_trie/traversal.py", line 153, in parse_path_to_route
    node, path_parameters, path = traverse_route_map(
                                  ^^^^^^^^^^^^^^^^^^^
  File "{project_parent_dir}/litestar-playground/.venv/lib/python3.11/site-packages/litestar/_asgi/routing_trie/traversal.py", line 54, in traverse_route_map
    raise NotFoundException()
litestar.exceptions.http_exceptions.NotFoundException: 404: Not Found

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "{project_parent_dir}/litestar-playground/.venv/lib/python3.11/site-packages/litestar/middleware/exceptions/middleware.py", line 219, in __call__
    await self.app(scope, receive, send)
  File "{project_parent_dir}/litestar-playground/.venv/lib/python3.11/site-packages/litestar/_asgi/asgi_router.py", line 86, in __call__
    asgi_app, scope["route_handler"], scope["path"], scope["path_params"] = self.handle_routing(
                                                                            ^^^^^^^^^^^^^^^^^^^^
  File "{project_parent_dir}/litestar-playground/.venv/lib/python3.11/site-packages/litestar/_asgi/asgi_router.py", line 102, in handle_routing
    return parse_path_to_route(
           ^^^^^^^^^^^^^^^^^^^^
  File "{project_parent_dir}/litestar-playground/.venv/lib/python3.11/site-packages/litestar/_asgi/routing_trie/traversal.py", line 170, in parse_path_to_route
    raise NotFoundException() from e
litestar.exceptions.http_exceptions.NotFoundException: 404: Not Found
Traceback (most recent call last):
  File "{project_parent_dir}/litestar-playground/.venv/lib/python3.11/site-packages/litestar/_asgi/routing_trie/traversal.py", line 153, in parse_path_to_route
    node, path_parameters, path = traverse_route_map(
                                  ^^^^^^^^^^^^^^^^^^^
  File "{project_parent_dir}/litestar-playground/.venv/lib/python3.11/site-packages/litestar/_asgi/routing_trie/traversal.py", line 54, in traverse_route_map
    raise NotFoundException()
litestar.exceptions.http_exceptions.NotFoundException: 404: Not Found

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "{project_parent_dir}/litestar-playground/.venv/lib/python3.11/site-packages/litestar/middleware/exceptions/middleware.py", line 219, in __call__
    await self.app(scope, receive, send)
  File "{project_parent_dir}/litestar-playground/.venv/lib/python3.11/site-packages/litestar/_asgi/asgi_router.py", line 86, in __call__
    asgi_app, scope["route_handler"], scope["path"], scope["path_params"] = self.handle_routing(
                                                                            ^^^^^^^^^^^^^^^^^^^^
  File "{project_parent_dir}/litestar-playground/.venv/lib/python3.11/site-packages/litestar/_asgi/asgi_router.py", line 102, in handle_routing
    return parse_path_to_route(
           ^^^^^^^^^^^^^^^^^^^^
  File "{project_parent_dir}/litestar-playground/.venv/lib/python3.11/site-packages/litestar/_asgi/routing_trie/traversal.py", line 170, in parse_path_to_route
    raise NotFoundException() from e
litestar.exceptions.http_exceptions.NotFoundException: 404: Not Found

Litestar Version

2.8.2

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.
Fund with Polar
@sergeyk93 sergeyk93 added the Bug 🐛 This is something that is not working as expected label May 5, 2024
peterschutt added a commit that referenced this issue May 7, 2024
Fix issue where a pydantic v1 field annotation is wrapped with `Optional` if it is marked not required, but has a default value.

Closes #3471
@peterschutt
Copy link
Contributor

peterschutt added a commit that referenced this issue May 7, 2024
Fix issue where a pydantic v1 field annotation is wrapped with `Optional` if it is marked not required, but has a default value.

Closes #3471
peterschutt added a commit that referenced this issue May 7, 2024
Fix issue where a pydantic v1 field annotation is wrapped with `Optional` if it is marked not required, but has a default value.

Closes #3471
@sergeyk93
Copy link
Author

@peterschutt Tested & verified, thanks! What version is this change gonna be in?

Copy link

github-actions bot commented May 7, 2024

This issue has been closed in #3476. The change will be included in the upcoming patch release.

Copy link

github-actions bot commented Jun 2, 2024

A fix for this issue has been released in v2.9.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug 🐛 This is something that is not working as expected
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants