Skip to content

➡ 🛠️ 🏧 📳

🗄 {

Warning

🚥 👆 🚫 "🕴" 🗄, 👆 🎲 🚫 💪 👉.

👆 💪 ⚒ 🗄 operationId ⚙️ 👆 ➡ 🛠️ ⏮️ 🔢 operation_id.

👆 🔜 ✔️ ⚒ 💭 👈 ⚫️ 😍 🔠 🛠️.

from fastapi import FastAPI

app = FastAPI()


@app.get("/items/", operation_id="some_specific_id_you_define")
async def read_items():
    return [{"item_id": "Foo"}]

⚙️ ➡ 🛠️ 🔢 📛 {

🚥 👆 💚 ⚙️ 👆 🔗' 🔢 📛 operationIdⓂ, 👆 💪 🔁 🤭 🌐 👫 & 🔐 🔠 ➡ 🛠️ operation_id ⚙️ 👫 APIRoute.name.

👆 🔜 ⚫️ ⏮️ ❎ 🌐 👆 ➡ 🛠️.

from fastapi import FastAPI
from fastapi.routing import APIRoute

app = FastAPI()


@app.get("/items/")
async def read_items():
    return [{"item_id": "Foo"}]


def use_route_names_as_operation_ids(app: FastAPI) -> None:
    """
    Simplify operation IDs so that generated API clients have simpler function
    names.

    Should be called only after all routes have been added.
    """
    for route in app.routes:
        if isinstance(route, APIRoute):
            route.operation_id = route.name  # in this case, 'read_items'


use_route_names_as_operation_ids(app)

Tip

🚥 👆 ❎ 🤙 app.openapi(), 👆 🔜 ℹ operationIdⓂ ⏭ 👈.

Warning

🚥 👆 👉, 👆 ✔️ ⚒ 💭 🔠 1️⃣ 👆 ➡ 🛠️ 🔢 ✔️ 😍 📛.

🚥 👫 🎏 🕹 (🐍 📁).

🚫 ⚪️➡️ 🗄

🚫 ➡ 🛠️ ⚪️➡️ 🏗 🗄 🔗 (& ➡️, ⚪️➡️ 🏧 🧾 ⚙️), ⚙️ 🔢 include_in_schema & ⚒ ⚫️ False:

from fastapi import FastAPI

app = FastAPI()


@app.get("/items/", include_in_schema=False)
async def read_items():
    return [{"item_id": "Foo"}]

🏧 📛 ⚪️➡️ #️⃣

👆 💪 📉 ⏸ ⚙️ ⚪️➡️ #️⃣ ➡ 🛠️ 🔢 🗄.

\f (😖 "📨 🍼" 🦹) 🤕 FastAPI 🔁 🔢 ⚙️ 🗄 👉 ☝.

⚫️ 🏆 🚫 🎦 🆙 🧾, ✋️ 🎏 🧰 (✅ 🐉) 🔜 💪 ⚙️ 🎂.

from typing import Set, 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
    tags: Set[str] = set()


@app.post("/items/", response_model=Item, summary="Create an item")
async def create_item(item: Item):
    """
    Create an item with all the information:

    - **name**: each item must have a name
    - **description**: a long description
    - **price**: required
    - **tax**: if the item doesn't have tax, you can omit this
    - **tags**: a set of unique tag strings for this item
    \f
    :param item: User input.
    """
    return item

🌖 📨

👆 🎲 ✔️ 👀 ❔ 📣 response_model & status_code ➡ 🛠️.

👈 🔬 🗃 🔃 👑 📨 ➡ 🛠️.

👆 💪 📣 🌖 📨 ⏮️ 👫 🏷, 👔 📟, ♒️.

📤 🎂 📃 📥 🧾 🔃 ⚫️, 👆 💪 ✍ ⚫️ 🌖 📨 🗄.

🗄 ➕

🕐❔ 👆 📣 ➡ 🛠️ 👆 🈸, FastAPI 🔁 🏗 🔗 🗃 🔃 👈 ➡ 🛠️ 🔌 🗄 🔗.

📡 ℹ

🗄 🔧 ⚫️ 🤙 🛠️ 🎚.

⚫️ ✔️ 🌐 ℹ 🔃 ➡ 🛠️ & ⚙️ 🏗 🏧 🧾.

⚫️ 🔌 tags, parameters, requestBody, responses, ♒️.

👉 ➡ 🛠️-🎯 🗄 🔗 🛎 🏗 🔁 FastAPI, ✋️ 👆 💪 ↔ ⚫️.

Tip

👉 🔅 🎚 ↔ ☝.

🚥 👆 🕴 💪 📣 🌖 📨, 🌅 🏪 🌌 ⚫️ ⏮️ 🌖 📨 🗄.

👆 💪 ↔ 🗄 🔗 ➡ 🛠️ ⚙️ 🔢 openapi_extra.

🗄 ↔

👉 openapi_extra 💪 👍, 🖼, 📣 🗄 ↔:

from fastapi import FastAPI

app = FastAPI()


@app.get("/items/", openapi_extra={"x-aperture-labs-portal": "blue"})
async def read_items():
    return [{"item_id": "portal-gun"}]

🚥 👆 📂 🏧 🛠️ 🩺, 👆 ↔ 🔜 🎦 🆙 🔝 🎯 ➡ 🛠️.

& 🚥 👆 👀 📉 🗄 ( /openapi.json 👆 🛠️), 👆 🔜 👀 👆 ↔ 🍕 🎯 ➡ 🛠️ 💁‍♂️:

{
    "openapi": "3.0.2",
    "info": {
        "title": "FastAPI",
        "version": "0.1.0"
    },
    "paths": {
        "/items/": {
            "get": {
                "summary": "Read Items",
                "operationId": "read_items_items__get",
                "responses": {
                    "200": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": {}
                            }
                        }
                    }
                },
                "x-aperture-labs-portal": "blue"
            }
        }
    }
}

🛃 🗄 ➡ 🛠️ 🔗

📖 openapi_extra 🔜 🙇 🔗 ⏮️ 🔁 🏗 🗄 🔗 ➡ 🛠️.

, 👆 💪 🚮 🌖 💽 🔁 🏗 🔗.

🖼, 👆 💪 💭 ✍ & ✔ 📨 ⏮️ 👆 👍 📟, 🍵 ⚙️ 🏧 ⚒ FastAPI ⏮️ Pydantic, ✋️ 👆 💪 💚 🔬 📨 🗄 🔗.

👆 💪 👈 ⏮️ openapi_extra:

from fastapi import FastAPI, Request

app = FastAPI()


def magic_data_reader(raw_body: bytes):
    return {
        "size": len(raw_body),
        "content": {
            "name": "Maaaagic",
            "price": 42,
            "description": "Just kiddin', no magic here. ✨",
        },
    }


@app.post(
    "/items/",
    openapi_extra={
        "requestBody": {
            "content": {
                "application/json": {
                    "schema": {
                        "required": ["name", "price"],
                        "type": "object",
                        "properties": {
                            "name": {"type": "string"},
                            "price": {"type": "number"},
                            "description": {"type": "string"},
                        },
                    }
                }
            },
            "required": True,
        },
    },
)
async def create_item(request: Request):
    raw_body = await request.body()
    data = magic_data_reader(raw_body)
    return data

👉 🖼, 👥 🚫 📣 🙆 Pydantic 🏷. 👐, 📨 💪 🚫 🎻 🎻, ⚫️ ✍ 🔗 bytes, & 🔢 magic_data_reader() 🔜 🈚 🎻 ⚫️ 🌌.

👐, 👥 💪 📣 📈 🔗 📨 💪.

🛃 🗄 🎚 🆎

⚙️ 👉 🎏 🎱, 👆 💪 ⚙️ Pydantic 🏷 🔬 🎻 🔗 👈 ⤴️ 🔌 🛃 🗄 🔗 📄 ➡ 🛠️.

& 👆 💪 👉 🚥 💽 🆎 📨 🚫 🎻.

🖼, 👉 🈸 👥 🚫 ⚙️ FastAPI 🛠️ 🛠️ ⚗ 🎻 🔗 ⚪️➡️ Pydantic 🏷 🚫 🏧 🔬 🎻. 👐, 👥 📣 📨 🎚 🆎 📁, 🚫 🎻:

from typing import List

import yaml
from fastapi import FastAPI, HTTPException, Request
from pydantic import BaseModel, ValidationError

app = FastAPI()


class Item(BaseModel):
    name: str
    tags: List[str]


@app.post(
    "/items/",
    openapi_extra={
        "requestBody": {
            "content": {"application/x-yaml": {"schema": Item.model_json_schema()}},
            "required": True,
        },
    },
)
async def create_item(request: Request):
    raw_body = await request.body()
    try:
        data = yaml.safe_load(raw_body)
    except yaml.YAMLError:
        raise HTTPException(status_code=422, detail="Invalid YAML")
    try:
        item = Item.model_validate(data)
    except ValidationError as e:
        raise HTTPException(status_code=422, detail=e.errors(include_url=False))
    return item

👐, 👐 👥 🚫 ⚙️ 🔢 🛠️ 🛠️, 👥 ⚙️ Pydantic 🏷 ❎ 🏗 🎻 🔗 💽 👈 👥 💚 📨 📁.

⤴️ 👥 ⚙️ 📨 🔗, & ⚗ 💪 bytes. 👉 ⛓ 👈 FastAPI 🏆 🚫 🔄 🎻 📨 🚀 🎻.

& ⤴️ 👆 📟, 👥 🎻 👈 📁 🎚 🔗, & ⤴️ 👥 🔄 ⚙️ 🎏 Pydantic 🏷 ✔ 📁 🎚:

from typing import List

import yaml
from fastapi import FastAPI, HTTPException, Request
from pydantic import BaseModel, ValidationError

app = FastAPI()


class Item(BaseModel):
    name: str
    tags: List[str]


@app.post(
    "/items/",
    openapi_extra={
        "requestBody": {
            "content": {"application/x-yaml": {"schema": Item.model_json_schema()}},
            "required": True,
        },
    },
)
async def create_item(request: Request):
    raw_body = await request.body()
    try:
        data = yaml.safe_load(raw_body)
    except yaml.YAMLError:
        raise HTTPException(status_code=422, detail="Invalid YAML")
    try:
        item = Item.model_validate(data)
    except ValidationError as e:
        raise HTTPException(status_code=422, detail=e.errors(include_url=False))
    return item

Tip

📥 👥 🏤-⚙️ 🎏 Pydantic 🏷.

✋️ 🎏 🌌, 👥 💪 ✔️ ✔ ⚫️ 🎏 🌌.