Skip to content

โž• ๐Ÿท

โ–ถ๏ธ โฎ๏ธ โฎ๏ธ ๐Ÿ–ผ, โšซ๏ธ ๐Ÿ”œ โš  โœ”๏ธ ๐ŸŒ… ๐ŸŒ˜ 1๏ธโƒฃ ๐Ÿ”— ๐Ÿท.

๐Ÿ‘‰ โœด๏ธ ๐Ÿ’ผ ๐Ÿ‘ฉโ€๐Ÿ’ป ๐Ÿท, โ†ฉ๏ธ:

  • ๐Ÿ”ข ๐Ÿท ๐Ÿ’ช ๐Ÿ’ช โœ”๏ธ ๐Ÿ”.
  • ๐Ÿ”ข ๐Ÿท ๐Ÿ”œ ๐Ÿšซ โœ”๏ธ ๐Ÿ”.
  • ๐Ÿ’ฝ ๐Ÿท ๐Ÿ”œ ๐ŸŽฒ ๐Ÿ’ช โœ”๏ธ #๏ธโƒฃ ๐Ÿ”.

Danger

๐Ÿ™… ๐Ÿช ๐Ÿ‘ฉโ€๐Ÿ’ป ๐Ÿ”ข ๐Ÿ”. ๐Ÿ•ง ๐Ÿช "๐Ÿ” #๏ธโƒฃ" ๐Ÿ‘ˆ ๐Ÿ‘† ๐Ÿ’ช โคด๏ธ โœ”.

๐Ÿšฅ ๐Ÿ‘† ๐Ÿšซ ๐Ÿ’ญ, ๐Ÿ‘† ๐Ÿ”œ ๐Ÿ’ก โšซ๏ธโ” "๐Ÿ”#๏ธโƒฃ" ๐Ÿ’‚โ€โ™‚ ๐Ÿ“ƒ.

๐Ÿ’— ๐Ÿท

๐Ÿ“ฅ ๐Ÿข ๐Ÿ’ญ โ” ๐Ÿท ๐Ÿ’ช ๐Ÿ‘€ ๐Ÿ’– โฎ๏ธ ๐Ÿ‘ซ ๐Ÿ” ๐Ÿ‘ & ๐Ÿฅ‰ ๐ŸŒโ” ๐Ÿ‘ซ โš™๏ธ:

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
from fastapi import FastAPI
from pydantic import BaseModel, EmailStr

app = FastAPI()


class UserIn(BaseModel):
    username: str
    password: str
    email: EmailStr
    full_name: str | None = None


class UserOut(BaseModel):
    username: str
    email: EmailStr
    full_name: str | None = None


class UserInDB(BaseModel):
    username: str
    hashed_password: str
    email: EmailStr
    full_name: 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

๐Ÿ”ƒ **user_in.dict()

Pydantic .dict()

user_in Pydantic ๐Ÿท ๐ŸŽ“ UserIn.

Pydantic ๐Ÿท โœ”๏ธ .dict() ๐Ÿ‘ฉโ€๐Ÿ”ฌ ๐Ÿ‘ˆ ๐Ÿ“จ dict โฎ๏ธ ๐Ÿท ๐Ÿ’ฝ.

, ๐Ÿšฅ ๐Ÿ‘ฅ โœ Pydantic ๐ŸŽš user_in ๐Ÿ’–:

user_in = UserIn(username="john", password="secret", email="john.doe@example.com")

& โคด๏ธ ๐Ÿ‘ฅ ๐Ÿค™:

user_dict = user_in.dict()

๐Ÿ‘ฅ ๐Ÿ”œ โœ”๏ธ dict โฎ๏ธ ๐Ÿ’ฝ ๐Ÿ”ข user_dict (โšซ๏ธ dict โ†ฉ๏ธ Pydantic ๐Ÿท ๐ŸŽš).

& ๐Ÿšฅ ๐Ÿ‘ฅ ๐Ÿค™:

print(user_dict)

๐Ÿ‘ฅ ๐Ÿ”œ ๐Ÿคš ๐Ÿ dict โฎ๏ธ:

{
    'username': 'john',
    'password': 'secret',
    'email': 'john.doe@example.com',
    'full_name': None,
}

๐ŸŽ dict

๐Ÿšฅ ๐Ÿ‘ฅ โœŠ dict ๐Ÿ’– user_dict & ๐Ÿšถโ€โ™€๏ธ โšซ๏ธ ๐Ÿ”ข (โš–๏ธ ๐ŸŽ“) โฎ๏ธ **user_dict, ๐Ÿ ๐Ÿ”œ "๐ŸŽ" โšซ๏ธ. โšซ๏ธ ๐Ÿ”œ ๐Ÿšถโ€โ™€๏ธ ๐Ÿ”‘ & ๐Ÿ’ฒ user_dict ๐Ÿ”— ๐Ÿ”‘-๐Ÿ’ฒ โŒ.

, โ–ถ๏ธ โฎ๏ธ user_dict โšช๏ธโžก๏ธ ๐Ÿ”›, โœ:

UserInDB(**user_dict)

๐Ÿ”œ ๐Ÿ ๐Ÿ•ณ ๐ŸŒ“:

UserInDB(
    username="john",
    password="secret",
    email="john.doe@example.com",
    full_name=None,
)

โš–๏ธ ๐ŸŒ… โšซ๏ธโ”, โš™๏ธ user_dict ๐Ÿ”—, โฎ๏ธ โšซ๏ธโ” ๐ŸŽš โšซ๏ธ ๐Ÿ’ช โœ”๏ธ ๐Ÿ”ฎ:

UserInDB(
    username = user_dict["username"],
    password = user_dict["password"],
    email = user_dict["email"],
    full_name = user_dict["full_name"],
)

Pydantic ๐Ÿท โšช๏ธโžก๏ธ ๐ŸŽš โž•1๏ธโƒฃ

๐Ÿ–ผ ๐Ÿ”› ๐Ÿ‘ฅ ๐Ÿคš user_dict โšช๏ธโžก๏ธ user_in.dict(), ๐Ÿ‘‰ ๐Ÿ“Ÿ:

user_dict = user_in.dict()
UserInDB(**user_dict)

๐Ÿ”œ ๐ŸŒ“:

UserInDB(**user_in.dict())

...โ†ฉ๏ธ user_in.dict() dict, & โคด๏ธ ๐Ÿ‘ฅ โš’ ๐Ÿ "๐ŸŽ" โšซ๏ธ ๐Ÿšถโ€โ™€๏ธ โšซ๏ธ UserInDB ๐Ÿ”  โฎ๏ธ **.

, ๐Ÿ‘ฅ ๐Ÿคš Pydantic ๐Ÿท โšช๏ธโžก๏ธ ๐Ÿ’ฝ โž•1๏ธโƒฃ Pydantic ๐Ÿท.

๐ŸŽ dict & โž• ๐Ÿ‡จ๐Ÿ‡ป

& โคด๏ธ โŽ โž• ๐Ÿ‡จ๐Ÿ‡ป โŒ hashed_password=hashed_password, ๐Ÿ’–:

UserInDB(**user_in.dict(), hashed_password=hashed_password)

...๐Ÿ”š ๐Ÿ†™ ๐Ÿ’†โ€โ™‚ ๐Ÿ’–:

UserInDB(
    username = user_dict["username"],
    password = user_dict["password"],
    email = user_dict["email"],
    full_name = user_dict["full_name"],
    hashed_password = hashed_password,
)

Warning

๐Ÿ”— ๐ŸŒ– ๐Ÿ”ข ๐Ÿค– ๐Ÿ’ช ๐Ÿ’ง ๐Ÿ’ฝ, โœ‹๏ธ ๐Ÿ‘ซ โ†—๏ธ ๐Ÿšซ ๐Ÿšš ๐Ÿ™† ๐ŸŽฐ ๐Ÿ’‚โ€โ™‚.

๐Ÿ“‰ โŽ

๐Ÿ“‰ ๐Ÿ“Ÿ โŽ 1๏ธโƒฃ ๐Ÿš ๐Ÿ’ญ FastAPI.

๐Ÿ“Ÿ โŽ ๐Ÿ“ˆ ๐Ÿคž ๐Ÿ›, ๐Ÿ’‚โ€โ™‚ โ”, ๐Ÿ“Ÿ ๐Ÿ” โ” (๐Ÿ•โ” ๐Ÿ‘† โ„น 1๏ธโƒฃ ๐Ÿฅ‰ โœ‹๏ธ ๐Ÿšซ ๐ŸŽ), โ™’๏ธ.

& ๐Ÿ‘‰ ๐Ÿท ๐ŸŒ ๐Ÿค ๐Ÿ“š ๐Ÿ’ฝ & โŽ ๐Ÿ”ข ๐Ÿ“› & ๐Ÿ†Ž.

๐Ÿ‘ฅ ๐Ÿ’ช ๐Ÿ‘ป.

๐Ÿ‘ฅ ๐Ÿ’ช ๐Ÿ“ฃ UserBase ๐Ÿท ๐Ÿ‘ˆ ๐Ÿฆ ๐Ÿงข ๐Ÿ‘† ๐ŸŽ ๐Ÿท. & โคด๏ธ ๐Ÿ‘ฅ ๐Ÿ’ช โš’ ๐Ÿฟ ๐Ÿ‘ˆ ๐Ÿท ๐Ÿ‘ˆ ๐Ÿ˜– ๐Ÿšฎ ๐Ÿ”ข (๐Ÿ†Ž ๐Ÿ“„, ๐Ÿ”ฌ, โ™’๏ธ).

๐ŸŒ ๐Ÿ’ฝ ๐Ÿ› ๏ธ, ๐Ÿ”ฌ, ๐Ÿงพ, โ™’๏ธ. ๐Ÿ”œ ๐Ÿ‘ท ๐Ÿ›Ž.

๐Ÿ‘ˆ ๐ŸŒŒ, ๐Ÿ‘ฅ ๐Ÿ’ช ๐Ÿ“ฃ ๐Ÿ”บ ๐Ÿ–– ๐Ÿท (โฎ๏ธ ๐Ÿ”ข password, โฎ๏ธ hashed_password & ๐Ÿต ๐Ÿ”):

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
from fastapi import FastAPI
from pydantic import BaseModel, EmailStr

app = FastAPI()


class UserBase(BaseModel):
    username: str
    email: EmailStr
    full_name: 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

Union โš–๏ธ anyOf

๐Ÿ‘† ๐Ÿ’ช ๐Ÿ“ฃ ๐Ÿ“จ Union 2๏ธโƒฃ ๐Ÿ†Ž, ๐Ÿ‘ˆ โ›“, ๐Ÿ‘ˆ ๐Ÿ“จ ๐Ÿ”œ ๐Ÿ™† 2๏ธโƒฃ.

โšซ๏ธ ๐Ÿ”œ ๐Ÿ”ฌ ๐Ÿ—„ โฎ๏ธ anyOf.

๐Ÿ‘ˆ, โš™๏ธ ๐Ÿฉ ๐Ÿ ๐Ÿ†Ž ๐Ÿ”‘ typing.Union:

Note

๐Ÿ•โ” โš– Union, ๐Ÿ”Œ ๐Ÿ† ๐ŸŽฏ ๐Ÿ†Ž ๐Ÿฅ‡, โฉ ๐ŸŒ˜ ๐ŸŽฏ ๐Ÿ†Ž. ๐Ÿ–ผ ๐Ÿ”›, ๐ŸŒ– ๐ŸŽฏ PlaneItem ๐Ÿ‘Ÿ โญ CarItem Union[PlaneItem, CarItem].

from typing import Union

from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()


class BaseItem(BaseModel):
    description: str
    type: str


class CarItem(BaseItem):
    type: str = "car"


class PlaneItem(BaseItem):
    type: str = "plane"
    size: int


items = {
    "item1": {"description": "All my friends drive a low rider", "type": "car"},
    "item2": {
        "description": "Music is my aeroplane, it's my aeroplane",
        "type": "plane",
        "size": 5,
    },
}


@app.get("/items/{item_id}", response_model=Union[PlaneItem, CarItem])
async def read_item(item_id: str):
    return items[item_id]
from typing import Union

from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()


class BaseItem(BaseModel):
    description: str
    type: str


class CarItem(BaseItem):
    type: str = "car"


class PlaneItem(BaseItem):
    type: str = "plane"
    size: int


items = {
    "item1": {"description": "All my friends drive a low rider", "type": "car"},
    "item2": {
        "description": "Music is my aeroplane, it's my aeroplane",
        "type": "plane",
        "size": 5,
    },
}


@app.get("/items/{item_id}", response_model=Union[PlaneItem, CarItem])
async def read_item(item_id: str):
    return items[item_id]

Union ๐Ÿ 3๏ธโƒฃ.1๏ธโƒฃ0๏ธโƒฃ

๐Ÿ‘‰ ๐Ÿ–ผ ๐Ÿ‘ฅ ๐Ÿšถโ€โ™€๏ธ Union[PlaneItem, CarItem] ๐Ÿ’ฒ โŒ response_model.

โ†ฉ๏ธ ๐Ÿ‘ฅ ๐Ÿšถโ€โ™€๏ธ โšซ๏ธ ๐Ÿ’ฒ โŒ โ†ฉ๏ธ ๐Ÿšฎ โšซ๏ธ ๐Ÿ†Ž โœ, ๐Ÿ‘ฅ โœ”๏ธ โš™๏ธ Union ๐Ÿ 3๏ธโƒฃ.1๏ธโƒฃ0๏ธโƒฃ.

๐Ÿšฅ โšซ๏ธ ๐Ÿ†Ž โœ ๐Ÿ‘ฅ ๐Ÿ’ช โœ”๏ธ โš™๏ธ โธ โธ,:

some_variable: PlaneItem | CarItem

โœ‹๏ธ ๐Ÿšฅ ๐Ÿ‘ฅ ๐Ÿšฎ ๐Ÿ‘ˆ response_model=PlaneItem | CarItem ๐Ÿ‘ฅ ๐Ÿ”œ ๐Ÿคš โŒ, โ†ฉ๏ธ ๐Ÿ ๐Ÿ”œ ๐Ÿ”„ ๐ŸŽญ โŒ ๐Ÿ› ๏ธ ๐Ÿ–– PlaneItem & CarItem โ†ฉ๏ธ ๐Ÿ”ฌ ๐Ÿ‘ˆ ๐Ÿ†Ž โœ.

๐Ÿ“‡ ๐Ÿท

๐ŸŽ ๐ŸŒŒ, ๐Ÿ‘† ๐Ÿ’ช ๐Ÿ“ฃ ๐Ÿ“จ ๐Ÿ“‡ ๐ŸŽš.

๐Ÿ‘ˆ, โš™๏ธ ๐Ÿฉ ๐Ÿ typing.List (โš–๏ธ list ๐Ÿ 3๏ธโƒฃ.9๏ธโƒฃ & ๐Ÿ”›):

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
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

๐Ÿ“จ โฎ๏ธ โŒ dict

๐Ÿ‘† ๐Ÿ’ช ๐Ÿ“ฃ ๐Ÿ“จ โš™๏ธ โœ… โŒ dict, ๐Ÿ“ฃ ๐Ÿ†Ž ๐Ÿ”‘ & ๐Ÿ’ฒ, ๐Ÿต โš™๏ธ Pydantic ๐Ÿท.

๐Ÿ‘‰ โš  ๐Ÿšฅ ๐Ÿ‘† ๐Ÿšซ ๐Ÿ’ญ โ˜‘ ๐Ÿ‘/๐Ÿ”ข ๐Ÿ“› (๐Ÿ‘ˆ ๐Ÿ”œ ๐Ÿ’ช Pydantic ๐Ÿท) โช.

๐Ÿ‘‰ ๐Ÿ’ผ, ๐Ÿ‘† ๐Ÿ’ช โš™๏ธ typing.Dict (โš–๏ธ dict ๐Ÿ 3๏ธโƒฃ.9๏ธโƒฃ & ๐Ÿ”›):

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}
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}

๐ŸŒƒ

โš™๏ธ ๐Ÿ’— Pydantic ๐Ÿท & ๐Ÿ˜– โžก ๐Ÿ”  ๐Ÿ’ผ.

๐Ÿ‘† ๐Ÿšซ ๐Ÿ’ช โœ”๏ธ ๐Ÿ‘ ๐Ÿ’ฝ ๐Ÿท ๐Ÿ“ ๐Ÿ‘จโ€๐Ÿ’ผ ๐Ÿšฅ ๐Ÿ‘ˆ ๐Ÿ‘จโ€๐Ÿ’ผ ๐Ÿ”œ ๐Ÿ’ช โœ”๏ธ ๐ŸŽ "๐Ÿ‡ต๐Ÿ‡ธ". ๐Ÿ’ผ โฎ๏ธ ๐Ÿ‘ฉโ€๐Ÿ’ป "๐Ÿ‘จโ€๐Ÿ’ผ" โฎ๏ธ ๐Ÿ‡ต๐Ÿ‡ธ โœ… password, password_hash & ๐Ÿ™…โ€โ™‚ ๐Ÿ”.