본문 바로가기
코딩/FastAPI

FastAPI 배우기 - Request body

by 형큐 2023. 6. 26.
SMALL

공식 문서를 번역한 내용입니다.

https://fastapi.tiangolo.com/ko/tutorial/body/

 

Request Body - FastAPI

Request Body Warning The current page still doesn't have a translation for this language. But you can help translating it: Contributing. When you need to send data from a client (let's say, a browser) to your API, you send it as a request body. A request b

fastapi.tiangolo.com


Request body & Response body란?

  • Request Body : 클라이언트가 API로 데이터를 보낼때 사용되는 데이터
  • Response Body : API가 request의 응답으로 클라이언트에게 보내는 데이터

API는 거의 항상 response body를 클라이언트에게 보내야 한다. 하지만 클라이언트는 꼭 request body를 보내지 않아도 된다.

request body를 선언하기 위해, pydantic 모델을 사용한다.

Pydantic의 BaseModel 임포트

우선, pydantic으로부터 BaseModel을 임포트 한다.

from fastapi import FastAPI
from pydantic import BaseModel

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

app = FastAPI()

@app.post("/items/")
async def create_item(item: Item):
    return item

데이터 모델 생성

BaseModel을 상속받는 데이터 모델을 클래스로 선언한다.

모든 어트리뷰트엔 표준 파이썬 모델을 사용한다.

from fastapi import FastAPI
from pydantic import BaseModel

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

app = FastAPI()

@app.post("/items/")
async def create_item(item: Item):
    return item

쿼리 매개변수와 비슷하게 기본값을 넣어줄 수 있고, None값을 넣어주면 선택값이 되고, 아무값도 넣어주지 않으면 필수값이 된다

예를 들어, 위의 모델은 다음과 같은 JSON ”object” (또는 python dict)를 선언한다.

{
    "name": "Foo",
    "description": "An optional description",
    "price": 45.2,
    "tax": 3.5
}

description 과 tax가 (None을 기본값으로 하는) 선택 사항이기 때문에, 아래와 같은 JSON “object”도 유효하다.

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

매개변수로 선언

경로 동작에 추가하기 위해, 경로와 쿼리 매개변수를 선언했던 것과 같은 방식을 사용하자

from fastapi import FastAPI
from pydantic import BaseModel

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

app = FastAPI()

@app.post("/items/")
async def create_item(item: Item):
    return item

그리고 만든 item으로 그 자료형을 선언하면 된다.

결론

  • request에서 JSON으로 데이터를 읽는다.
  • (만약 필요하다면) 해당하는 자료형으로 변환시킨다
  • 데이터 유효성 검사를 진행함
    • 만약 데이터가 유효하지 않다면 clear error를 리턴하며 정확히 어떤 데이터가 문제인지 명시해준다
  • 매개변수에 있는 item을 받아온다
    • 만약 item의 매개변수들을 선언하였다면, 편집기에서 자동완성 기능을 사용할 수 있다
  • 프로그래머가 작성한 클래스 모델에 맞춰 JSON Schema를 만들어낸다
  • 이 schemas는 생성된 OpenAPI schema의 일부가 되고, Swagger와 같은 자동완성 문서에 사용된다.

모델 사용

함수 내부에서, 모델 객체의 모든 어트리뷰트에 바로 접근 할 수 있다.

from fastapi import FastAPI
from pydantic import BaseModel

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

app = FastAPI()

@app.post("/items/")
async def create_item(item: Item):
    item_dict = item.dict()
    if item.tax:
        price_with_tax = item.price + item.tax
        item_dict.update({"price_with_tax": price_with_tax})
    return item_dict

Request Body + 경로 매개변수

경로 매개변수와 Request Body를 동시에 선언할 수 있다.

FastAPI는 경로 매개변수와 일치하는 함수 매개변수를 경로에서 가져와야 하며, Pydantic 모델로 선언된 함수 매개변수를 Request Body에서 가져와야 한다고 인식한다.

from fastapi import FastAPI
from pydantic import BaseModel

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

app = FastAPI()

@app.put("/items/{item_id}")
async def create_item(item_id: int, item: Item):
    return {"item_id": item_id, **item.dict()}

Request Body + 경로 + 쿼리 매개변수

body, 경로 그리고 쿼리 매개변수 또한 동시에 선언할 수 있다.

FastAPI는 그것들을 각각 인지하고 데이터를 올바른 위치에서 가져온다.

from fastapi import FastAPI
from pydantic import BaseModel

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

app = FastAPI()

@app.put("/items/{item_id}")
async def create_item(item_id: int, item: Item, q: str | None = None):
    result = {"item_id": item_id, **item.dict()}
    if q:
        result.update({"q": q})
    return result

함수 매개변수는 다음과 같이 인지된다.

  1. Parameter가 Path에 정의되어 있으면 path로 해석한다
  2. path를 제외하고 sigular type(int, float, bool str, etc)이면 query parameter로 해석한다
  3. Parameter가 Pydantic Model로 정의되어 있으면 Request Body로 해석한다

🍳 FastAPI는 기본값이 = None이기 때문에 q의 값이 필수로 요구되지 않는다는 걸 알게 된다 Union[str] 속 Union은 FastAPI에 의해 사용되지 않지만, 편집기가 코드 속 오류를 찾는데 도움을 준다.

Without Pydantic

Pydantic model을 사용하지 않는다면 Body Parametes에 넣는 방법도 있다

https://fastapi.tiangolo.com/ko/tutorial/body-multiple-params/#singular-values-in-body

반응형
LIST