본문 바로가기
코딩/FastAPI

FastAPI 배우기 - Body - Multiple Parameters

by 형큐 2023. 6. 27.
SMALL

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

https://fastapi.tiangolo.com/ko/tutorial/body-multiple-params/

 

Body - Multiple Parameters - FastAPI

FastAPI framework, high performance, easy to learn, fast to code, ready for production

fastapi.tiangolo.com


Query, Path, Request Body 함께 사용하기

물론 경로, 쿼리, 요청 본문 매개변수 선언을 자유롭게 혼합할 수 있으며, FastAPI는 무엇을 해야 할지 알고 있습니다.

또한 기본값을 없음으로 설정하여 본문 매개변수를 선택 사항으로 선언할 수도 있습니다:

from typing import Annotated

from fastapi import FastAPI, Path
from pydantic import BaseModel

app = FastAPI()

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

@app.put("/items/{item_id}")
async def update_item(
    item_id: Annotated[int, Path(title="The ID of the item to get", ge=0, le=1000)],
    q: str | None = None,
    item: Item | None = None,
):
    results = {"item_id": item_id}
    if q:
        results.update({"q": q})
    if item:
        results.update({"item": item})
    return results

🍳 이 경우, 바디로 부터 받아지는 item은 선택사항이고, None을기본값으로 갖는다는 것을 잊지말자

다중 바디 매개변수

이전 예제에서 경로 작업은 다음과 같이 항목의 속성이 있는 JSON 본문을 기대합니다:

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

그러나 항목 및 사용자 등 여러 개의 본문 매개 변수를 선언할 수도 있습니다:

from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()

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

class User(BaseModel):
    username: str
    full_name: str | None = 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 results

이 경우 FastAPI는 함수에 두 개 이상의 본문 매개변수가 있음을 알 수 있습니다(Pydantic 모델인 매개변수 두 개).

따라서 매개변수 이름을 본문의 키(필드 이름)로 사용하고 다음과 같은 본문이 예상됩니다:

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

🍳Note 이전과 동일한 방식으로 아이템이 선언되었지만, 이제 키 아이템과 함께 본문 내부에 있을 것으로 예상됩니다.

FastAPI는 요청에서 자동 변환을 수행하여 매개변수 항목이 특정 콘텐츠를 수신하고 사용자에게도 동일한 콘텐츠를 수신하도록 합니다.

복합 데이터의 유효성 검사를 수행하고 이를 OpenAPI 스키마 및 자동 문서에 맞게 문서화합니다.

바디 내부의 단일 값

쿼리 및 경로 매개변수에 대한 추가 데이터를 정의하는 쿼리 및 경로가 있는 것과 같은 방식으로 FastAPI는 이에 상응하는 본문(Body)을 제공합니다.

예를 들어 이전 모델을 확장하여 항목과 사용자 외에 다른 주요 중요도를 동일한 바디에 포함시키기로 결정할 수 있습니다.

이 값은 단수 값이므로 그대로 선언하면 FastAPI는 이를 쿼리 매개변수로 간주합니다.

그러나 Body를 사용하여 다른 본문 키로 취급하도록 FastAPI에 지시할 수 있습니다:

from typing import Annotated

from fastapi import Body, FastAPI
from pydantic import BaseModel

app = FastAPI()

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

class User(BaseModel):
    username: str
    full_name: str | None = None

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

이 경우 FastAPI는 다음과 같은 본문이 예상됩니다:

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

다중 바디 매개변수와 쿼리

물론 필요할 때마다 본문 매개변수 외에 추가 쿼리 매개변수를 선언할 수도 있습니다.

기본적으로 단수 값은 쿼리 매개변수로 해석되므로 쿼리를 명시적으로 추가할 필요 없이 그냥 추가하면 됩니다:

q: Union[str, None] = None

Or in Python 3.10 and above:

q: str | None = None

예를들어

from typing import Annotated

from fastapi import Body, FastAPI
from pydantic import BaseModel

app = FastAPI()

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

class User(BaseModel):
    username: str
    full_name: str | None = None

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

❗INFO 본문에는 쿼리, 경로 및 나중에 보게 될 다른 매개변수와 동일한 추가 유효성 검사 및 메타데이터 매개변수도 모두 있습니다.

단일 바디 매개변수 삽입

Pydantic 모델 항목에서 항목 본문 매개변수가 하나만 있다고 가정해 보겠습니다.

그러면 기본적으로 FastAPI는 해당 본문을 직접 기대합니다.

그러나 추가 본문 매개변수를 선언할 때와 마찬가지로 키 항목과 그 안에 모델 콘텐츠가 포함된 JSON을 기대하려면 특수 본문 매개변수 임베드를 사용할 수 있습니다:

item: Item = Body(embed=True)

as in:

from typing import Annotated

from fastapi import Body, FastAPI
from pydantic import BaseModel

app = FastAPI()

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

@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Annotated[Item, Body(embed=True)]):
    results = {"item_id": item_id, "item": item}
    return results

이 경우 FastAPI는 다음과 같은 본문이 예상됩니다:

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

instead of:

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

요약

요청에 하나의 본문만 있을 수 있지만 경로 연산 함수에 여러 본문 매개변수를 추가할 수 있습니다.

하지만 FastAPI는 이를 처리하고, 함수에 올바른 데이터를 제공하며, 경로 연산에서 올바른 스키마의 유효성을 검사하고 문서화합니다.

본문의 일부로 수신할 단수 값을 선언할 수도 있습니다.

그리고 선언된 매개변수가 하나만 있는 경우에도 FastAPI가 키에 본문을 포함하도록 지시할 수 있습니다.

반응형

 

반응형
LIST