본문 바로가기

Fastapi

내맘대로 Fastapi Docs 정리(Query, Path, Body parameters)

Query parameters

from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(q: Union[str, None] = Query(default=None, max_length=50)):
  •  Union[str, None] 대신에 Optional[str] 혹은 str | None(python 3.10이상)을 쓸 수 있으며, Query는 추가적으로 validation을 달고 싶을 때 쓸 수 있다.
  • 다음과 같이 여러 validataion을 넣을 수 있으며, regex는 정규식이다. Query(default=None, min_length=3, max_length=50, regex="^fixedquery$")
  • default value가 None이거나, 특정 값이 들어가 있을 경우 required하지 않다는 뜻이되므로, required하다라는 의미를 전달해줄려면 ellipsis(...) 혹은, Required를 넣거나, default 옵션을 안주면 된다. q: str = Query(default=..., min_length=3)

query를 list로 넣고 싶을 때

from typing import List, Union

@app.get("/items/")
async def read_items(q: Union[List[str], None] = Query(default=None)):
    query_items = {"q": q}
    return query_items
  • curl로 보낼 때 주소는 다음과 같다. -> http://localhost:8000/items/?q=foo&q=bar

swagger 를 통해 보면,

  • q의 결과 값은 -> {"q": ["foo", "bar"]}
  • default로 list를 주고 싶을때, q: List[str] = Query(["foo", "bar"])
  • q: list = Query([])에서 list만 쓸 경우 list 안의 데이터를 check안하지만, List[int]는 int인지 check한다.

 

# title, description
@app.get("/items/")
async def read_items(
    q: Union[str, None] = Query(
        default=None,
        title="Query string",
        description="Query string for the items to search in the database that have a good match",
        min_length=3,
    )
):

# alias
@app.get("/items/")
async def read_items(q: Union[str, None] = Query(default=None, alias="item-query")):
  • Query에 title과 description을 넣어서, 추가적인 정보를 제공할 수 있으며, openapi를 통해 나타난다.
  • alias도 지정할 수 있는데, http://127.0.0.1:8000/items/?item-query=foobaritems 여기서 보통 python 변수는 snake_case로 item_query로 쓰는게 좋은데, item-query로 query를 보내고 싶을때, 혹은 다른 변수이름으로 보내고 싶을 때 alias를 지정할 수 있다.
  • deprecated=True 도 넣을 수 있는데 이건 더이상 해당 파라미터를 쓰기 싫은데 남겨둬야 할때 이렇게 
    선언하면 openapi에 표시되지만, query는 가능하다.

 

@app.get("/items/")
async def read_items(
    hidden_query: Union[str, None] = Query(default=None, include_in_schema=False)
):
  • 다음과 같이 include_in_schema=False를 지정할 수 있는데, 이는 openapi에서 request를 보낼때 해당 query를 제외시킬 수 있는데, default값이 없으면 422 에러가 뜬다. curl을 통해 query로 보내면 제대로 응답이 온다.

 

 

Path parameters

from fastapi import FastAPI, Path, Query
app = FastAPI()
@app.get("/items/{item_id}")
async def read_items(
    item_id: int = Path(..., title="The ID of the item to get"),
    q: Optional[str] = Query(None, alias="item-query"),
):

 

  • query같이 path도 지정할 수 있다.
  • ellipsis(...)를 지정하여 required라고 알려주는 것이 좋지만, None이나 다른값으로 default를 지정해도 아무런 영향을 끼치지 않는다.

 

@app.get("/items/{item_id}")
async def read_items(
    *, item_id: int = Path(title="The ID of the item to get", ge=1), q: str
):
  • bare *의 의미는 뒤에 keyword arguments만 받을 수 있다는 의미다.
  • numeric validations도 가능한데, path가 number 자료형일 경우 validation을 달 수 있다. (gt, lt, le, ge)

 

Body Multiple Parameters

from typing import Union

from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()

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


class User(BaseModel):
    username: str
    full_name: Union[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
  • 다음과 같이 여러개의 body를 지정할 수 있다. (Item, User)

 

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

 

  • 다음과 같이 pydantic type이 아니고 singular type이라면 body로 인식을 안하는데, Body()로 정의해주면 body로 인식한다.
  • 또한 path, query parameter처럼 validation을 넣어줄 수 있다.

 

item: Item = Body(..., embed=True)
  • 만약 body가 한개라면 item이라는 key가 생기지 않고 item 안의 항목들만 나올텐데 embed=True로 하면 key포함해서 전달해줘야한다. 안그러면 422 에러가 뜬다.