➡ 🛠️ 🏧 📳¶
🗄 {¶
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, ✋️ 👆 💪 ↔ ⚫️.
👆 💪 ↔ 🗄 🔗 ➡ 🛠️ ⚙️ 🔢 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())
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())
return item
Tip
📥 👥 🏤-⚙️ 🎏 Pydantic 🏷.
✋️ 🎏 🌌, 👥 💪 ✔️ ✔ ⚫️ 🎏 🌌.