When making an app that uses dependency injection with a list field, the parameter automatically goes to the request body in SwaggerUI:
from fastapi import FastAPI, Query, Depends
import uvicorn
from pydantic import BaseModel, Field
from typing import List
class QueryParams(BaseModel):
name: str = Field(...)
ages: List[int] = Field([])
app = FastAPI()
@app.get("/test")
def test(query: QueryParams = Depends()):
return "hi"
uvicorn.run(app)
Which means I cant test it in swagger UI. Even if I change field to query, it still doesn't work:
from fastapi import FastAPI, Query, Depends
import uvicorn
from pydantic import BaseModel, Field
from typing import List
class QueryParams(BaseModel):
name: str = Field(...)
ages: List[int] = Query([]) # <-- Query
app = FastAPI()
@app.get("/test")
def test(query: QueryParams = Depends()):
return "hi"
uvicorn.run(app)
If I put it in the route function, it works:
from fastapi import FastAPI, Query, Depends
import uvicorn
from pydantic import BaseModel, Field
from typing import List
class QueryParams(BaseModel):
name: str = Field(...)
app = FastAPI()
@app.get("/test")
def test(query: QueryParams = Depends(), ages: List[int] = Query([])):
return "hi"
uvicorn.run(app)
How can I get swagger UI to recognize a list query field in a basemodel with dependency injection?
As described in this answer, one can't use a List
field inside a Pydantic model and expect it to be a query
parameter. The way to do this is to implement your query parameter-parsing in a separate dependency class, as shown below:
class QueryParams:
def __init__(
self,
name: str,
ages: List[int] = Query(...)
):
self.name = name
self.ages = ages
@app.get("/test")
def test(query: QueryParams = Depends()):
return "hi"
The above can be re-written using the @dataclass
decorator, as shown below:
from dataclasses import dataclass
@dataclass
class QueryParams:
name: str
ages: List[int] = Query(...)
@app.get("/test")
def test(query: QueryParams = Depends()):
return "hi"
One could wrap the Query()
in a Field()
that would allow them to define a List
field as query parameter inside the Pydantic model. Complete working examples can be found in this answer and this answer.
from fastapi import Query
from pydantic import BaseModel, Field
from typing import List
class QueryParams(BaseModel):
name: str
ages: List[int] = Field(Query(...))