본격적인 포스팅에 들어가기전 간단하게 HTTP를 통한 통신 메서드4가지를 정리하려고 한다.
Client즉, 우리의 컴퓨터가 Server와 통신하기 위해서는 HTTP의 method를 사용해야하는데 이때 주로 사용되는
것이 GET, POST, PUT, DELETE이다.
GET은 조회를 하는것 즉, 서버에 있는 데이터를 읽는 것이다.
POST는 서버에 데이터를 생성하는것, 등록하는것이다.
PUT은 서버에 있는 데이터를 변경하고 수정하는것이다.
DELETE는 서버에 있는 데이터를 삭제하는 것이다.
클라이언트에서 API를 통하여 데이터를 보내고 싶을때, request body를 사용하여 보낼 수 있는데, request body를 정의를 할때 Pydantic과 함께 사용할 수 있다.
생성, 수정, 삭제 같은 경우에는 상황에 맞는 http method와 함께 response를 하면되지만, GET메서드와 함께 body를 보내는 것은 이상한 행동임을 이해할것이다...
** Pydentic의 BaseModel클래스를 상속받는 data model을 선언해보자
from typing import Union
from fastapi import FastAPI
from pydantic import BaseModel
class Item(BaseModel):
name: str
description: Union[str, None] = None
price: float
tax: Union[float, None] = None
app = FastAPI()
@app.post("/items/")
async def create_item(item: Item):
return item
data model을 선언할때에도 query파라미터를 선언할때와 마찬가지로 필수와 선택, default값 등을 부여할 수 있다.
위의 내용을 JSON으로 변환되면 아래와 같다.
"name": "Foo",
"description": "An optional description",
"price": 45.2,
"tax": 3.5
이때, description과 tax는 optional하기 때문에 제외해도 무관하다.
파이썬의 타입 선언과 마찬가지로, FastAPI에서는
from typing import Union
from fastapi import FastAPI
from pydantic import BaseModel
class Item(BaseModel):
name: str
description: Union[str, None] = None
price: float
tax: Union[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
(여기서 FastAPI는 자동적으로 함수의 파라미터에서 path로 부터 받은 것은 path 파라미터로 인식을 하고, Pydantic 모델로 선언된것은 request body로 인식한다.)
from typing import Union
from fastapi import FastAPI
from pydantic import BaseModel
class Item(BaseModel):
name: str
description: Union[str, None] = None
price: float
tax: Union[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()}
마지막 return값에 items.dict() 앞에 **
가 붙은것이 보인다.
**
이 기호는 Python에서 dictionary unpacking 또는 dictionary expansion이라고 불리는 문법으로 이 기호를 사용하게 되면 딕셔너리의 키-값 쌍을 다른 딕셔너리에 풀어서(펼쳐서)병합할 수 있다.
예를 들어 아래와 같은 경우가 있다.
dict1 = {"a": 1, "b": 2}
dict2 = {"c": 3, "d": 4}
merged_dict = {**dict1, **dict2}
print(merged_dict) # 출력: {'a': 1, 'b': 2, 'c': 3, 'd': 4}
우리의 예시의 경우는 item을 dict형태로 바꾸었으며 return되는 dict에 펼쳐져서 나오는 형태로
만들기 위해서 기호를 넣은것이다.
from typing import Union
from fastapi import FastAPI
from pydantic import BaseModel
class Item(BaseModel):
name: str
description: Union[str, None] = None
price: float
tax: Union[float, None] = None
app = FastAPI()
@app.put("/items/{item_id}")
async def create_item(item_id: int, item: Item, q: Union[str, None] = None):
result = {"item_id": item_id, **item.dict()}
if q:
result.update({"q": q})
return result