PWZER / swagger-ui-py

Swagger UI for Python web framework, such Tornado, Flask and Sanic. https://pwzer.github.io/swagger-ui-py/
https://pypi.org/project/swagger-ui-py
Apache License 2.0
68 stars 31 forks source link

feat: added config_rel_url parameter #36

Closed giuliano-macedo closed 1 year ago

giuliano-macedo commented 1 year ago

Added a parameter named config_rel_url to ApplicationDocument so that it behaves like config_url except that it gets the openapi specification from a relative location to the server, example (AioHttp):

from aiohttp import web
from swagger_ui import aiohttp_api_doc

async def handler(req: web.Request) -> web.Response:
    return web.json_response({"openapi":"3.0.1","info":{"title":"python-swagger-ui test api","description":"python-swagger-ui test api","version":"1.0.0"},"servers":[{"url":"http://127.0.0.1:8989/api"}],"tags":[{"name":"default","description":"default tag"}],"paths":{"/hello/world":{"get":{"tags":["default"],"summary":"output hello world.","responses":{"200":{"description":"OK","content":{"application/text":{"schema":{"type":"object","example":"Hello World!!!"}}}}}}}},"components":{}})

app = web.Application()
app.router.add_get("/doc/openapi.json", handler)
aiohttp_api_doc(
    app,
    url_prefix="/doc",
    config_rel_url="/openapi.json",
    editor=True,
)

web.run_app(app, port=8080)

The motivation is that populating the "servers" field in the specification at least in aiohttp can't be done before the app is running, so one must inject the current server inside the request (see example below), therefore aiohttp_api_doc could provide a way to confingure a relative url pointing to the specification document in the server.

async def handler(req: web.Request) -> web.Response:
    return web.json_response(
        {
            "openapi": "3.0.1",
            "info": {
                "title": "python-swagger-ui test api",
                "description": "python-swagger-ui test api",
                "version": "1.0.0",
            },
            "servers": [{"url": f"{req.url.scheme}://{req.url.raw_authority}"}], #NOTE: using request to get the server domain
            "tags": [{"name": "default", "description": "default tag"}],
            "paths": {
                "/hello/world": {
                    "get": {
                        "tags": ["default"],
                        "summary": "output hello world.",
                        "responses": {
                            "200": {
                                "description": "OK",
                                "content": {
                                    "application/text": {
                                        "schema": {
                                            "type": "object",
                                            "example": "Hello World!!!",
                                        }
                                    }
                                },
                            }
                        },
                    }
                }
            },
            "components": {},
        }
    )