๐ฐ FastAPI ๊ณต์๋ฌธ์๋ฅผ ๋ณด๋ฉด์ ๊ฐ์ธ์ ์ผ๋ก ์ ๋ฆฌํ ๊ธ ์
๋๋ค.
Type
FastAPI๋ ํ์ด์ฌ์ Type Annotation์ ๊ธฐ๋ฐ์ ๋๊ณ ์๋ค.
์ด๋ฅผ ํตํด ํ์ด์ฌ ๋ณ์๋ฅผ ์ ์ธํ๊ฑฐ๋ ํจ์์ ๊ฐ์ ๋ฆฌํดํ ๋ ํ์ ์ ์ง์ ํ ์ ์๋ค.
์ด๋ฌํ Type Annotation์ ":"์ ์ฌ์ฉํ์ฌ ๋ช ์ํ ์ ์๋ค.
(๋ฐํ ํ์ ์ "->" ๋ก ์ง์ )
Simple Type
- int
- float
- str
- bool ๋ฑ์ ํ์ด์ฌ ํ์คํ์
def getItem(a:int,b:float)->int:
return a+int(b)
result:int = getItem(1,1.5)
print(result)
ํ์ ๋งค๊ฐ๋ณ์๋ฅผ ํ์ฉํ Generic(์ ๋ค๋ฆญ) ํ์
- list, dict, set, tuple ๊ฐ์ ๊ฐ์ ์ ์ฅํ ์ ์๋ ๋ฐ์ดํฐ ๊ตฌ์กฐ์ ๋ด๋ถ๋ ๊ฐ์์ ํ์ ์ ๊ฐ์ง ์ ์๋ค.
- typing์ ์ด์ฉํด ๋ด๋ถ Type Annotation์ ์ง์ ํ ์ ์๋ค. (List, Dict, Set, Tuple)
from typing import List
def getItems(items: List[str]) -> None:
for item in items:
print(item)
getItems(["1", "2", "3", "4"])
from typing import Set, Tuple, Dict
def getItems1(it1: Tuple[int, int, float], it2: Set[int]) -> None:
for item in zip(it1, it2):
print(item)
def getItems2(dic: Dict[str, int]) -> None:
for k, v in dic.items():
print(k, v)
getItems1((1, 2, 1.0), {1, 2, 3})
getItems2({"h": 1, "b": 3, "e": 2})
Optional ํ์ ์ ์ฌ์ฉํด์ "์ ํ์ "์ผ๋ก ํ์ ์ ์ง์ ํ ์ ์๋ค.
from typing import Optional
def getItems(items: Optional[int] = None) -> None:
# ํญ์ int๊ฐ ์๋๋ผ None์ด ๋ ์๋ ์์
for item in items:
print(item)
getItems([1, 2, 3, None])
Union[X,Y] ํ์ ์ผ๋ก X ๋๋ Y ํ์ ์ ์ง์ ํ ์ ์๋ค.
from typing import Union
def getItems(items: list) -> Union[int, list]:
return items[:2]
d: Union[int, list] = None
d = getItems([1, 2, 3, 4])
print(d)
Pydantic
๋ฐ์ดํฐ ๊ฒ์ฆ(Validation)์ ์ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ด๋ค.
- ex) ๋ณต์กํ ์๋น์ค ๋ก์ง์์ ๊ฐ๋ฐ์๊ฐ ์ํ๋ ๋ฐฉํฅ์ผ๋ก ํ๋ฅด๊ฒ ๋ง๋ค์ด์ผ ํ๋, ์ฌ์ฉ์๋ค์ ์๋ชป๋ ์ ๋ ฅ์ผ๋ก ์ธํ ๋ฌธ์ ๋ฅผ ๋ฐฉ์งํ๊ธฐ ์ํด ํน์ ์ ํ๊ณผ ์ ์ฝ์กฐ๊ฑด์ ํตํด ๋ฐ์ดํฐ ๊ฒ์ฆ์ ํ๋ค.
ํ์ ์ ์ ์ฝ์กฐ๊ฑด ๋ณด์ฅ๊ณผ ์ถ๋ ฅ ๋ชจ๋ธ์ ์ ํ๊ณผ ์ ์ฝ์กฐ๊ฑด์ ๋ณด์ฅํ๋ค.
FastAPI์์ API ํธ์ถ ์ ์ถ๋ ฅ ๋ชจ๋ธ์ ์ ํ๊ณผ ์ ์ฝ์กฐ๊ฑด์ ๋ณด์ฅ์ํค๊ธฐ ์ํด ์ฌ์ฉํ๋ค ์๊ฐํ๋ฉด ๋๋ค.
pip install pydantic
from pydantic import BaseModel
from typing import Union
class Item(BaseModel):
name: str
desc: Union[str, None] = None
price: float
tax: Union[float, None] = None
if __name__ == "__main__":
data = {
'name': 'toy',
'desc': '์ฅ๋๊ฐ',
'price': 4.7,
'tax': 0.2
}
toy = Item(**data)
print(toy)
print()
data = {
'name': 'toy',
'desc': '์ฅ๋๊ฐ',
'price': 'dd',
'tax': 0.2
}
toy = Item(**data)
print(toy)
ํ์ ์ ๋ง์ง ์์ ๊ฐ์ ์ ๋ฌ์ ์๋ฌ ๋ฐ์
๐ฅ ์ ์๋์ง ์์ ๊ฐ์ด ๋ค์ด๊ฐ๊ฑฐ๋ ๋ณํ ๊ฐ๋ฅํ ๊ฒฝ์ฐ ์ ์๋ ํ๋์ ๋ง๋๋ก ์ฒ๋ฆฌํด์ค.
Constrained types์ ์ฌ์ฉํด ์์ ์ ์ ํ์ ์ ์ฉํ ์ ์๋ค.
from pydantic import BaseModel, constr, conint
class Person(BaseModel):
f_name: str
# 3 <= ๋ฌธ์์ด ๊ธธ์ด <= 4
l_name: constr(min_length=3, max_length=4)
# 1 <= ๊ฐ <= 25
age: conint(ge=1, le=25)
if __name__ == "__main__":
data = {
'f_name': "Pupba",
'l_name': "Jung",
'age': 25
}
p = Person(**data)
print(p)
Validator decorator๋ฅผ ์ฌ์ฉํด์ ์์ฒด์ ์ธ ๊ท์น์ ๋ง๋ค์ด ๋ฐ์ดํฐ ๊ฒ์ฌ๋ฅผ ํ ์ ์๋ค.
from pydantic import BaseModel, validator, ValidationError
from typing import Union
class Person(BaseModel):
name: str
age: int
# ์ด๋ฆ ๊ฒ์ฌ
@validator('name')
def name_must_english(cls, v):
assert v.encode().isalpha(), ValidationError('Name Must be english')
return v
# ๋์ด ๊ฒ์ฌ
@validator('age')
def is_adult(cls, v):
if v <= 19:
raise ValidationError('์ ์ก์ด ๊ตฌ๋ง')
return v
if __name__ == "__main__":
data = {
'name': "pupba",
'age': 15
}
try:
pupba = Person(**data)
print(pupba)
except ValidationError as e:
print(e)
Model๋ก๋ถํฐ JSON์ ๋ง๋๋ ๊ฒ๋ ๊ฐ๋ฅํ๋ค.
from pydantic import BaseModel
class Person(BaseModel):
f_name: str
l_name: str
age: int
if __name__ == "__main__":
data = {
'f_name': "Pupba",
'l_name': "Jung",
'age': 25
}
json = Person(**data).model_dump_json()
print(json)
์์ฑ๋ ๋ชจ๋ธ์ model_dump_json()๋ก JSON์ผ๋ก ๋ณํํ ์ ์๋ค.
'Back-end & Server > FastAPI' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[FastAPI] Form (0) | 2024.02.20 |
---|---|
[FastAPI] ๋ชจ๋ธ (0) | 2024.02.20 |
[FastAPI] ๋งค๊ฐ๋ณ์ (0) | 2024.02.20 |
[FastAPI] ๋์์ฑ๊ณผ async / await (0) | 2024.02.19 |
[FastAPI] ๊ฐ์ (0) | 2024.02.19 |