None이 될 수 있는 필드가 Swagger에서 제대로 표시되지 않는 문제
async def read_items(q: List[str] | None = Query())처럼 None이 될 수 있는 필드가 Swagger에서 제대로 표시되지 않는 현상
Posted on 2024-03-31 by GKSRUDTN99
FastAPI
Python
FastAPI
FastAPI 공식 가이드에 나와있는 대로
from typing import List
from fastapi import FastAPI, Query
app = FastAPI()
@app.get('/items')
async def read_items(q: List[str] | None = Query(default=None)):
query_items = {"q": q}
return query_items
어떤 Query Parameter가 필수값이 아닐 때, 그냥 None을 쓰면, Swagger 상에서 제대로 테스트 할 수 있는 형태로 필드가 표시되지 않습니다.
openapi.json 파일을 열어보면 이유를 알 수 있는데,
...
"parameters": [
{
"name": "q",
"in": "query",
"required": false,
"schema": {
"anyOf": [
{
"type": "array",
"items": {
"type": "string"
}
},
{
"type": "null"
}
],
"title": "Q"
}
}
],
...
Q의 타입이 array가 아니라, anyOf로 감싸진 형태가 되기 때문인데요,
이 경우에는 Swagger 상에서 Array 타입으로 표시되지 않기 때문에, 정상적인 테스트가 불가합니다.
어느 정도는 FastAPI / Swagger 쪽 버그라고 생각되지만, FastAPI Github의 한 이슈 workaround를 찾았습니다.
None 대신 SkipJsonSchema[None] 형태로 사용하는 것입니다.
from typing import List
from fastapi import FastAPI, Query
from pydantic.json_schema import SkipJsonSchema
app = FastAPI()
@app.get('/items')
async def read_items(q: List[str] | SkipJsonSchema[None] = Query(default=None)):
query_items = {"q": q}
return query_items
이렇게 바꾸고 openapi.json 파일을 확인하면,
"parameters": [
{
"name": "q",
"in": "query",
"required": false,
"schema": {
"type": "array",
"items": {
"type": "string"
},
"title": "Q"
}
}
],
이렇게 Q의 타입이 array로 잘 잡히고, required도 false로 잘 들어가 있는 것을 확인할 수 있습니다.
여기서 주의할 점은,
= Query()
형태로 Default Value를 주지 않으면, Swagger 상에서 required=true인 상태로 표시될 수 있습니다.
따라서 Default Value를 명시해야 required=false로 표시됩니다.