Fast API, Body - Multiple Parameters, Field

Junha Kim·2021년 1월 6일
0

FastAPI

목록 보기
10/16

Mixed Path, Query, Request Body parameter

이제 모든 parameter들의 선언 방법에 대해 알아보았으니, 아래의 코드를 보며 어떤 parameter인지 보자.

class Item(BaseModel):
    name: str
    description: Optional[str] = None
    price: float
    tax: Optional[float] = None

@app.put("/items/{item_id}")
async def update_item(
    *,
    item_id: int = Path(..., title="The ID of the item to get", ge=0, le=1000),
    q: Optional[str] = None,
    item: Optional[Item] = None,
):
    results = {"item_id": item_id}
    if q:
        results.update({"q": q})
    if item:
        results.update({"item": item})
    return results
  • item_id : path parameter (required) → URL 에 명시
  • q : query parameter (optional) → URL X, Pydantic Model X
  • item : request body (optionval) → URL X, Pydantic Model O

Multiple Body Parameters

request body에 필요한 parameter들이 여러개일때는 아래와 같이 선언할 수 있다.

class Item(BaseModel):
    name: str
    description: Optional[str] = None
    price: float
    tax: Optional[float] = None

class User(BaseModel):
    username: str
    full_name: Optional[str] = None

@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item, user: User):
    results = {"item_id": item_id, "item": item, "user": user}
    return resul

위와 같이 선언되면, request body의 내용은 아래와 같은 형식이 되어야한다.

{
    "item": {
        "name": "Foo",
        "description": "The pretender",
        "price": 42.0,
        "tax": 3.2
    },
    "user": {
        "username": "dave",
        "full_name": "Dave Grohl"
    }
}

Fast API는 해당 json 형식을 파악하여 자동으로 ItemUser model로 converting과 validation check을 하며 바꾸게 된다.


Singular Values in Body

Request Body는 Pydantic 모델을 설정하여 해당 Type을 명시하여 받는 것으로 Body parameter로 판단했다.

하지만 여러개의 변수를 캡슐화한 Pydantic 모델이 아닌, 단일 변수로 받고 싶을 때는 어떻게 해야될까?

이를 위해 Fast API는 Body라는 것이 존재한다.

from fastapi import Body, FastAPI

@app.put("/items/{item_id}")
async def update_item(
    *,
    item_id: int,
    item: Item,
    user: User,
    importance: int = Body(..., gt=0),
    q: Optional[str] = None
):
    results = {"item_id": item_id, "item": item, "user": user, "importance": importance}
    if q:
        results.update({"q": q})
    return results

Query/Path와 똑같이 metadata 또한 설정할 수 있다. 위와 같이 선언될 경우 request body는 아래와 같은 형식이다.

{
    "item": {
        "name": "Foo",
        "description": "The pretender",
        "price": 42.0,
        "tax": 3.2
    },
    "user": {
        "username": "dave",
        "full_name": "Dave Grohl"
    },
    "importance": 5
}

Embed a single body parameter

만약 request body parameter로 단 하나의 모델만이 필요할 때는 embed변수를 True로 하여 body 구조를 바꿀 수 있다.

이전의 구조는 아래와 같았다면,

{
    "name": "Foo",
    "description": "The pretender",
    "price": 42.0,
    "tax": 3.2
}
@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item = Body(..., embed=True)):
    results = {"item_id": item_id, "item": item}
    return results

embed=True로 설정해준 뒤의 구조는 아래처럼 된다.

{
    "item": {
        "name": "Foo",
        "description": "The pretender",
        "price": 42.0,
        "tax": 3.2
    }
}

Field

Pydantic 모델 또한 validation이나 meatadata를 추가할 수 있다.

먼저 pydantic 모듈에서 Field를 import 한다.

from pydantic import BaseModel, Field

이후, metadata나 validation 조건을 설정해주고 싶은 필드에 작성하면 된다.

class Item(BaseModel):
    name: str
    description: Optional[str] = Field(
        None, title="The description of the item", max_length=300
    )
    price: float = Field(..., gt=0, description="The price must be greater than zero")
    tax: Optional[float] = None

Query, Path, Body 모두 같은 역할을 하는 것이다.


Note

Fast API 공식 문서에 따르면, Query, Path는 함수라고 한다. Pydantic의 FieldInfo 클래스의 하위 클래스인 Param의 객체를 생성하여 return한다고 한다. 반면에 Body나 FieldFieldInfo 클래스 객체 생성자이며, 위의 함수들과는 엄밀히 보자면 다르다고 한다.

0개의 댓글