How to set Swagger UI to use List fields in query parameters using FastAPI?
Question:
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?
Answers:
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"
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"