프레임워크/FastAPI

[FastAPI] FastAPI [15] Response model 2 - Other Return Type Annotations

:) :) 2023. 4. 25. 14:06

https://fastapi.tiangolo.com/ko/tutorial/response-model/

 

Response Model - Return Type - FastAPI

Response Model - Return Type Warning The current page still doesn't have a translation for this language. But you can help translating it: Contributing. You can declare the type used for the response by annotating the path operation function return type. Y

fastapi.tiangolo.com

<FastAPI 공식문서 참조>

 

 

 

 

0. Other Return Type Annotations

유효한 Pydantic field가 아닌데도 함수에다가 주석을 달아놓았으면 여러 지원을 받을 수 있다.

 

1. Other Return Type Annotations

 가장 일반적인 경우는 응답을 직접 하고 상위의 docs에서 설명하는 것이다.

from fastapi import FastAPI, Response
from fastapi.responses import JSONResponse, RedirectResponse

app = FastAPI()


@app.get("/portal")
async def get_portal(teleport: bool = False) -> Response:
    if teleport:
        return RedirectResponse(url="https://www.youtube.com/watch?v=dQw4w9WgXcQ")
    return JSONResponse(content={"message": "Here's your interdimensional portal."})

 

2.  Annotate a Response Subclass

from fastapi import FastAPI
from fastapi.responses import RedirectResponse

app = FastAPI()


@app.get("/teleport")
async def get_teleport() -> RedirectResponse:
    return RedirectResponse(url="https://www.youtube.com/watch?v=dQw4w9WgXcQ")

이렇게 Responese의 서브클래스로 반환형을 지정해도 된다.

 

 

3. Invaild Return Type Annotations

  아래와 같은 예시는 응답이 실패한다.

from fastapi import FastAPI, Response
from fastapi.responses import RedirectResponse

app = FastAPI()


@app.get("/portal")
async def get_portal(teleport: bool = False) -> Response | dict:
    if teleport:
        return RedirectResponse(url="https://www.youtube.com/watch?v=dQw4w9WgXcQ")
    return {"message": "Here's your interdimensional portal."}

자료형 주석이 Response와 dictionary의 합집합 비슷한 자료형을 가지고 있기 때문에 특정하기 어려워 응답이 실패한다.

 

 

4. Disable Response Model

from fastapi import FastAPI, Response
from fastapi.responses import RedirectResponse

app = FastAPI()


@app.get("/portal", response_model=None)
async def get_portal(teleport: bool = False) -> Response | dict:
    if teleport:
        return RedirectResponse(url="https://www.youtube.com/watch?v=dQw4w9WgXcQ")
    return {"message": "Here's your interdimensional portal."}

이 skip과정은 응답모델 생성시간과 FastAPI application에 영향을 미치지 않게 해준다.

 

 

 

5. Use the response_model_exclude_unset parameter

경로동작 데코레이터 매개변수 response_model_exclude_unset 를 True로 설정할 수 있다.

 

from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()


class Item(BaseModel):
    name: str
    description: str | None = None
    price: float
    tax: float = 10.5
    tags: list[str] = []


items = {
    "foo": {"name": "Foo", "price": 50.2},
    "bar": {"name": "Bar", "description": "The bartenders", "price": 62, "tax": 20.2},
    "baz": {"name": "Baz", "description": None, "price": 50.2, "tax": 10.5, "tags": []},
}


@app.get("/items/{item_id}", response_model=Item, response_model_exclude_unset=True)
async def read_item(item_id: str):
    return items[item_id]

이러면 모든 기본값이 response에 포함되어있지 않고 설정되어만 있다.

 

이때 ID foo를 포함한 requset를 qhsoaus, response는 다음처럼 된다:

{
    "name": "Foo",
    "price": 50.2
}

 

5-1. Data with values for fields with defaults

 그러나 field에 기본값이 있는 model의 경우, 기본적으로 포함되게 된다.

{
    "name": "Bar",
    "description": "The bartenders",
    "price": 62,
    "tax": 20.2
}

 

6. response_model_include and response_model_exclude

 response model을  "포함" 하거나 "생략"할 수 있다. Pydantic model이 하나만 있고 여기서 일부 제거한 것을 출력하려 할 때 사용하면 빠르고 좋다.

from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()


class Item(BaseModel):
    name: str
    description: str | None = None
    price: float
    tax: float = 10.5


items = {
    "foo": {"name": "Foo", "price": 50.2},
    "bar": {"name": "Bar", "description": "The Bar fighters", "price": 62, "tax": 20.2},
    "baz": {
        "name": "Baz",
        "description": "There goes my baz",
        "price": 50.2,
        "tax": 10.5,
    },
}


@app.get(
    "/items/{item_id}/name",
    response_model=Item,
    response_model_include={"name", "description"},
)
async def read_item_name(item_id: str):
    return items[item_id]


@app.get("/items/{item_id}/public", response_model=Item, response_model_exclude={"tax"})
async def read_item_public_data(item_id: str):
    return items[item_id]

여기서, 아래가 해당하는 부분이다.

 response_model_include={"name", "description"},
@app.get("/items/{item_id}/public", response_model=Item, response_model_exclude={"tax"})

 

 

6-1. Using list s instead of set s

 set 대신 python의 기본 자료형인 list 혹은 tuple을 사용해도 된다. FastAPI는 똑똑해서 이를 set 자료형으로 잘 바꿔 해석할 것이다.

 

response_model_include=["name", "description"],
@app.get("/items/{item_id}/public", response_model=Item, response_model_exclude=["tax"])

 

 

7. Recap

  •  경로 동작 데코레이터 매개변수 response_model은 사적인 데이터를 필터링하여 response에 실어 보내기 위한 특별한 작업이다.
  •   response_model_exclude_unset은 값을 명시적으로 설정된 값들만으로 반환하기 위해 사용한다.

 

8. Reference

https://fastapi.tiangolo.com/tutorial/response-model/

 

Response Model - Return Type - FastAPI

Response Model - Return Type Warning The current page still doesn't have a translation for this language. But you can help translating it: Contributing. You can declare the type used for the response by annotating the path operation function return type. Y

fastapi.tiangolo.com