Python FastApi generated Swagger docs don't replace parameter placeholder (i.e. {id}) with value

Question:

i tried to create a fastapi router that would handle 2 path parameters of type int.

i expected it to replace the placeholders (i.e. {parameter_name}) with the value i entered in the swagger ui.

only one of the parameters were replaced, and the other was kept as the variable name with url encoded curly brackets, i.e. "%parameter_name%".

i defined this route with fastapi:

api_router = APIRouter(prefix="user/{user_id}")

@api_router.put("/post/{post_id}")
def module_deep_clone(
        user_id: int,
        post_id: int,
):
    return {"post_id": post_id, "company_id": company_id}

Using the generated Swagger ui results in a bad request url, where one path variable isn’t replaced with the value:
"http://0.0.0.0:8000/user/123/post/{post_id}"

which results in a validation error, as post_id is expected to be an integer and not "%7Bpost_id%"

when i replace the order of parameter definition in the function:

@api_router.put("/post/{post_id}")
def module_deep_clone(
        post_id: int,
        user_id: int,
):

the resulting url is:
"http://0.0.0.0:8000/user/{user_id}/post/123"

which made me think that somehow Swagger was expecting only one parameter, but the relevant section in the resulting openapi.json looks like this:

"parameters": [
        {
            "name": "company_id",
            "in": "path",
            "required": true,
            "schema": {
                "type": "integer",
                "title": "Company Id"
            }
        },
        {
            "name": "item_id",
            "in": "path",
            "required": true,
            "schema": {
                "type": "integer",
                "title": "Item Id"
            }
        }
    ]}

i’m using python 3.11, fastapi 0.101.1.

What am i missing?

Thanks

Asked By: user2546783

||

Answers:

This is a bug in latest version of Swagger UI.
You can overcome it by using older version (https://github.com/tiangolo/fastapi/discussions/11572#discussioncomment-9403528) :

app = FastAPI(docs_url=None)  # Disable default docs

from fastapi.openapi.docs import (get_swagger_ui_html,
                                  get_swagger_ui_oauth2_redirect_html)

@app.get("/docs", include_in_schema=False)
async def custom_swagger_ui_html():
    return get_swagger_ui_html(
        openapi_url=app.openapi_url,
        title=app.title + " - Swagger UI",
        oauth2_redirect_url=app.swagger_ui_oauth2_redirect_url,
        swagger_js_url="https://unpkg.com/[email protected]/swagger-ui-bundle.js",
        swagger_css_url="https://unpkg.com/[email protected]/swagger-ui.css",
    )
Answered By: Yurii Motov
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.