- input model
- output model
- database model
Multiple models
from typing import Union
from fastapi import FastAPI
from pydantic import BaseModel, EmailStr
app = FastAPI()
class UserIn(BaseModel):
username: str
password: str
email: EmailStr
full_name: Union[str, None] = None
class UserOut(BaseModel):
username: str
email: EmailStr
full_name: Union[str, None] = None
class UserInDB(BaseModel):
username: str
hashed_password: str
email: EmailStr
full_name: Union[str, None] = None
def fake_password_hasher(raw_password: str):
return "supersecret" + raw_password
def fake_save_user(user_in: UserIn):
hashed_password = fake_password_hasher(user_in.password)
user_in_db = UserInDB(**user_in.dict(), hashed_password=hashed_password)
print("User saved! ..not really")
return user_in_db
@app.post("/user/", response_model=UserOut)
async def create_user(user_in: UserIn):
user_saved = fake_save_user(user_in)
return user_saved
- password를 일반적으로 다루기 위한 예시 idea이다.
About **user_in.dict()
user_in = UserIn(username="john", password="secret", email="john.doe@example.com")
- Pydantic model들은 dict() method가 있다.
- return dict with the model's data
user_dict = user_in.dict()
Unwrapping a dict
- ** 연산이 붙으면, python은 dictionary로 unwrap해준다.
UserInDB(**user_dict)
UserInDB(
username="john",
password="secret",
email="john.doe@example.com",
full_name=None,
)
- 두 코드는 동일한 코드다.
- **user_in.dict()는 unwrap한 dict를 전해주는 것이라 이해하면 되겠다.
Reduce duplication
from typing import Union
from fastapi import FastAPI
from pydantic import BaseModel, EmailStr
app = FastAPI()
class UserBase(BaseModel):
username: str
email: EmailStr
full_name: Union[str, None] = None
class UserIn(UserBase):
password: str
class UserOut(UserBase):
pass
class UserInDB(UserBase):
hashed_password: str
def fake_password_hasher(raw_password: str):
return "supersecret" + raw_password
def fake_save_user(user_in: UserIn):
hashed_password = fake_password_hasher(user_in.password)
user_in_db = UserInDB(**user_in.dict(), hashed_password=hashed_password)
print("User saved! ..not really")
return user_in_db
@app.post("/user/", response_model=UserOut)
async def create_user(user_in: UserIn):
user_saved = fake_save_user(user_in)
return user_saved
- 이전에 선언한 코드에서 모델들은 너무 많은 데이터와 속성들을 중복으로 갖고, 공유하고 있었다. 이를 개선한 코드 예시다.
- Base로 Userbase를 갖은 채로, 이를 상속받은 것이다.
Union or anyOf
- 두개 이상의 Type에 대해서는 Union reponse를 선언한다.
List of models
from typing import List
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: str
items = [
{"name": "Foo", "description": "There comes my hero"},
{"name": "Red", "description": "It's my aeroplane"},
]
@app.get("/items/", response_model=List[Item])
async def read_items():
return items
- 모델들은 List로 reponse할 수 있다.
Response with arbitrary dict
from typing import Dict
from fastapi import FastAPI
app = FastAPI()
@app.get("/keyword-weights/", response_model=Dict[str, float])
async def read_keyword_weights():
return {"foo": 2.3, "bar": 3.4}
- key, value 형태로 Dict를 사용해 Pydantic 모델을 만들 수 있다.