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 using Schema constructor in blueprints gives error #199

Open
m-aliansari opened this issue Jun 4, 2023 · 0 comments
Open

Comments

@m-aliansari
Copy link

m-aliansari commented Jun 4, 2023

Description
I want to show the minimum value of a query parameter in the docs, so I am using Schema constructor with @openapi.parameter decorator. It works great when using in app route directly. However, it starts giving error when I use the same method in blueprints. I am attaching sample code and screenshots below.

What's working
here is the sample code that works correct

from sanic import Request, Sanic
from sanic_ext import Config, openapi
from sanic_ext.extensions.openapi.types import Schema

app = Sanic(name="sample")
app.extend(
    config=Config(
        swagger_ui_configuration={
            "showCommonExtensions": True,
            "apisSorter": "alpha", 
            "operationsSorter": "alpha"
        }
    )
)

@app.get("/")
@openapi.parameter(name='other', schema=Schema(type="int", minimum=1))
async def hello(request: Request):
    return "hello world"

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=8000)

Notice the Schema constructor being used. It gives the docs also as expected.
image

What does not work (Steps to reproduce)
Here is the sample code that doesn't work. It involves two files.

# example_blueprint.py
from sanic import Blueprint, Request, Sanic
from sanic_ext import openapi
from sanic_ext.extensions.openapi.types import Schema

app = Sanic.get_app()

example_blueprint = Blueprint("example_blueprint", "/example")

@example_blueprint.get("/")
@openapi.parameter(name="page", schema=Schema(type=int, minimum=1))
async def movie(request: Request):
    return "some"
# server.py
from sanic import Request, Sanic
from sanic_ext import Config, openapi
from sanic_ext.extensions.openapi.types import Schema

app = Sanic(name="sample")
app.extend(
    config=Config(
        swagger_ui_configuration={
            "showCommonExtensions": True,
            "apisSorter": "alpha", 
            "operationsSorter": "alpha"
        }
    )
)

from example_blueprint import example_blueprint
app.blueprint(blueprint=example_blueprint)

@app.get("/")
@openapi.parameter(name='other', schema=Schema(type="int", minimum=1))
async def hello(request: Request):
    return "hello world"

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=8000)

This code initializes perfect but when I navigate to /docs it gives the following error in console:

[12240] [ERROR] Exception occurred while handling uri: 'http://localhost:8000/docs/openapi.json'
Traceback (most recent call last):
  File "E:\workplace\sanic-openapi-problem\venv\Lib\site-packages\sanic\app.py", line 974, in handle_request
    response = await response
               ^^^^^^^^^^^^^^
  File "E:\workplace\sanic-openapi-problem\venv\Lib\site-packages\sanic_ext\extensions\openapi\blueprint.py", line 109, in spec
    return json(SpecificationBuilder().build(request.app).serialize())
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "E:\workplace\sanic-openapi-problem\venv\Lib\site-packages\sanic\response\convenience.py", line 50, in json
    return JSONResponse(
           ^^^^^^^^^^^^^
  File "E:\workplace\sanic-openapi-problem\venv\Lib\site-packages\sanic\response\types.py", line 361, in __init__
    self._encode_body(self._use_dumps(body, **self._use_dumps_kwargs)),
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\Ansari\AppData\Local\Programs\Python\Python311\Lib\json\__init__.py", line 238, in dumps
    **kw).encode(obj)
          ^^^^^^^^^^^
  File "C:\Users\Ansari\AppData\Local\Programs\Python\Python311\Lib\json\encoder.py", line 200, in encode
    chunks = self.iterencode(o, _one_shot=True)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\Ansari\AppData\Local\Programs\Python\Python311\Lib\json\encoder.py", line 258, in iterencode
    return _iterencode(o, 0)
           ^^^^^^^^^^^^^^^^^
  File "C:\Users\Ansari\AppData\Local\Programs\Python\Python311\Lib\json\encoder.py", line 180, in default
    raise TypeError(f'Object of type {o.__class__.__name__} '
TypeError: Object of type type is not JSON serializable

And on the web it gives this error.
image

Environment:

  • OS: Windows 10
  • Browser: chrome
  • Sanic: v23.3.0
  • sanic-routing: 22.8.0
  • sanic-ext: 23.3.0
  • python: 3.11.3

Additional context
It works fine when I use docstrings as documentation, but I can't use docstrings because some of my query params are complex and will require a lot of writing everytime something changes. So, I want to make it work with @openapi.parameter decorator.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant