Search code examples
pythonswaggerfastapiopenapi

Description for APIRouter in FastAPI?


Suppose I have the following sample code:

from fastapi import APIRouter, FastAPI

router_one = APIRouter(tags=["users"])
router_two = APIRouter(tags=["products"])

app = FastAPI(description="## Description for whole application")

@router_one.get("/users")
async def fn1():
    pass

@router_one.post("/users")
async def fn2():
    pass

@router_two.get("/products")
async def fn3():
    pass

@router_two.post("/products")
async def fn4():
    pass

app.include_router(router_one)
app.include_router(router_two)

It is rendered as below in swagger:

enter image description here

I know I can pass description argument for individual path operation functions but what I really need is to pass description argument to the APIRouter itself(I showed in the picture). I have some common information which is shared among the path operations below a certain tag like users.

I noticed that there is no api available for that in FastAPI like this:

router_one = APIRouter(tags=["users"], description=...)

# or

app.include_router(router_one, description=...)

Is there any other way to achieve that?


Solution

  • You can use the openapi_tags parameter of FastAPI class as below -

    from fastapi import APIRouter, FastAPI
    
    router_one = APIRouter(tags=["users"])
    router_two = APIRouter(tags=["products"])
    
    app = FastAPI(
        description="## Description for whole application",
        openapi_tags=[
            {"name": "users", "description": "Operations with users"},
            {
                "name": "products",
                "description": "Operations with products",
                "externalDocs": {
                    "description": "Items external docs",
                    "url": "https://fastapi.tiangolo.com/",
                },
            },
        ],
    )
    
    
    @router_one.get("/users")
    async def fn1():
        pass
    
    
    @router_one.post("/users")
    async def fn2():
        pass
    
    
    @router_two.get("/products")
    async def fn3():
        pass
    
    
    @router_two.post("/products")
    async def fn4():
        pass
    
    
    app.include_router(router_one)
    app.include_router(router_two)

    Result

    Output