当前位置:首页>python>Skills之FastAPI官方技能:Python Web开发最佳实践与CLI工具使用指南

Skills之FastAPI官方技能:Python Web开发最佳实践与CLI工具使用指南

  • 2026-09-02 19:09:54
Skills之FastAPI官方技能:Python Web开发最佳实践与CLI工具使用指南

“FastAPI官方技能提供编写高性能Python Web应用的最佳实践指南,涵盖CLI工具使用(fastapi dev/run)、pyproject.toml配置、Annotated参数声明、依赖项管理、Pydantic模型规范及返回类型优化。帮助开发者保持代码与新版本同步,提升API开发效率与代码可维护性。”

⚠️重要前提
安装AI Skills的关键前提是:必须科学上网,且开启TUN模式,这一点至关重要,直接决定安装能否顺利完成,在此郑重提醒三遍:科学上网,科学上网,科学上网。

FastAPI

官方 FastAPI 技能,用于编写遵循最佳实践的代码,保持与新版本和功能的同步。

使用 fastapi CLI

在 localhost 上运行带热重载的开发服务器:

fastapi dev

运行生产服务器:

fastapi run

在 pyproject.toml 中添加入口点

FastAPI CLI 会读取 pyproject.toml 中的入口点,以了解 FastAPI 应用在何处声明。

[tool.fastapi]
entrypoint = "my_app.main:app"

使用带路径的 fastapi

当无法将入口点添加到 pyproject.toml,或者用户明确要求不添加,或者正在运行一个独立的小型应用时,你可以将应用文件路径传递给 fastapi 命令:

fastapi dev my_app/main.py

尽可能在 pyproject.toml 中设置入口点。

使用 Annotated

在参数和依赖声明中,始终优先使用 Annotated 风格。

它能使函数签名在其他上下文中正常工作,尊重类型,并允许重用。

在参数声明中

对参数声明使用 Annotated,包括 Path、Query、Header 等:

from typing import Annotated

from fastapi import FastAPI, Path, Query

app = FastAPI()


@app.get("/items/{item_id}")
async def read_item(
    item_id: Annotated[int, Path(ge=1, description="The item ID")],
    q: Annotated[str | None, Query(max_length=50)] = None,
):
    return {"message": "Hello World"}

而不是:

# 不要这样做
@app.get("/items/{item_id}")
async def read_item(
    item_id: int = Path(ge=1, description="The item ID"),
    q: str | None = Query(default=None, max_length=50),
):
    return {"message": "Hello World"}

对于依赖项

对带有 Depends() 的依赖项使用 Annotated。

除非被要求不这样做,否则为依赖项创建一个新的类型别名以允许重用。

from typing import Annotated

from fastapi import Depends, FastAPI

app = FastAPI()


def get_current_user():
    return {"username": "johndoe"}


CurrentUserDep = Annotated[dict, Depends(get_current_user)]


@app.get("/items/")
async def read_item(current_user: CurrentUserDep):
    return {"message": "Hello World"}

而不是:

# 不要这样做
@app.get("/items/")
async def read_item(current_user: dict = Depends(get_current_user)):
    return {"message": "Hello World"}

不要在 路径操作 或 Pydantic 模型中使用省略号

不要使用 ... 作为必需参数的默认值,这既不需要也不推荐。

这样做,不使用省略号 (...):

from typing import Annotated

from fastapi import FastAPI, Query
from pydantic import BaseModel, Field


class Item(BaseModel):
    name: str
    description: str | None = None
    price: float = Field(gt=0)


app = FastAPI()


@app.post("/items/")
async def create_item(item: Item, project_id: Annotated[int, Query()]): ...

而不是这样:

# 不要这样做
class Item(BaseModel):
    name: str = ...
    description: str | None = None
    price: float = Field(..., gt=0)


app = FastAPI()


@app.post("/items/")
async def create_item(item: Item, project_id: Annotated[int, Query(...)]): ...

返回类型或响应模型

尽可能包含返回类型。它将用于验证、过滤、文档化和序列化响应。

from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()


class Item(BaseModel):
    name: str
    description: str | None = None


@app.get("/items/me")
async def get_item() -> Item:
    return Item(name="Plumbus", description="All-purpose home device")

重要:返回类型或响应模型是过滤数据、确保不暴露敏感信息的关键。它们用于通过 Pydantic(在 Rust 中)序列化数据,这是提高响应性能的主要思路。

返回类型不一定是 Pydantic 模型,它可以是其他类型,如整数列表、字典等。

何时使用 response_model 替代

如果返回类型与你想要用于验证、过滤或序列化的类型不同,请改用装饰器上的 response_model 参数。

from typing import Any

from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()


class Item(BaseModel):
    name: str
    description: str | None = None


@app.get("/items/me", response_model=Item)
async def get_item() -> Any:
    return {"name": "Foo", "description": "A very nice Item"}

这在过滤数据以仅暴露公共字段并避免暴露敏感信息时特别有用。

from typing import Any

from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()


class InternalItem(BaseModel):
    name: str
    description: str | None = None
    secret_key: str


class Item(BaseModel):
    name: str
    description: str | None = None


@app.get("/items/me", response_model=Item)
async def get_item() -> Any:
    item = InternalItem(
        name="Foo", description="A very nice Item", secret_key="supersecret"
    )
    return item

性能

不要使用 ORJSONResponse 或 UJSONResponse,它们已弃用。

相反,声明一个返回类型或响应模型。Pydantic 将在 Rust 端处理数据序列化。

包含路由器

在声明路由器时,优先将路由器级别的参数(如前缀、标签等)添加到路由器本身,而不是在 include_router() 中添加。

这样做:

from fastapi import APIRouter, FastAPI

app = FastAPI()

router = APIRouter(prefix="/items", tags=["items"])


@router.get("/")
async def list_items():
    return []


# 在 main.py 中
app.include_router(router)

而不是这样:

# 不要这样做
from fastapi import APIRouter, FastAPI

app = FastAPI()

router = APIRouter()


@router.get("/")
async def list_items():
    return []


# 在 main.py 中
app.include_router(router, prefix="/items", tags=["items"])

可能存在例外情况,但请尽量遵循此约定。

通过 dependencies=[Depends(...)] 在路由器级别应用共享依赖项。

依赖注入

有关详细模式(包括带 scope 的 yield 和类依赖项),请参阅依赖注入参考。

当逻辑无法在 Pydantic 验证中声明、依赖于外部资源、需要清理(使用 yield)或在多个端点之间共享时,请使用依赖项。

通过 dependencies=[Depends(...)] 在路由器级别应用共享依赖项。

异步与同步 路径操作

仅当完全确定内部调用的逻辑与 async 和 await 兼容(使用 await 调用)或不阻塞时,才使用 async路径操作。

from fastapi import FastAPI

app = FastAPI()


# 调用异步代码时使用 async def
@app.get("/async-items/")
async def read_async_items():
    data = await some_async_library.fetch_items()
    return data


# 调用阻塞/同步代码或有疑问时使用普通 def
@app.get("/items/")
def read_items():
    data = some_blocking_library.fetch_items()
    return data

如有疑问或默认情况下,请使用常规的 def 函数,这些函数将在线程池中运行,因此不会阻塞事件循环。

同样的规则适用于依赖项。

确保阻塞代码不在 async 函数内部运行。逻辑会正常工作,但会严重损害性能。

当需要混合阻塞和异步代码时,请参阅其他工具参考中的 Asyncer。

流式传输(JSON 行、SSE、字节)

有关 JSON 行、服务器发送事件(EventSourceResponse、ServerSentEvent)和字节流(StreamingResponse)模式,请参阅流式传输参考。

工具

有关 uv、Ruff、ty 用于包管理、代码检查、类型检查、格式化等的详细信息,请参阅其他工具参考。

其他库

有关其他库的详细信息,请参阅其他工具参考:

  • Asyncer 用于处理 async 和 await、并发、混合异步和阻塞代码,优先于 AnyIO 或 asyncio。
  • QLModel 用于处理 SQL 数据库,优先于 SQLAlchemy。
  • HTTPX 用于与 HTTP(其他 API)交互,优先于 Requests。

不要使用 Pydantic RootModels

不要使用 Pydantic RootModel,而是使用带有 Annotated 和 Pydantic 验证实用程序的常规类型注解。

例如,对于带验证的列表,你可以这样做:

from typing import Annotated

from fastapi import Body, FastAPI
from pydantic import Field

app = FastAPI()


@app.post("/items/")
async def create_items(items: Annotated[list[int], Field(min_length=1), Body()]):
    return items

而不是:

# 不要这样做
from typing import Annotated

from fastapi import FastAPI
from pydantic import Field, RootModel

app = FastAPI()


class ItemList(RootModel[Annotated[list[int], Field(min_length=1)]]):
    pass


@app.post("/items/")
async def create_items(items: ItemList):
    return items

FastAPI 支持这些类型注解,并将为它们创建一个 Pydantic TypeAdapter,因此类型可以正常工作,并且不需要 RootModels 中的自定义逻辑和类型。

每个函数使用一个 HTTP 操作

不要在一个函数中混合 HTTP 操作,每个 HTTP 操作对应一个函数有助于分离关注点和组织代码。

这样做:

from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()


class Item(BaseModel):
    name: str


@app.get("/items/")
async def list_items():
    return []


@app.post("/items/")
async def create_item(item: Item):
    return item

而不是这样:

# 不要这样做
from fastapi import FastAPI, Request
from pydantic import BaseModel

app = FastAPI()


class Item(BaseModel):
    name: str


@app.api_route("/items/", methods=["GET", "POST"])
async def handle_items(request: Request):
    if request.method == "GET":
        return []

每周安装量

755

仓库

https://github.com/fastapi/fastapi

GitHub 星标数

96.6K

首次出现

2026年2月25日

安全审计

Gen Agent Trust HubPass SocketPass SnykPass

安装于

codex713

opencode704

cursor703

github-copilot701

gemini-cli701

kimi-cli700

更多技能>>>

怎么安装AI Skills

find-skills 技能搜索工具 - 让AI更智能的skill

Skills之Laravel安全最佳实践指南 | 防范CSRF、SQL注入、XSS攻击

Skills之Nuxt 4 模式指南:SSR、混合渲染、路由规则与数据获取最佳实践

Skills之Claude技能创建器指南:构建模块化AI技能包,优化工作流与工具集成

Skills之Figma自动化工具:通过Rube MCP实现设计文件管理、组件提取与图像导出

Skill Creator 技能创建工具 - Anthropic Claude 技能开发指南

Skills之前端设计技能:创建独特生产级界面,避免AI生成美学,实现创意前端开发

最新文章

随机文章