首页
/ FastAPI 入门实战指南:从零搭建基于 Python 类型标注的高性能 Web API

FastAPI 入门实战指南:从零搭建基于 Python 类型标注的高性能 Web API

2026-09-07 13:53:08作者:咎竹峻Karen

FastAPI 是一个基于 Python 标准类型标注(type hints)构建的现代化 Web 框架,目标是让开发者以最少的代码写出高性能、易学习、开发迅速且可直接用于生产的 API。本指南以仓库中 docs/es/docs/index.md(西班牙语版首页文档)为骨架,围绕"安装依赖、编写首个 API、启动调试、自动生成交互文档、演进到带请求体与数据校验的完整应用"这条完整链路展开,并结合当前仓库源码印证底层实现,帮助你彻底掌握 FastAPI 的核心工作方式与落地步骤。

FastAPI 是什么

FastAPI 是专为构建 API 而生的 Python Web 框架,其最鲜明的特征是完全建立在 Python 3.10+ 的类型标注(annotations)体系之上——不需要学习新的语法或第三方专有类,只需要写标准 Python,就能获得编辑器补全、数据校验、序列化与交互式文档等一整套能力。当前仓库中 fastapi/init.py 声明的版本为 0.141.1requires-python 要求不低于 Python 3.10(见 pyproject.toml)。

官方首页文档概括了它的关键特性:

  • 高性能:官方文档称其性能与 NodeJSGo 相当(得益于底层 Starlette 与 Pydantic),是"Python 生态中速度最快的 Web 框架之一";
  • 开发效率高:据官方文档估算,可将功能开发速度提升约 200% 到 300%
  • Bug 更少:据官方文档估算,可减少约 40% 的人为(开发者引入)错误;
  • 对编辑器友好:全面支持自动补全(Autocompletado / IntelliSense),减少调试时间;
  • 简单易学:设计目标就是降低学习与阅读文档的成本;
  • 代码简洁:通过最少的参数声明复用获得多种能力,最小化重复代码;
  • 生产就绪且健壮:自带自动化的交互式 API 文档;
  • 基于开放标准:与 API 开放标准 OpenAPI(即此前的 Swagger)及 JSON Schema 完全兼容。

需要说明的是:上文中"开发提速 200%~300%"、"Bug 减少 40%"等数字是官方文档基于内部开发团队构建生产应用时的估算值(原文档已标注 * estimación basada en pruebas con un equipo de desarrollo interno),而"性能与 NodeJS/Go 相当"源自官方引用的 TechEmpower 基准测试,均属于框架方声明而非本仓库可直接复现的结论。

快速安装 FastAPI

FastAPI 站在两个关键依赖之上,官方将其称为"站在巨人的肩膀上":

  • Starlette:负责 Web 相关部分(路由、请求/响应、中间件、WebSocket 等);
  • Pydantic:负责数据部分(校验、序列化、模型定义)。

使用 uv 安装(官方推荐)

官方文档推荐先安装 uv,然后在项目目录中执行:

$ uv add "fastapi[standard]"

---> 100%

注意:务必给 fastapi[standard] 加上双引号,以保证它在所有终端(尤其是 zsh 等会将 [standard] 解释为通配符的 shell)中都能正常工作。standard 是框架提供的可选依赖组(extra),一次性带入开发与本地运行所需的配套工具。

使用 pip 安装

如果习惯用 pip,可以在虚拟环境中安装 fastapi[standard]。更多替代步骤可参考 教程-用户指南 中的安装章节。

standard 依赖组里到底装了什么

结合当前仓库 pyproject.tomlstandard extra 的实际声明,该依赖组包含:

  • fastapi-cli[standard]:提供 fastapi 命令行入口(同时带入 fastapi-cloud-cli,用于在 FastAPI Cloud 上部署);
  • uvicorn[standard]:ASGI 服务器,负责加载并运行你的应用,其 standard 变体包含 uvloop 等高性能服务所需组件;
  • httpx:使用 TestClient 进行接口测试所必需;
  • jinja2:使用默认模板渲染配置(如 Jinja2Templates)所必需;
  • python-multipart:支持 request.form() 解析表单数据(文件上传、表单字段)所必需;
  • email-validator:用于 Pydantic 的 EmailStr 等邮箱字段校验;
  • pydantic-settings:用于应用配置管理;
  • pydantic-extra-types:为 Pydantic 提供额外数据类型。

按需裁剪安装

  • 不想要可选的 standard 依赖:直接执行 uv add fastapi
  • 想要 standard 依赖但不需要 fastapi-cloud-cli:执行 uv add "fastapi[standard-no-fastapi-cloud-cli]"——该 extra 在 pyproject.toml 中同样有明确定义;
  • 其余可选依赖(视具体功能按需安装):orjson(使用 ORJSONResponse 时)、ujson(使用 UJSONResponse 时)。

值得说明的是:官方文档在 uvicorn 之外还提到了 fastapi-cliuvicornstandard 内的核心成员,而仓库的 pyproject.toml 实际已将 pydantic-settingspydantic-extra-types 一并纳入 standard extra,二者表述略有出入,以当前仓库代码为准即可。

底层依赖与 CLI 入口的实现印证

从源码看,FastAPI 的核心运行依赖正是文档所述的组合。在 pyproject.toml 中声明的基础依赖为 starlette>=0.46.0pydantic>=2.9.0typing-extensions>=4.8.0typing-inspection>=0.4.2annotated-doc>=0.0.2。而 fastapi 命令的入口被注册在 pyproject.toml[project.scripts] 中,指向 fastapi/cli.py;该文件会尝试导入 fastapi_cli.cli.main,若未安装 fastapi[standard],则会打印 pip install "fastapi[standard]" 的提示并抛出 RuntimeError。也就是说,只有安装了 standard extra,才能使用 fastapi dev / fastapi run 等命令

第一个 FastAPI 应用

编写 main.py

新建文件 main.py,内容如下:

from fastapi import FastAPI

app = FastAPI()


@app.get("/")
def read_root():
    return {"Hello": "World"}


@app.get("/items/{item_id}")
def read_item(item_id: int, q: str | None = None):
    return {"item_id": item_id, "q": q}

这段代码对应的示例在仓库中也有可运行版本,例如 docs_src/first_steps/tutorial001_py310.py,并且有配套测试 tests/test_tutorial/test_first_steps/test_tutorial001_tutorial002_tutorial003.py 验证其行为与 /openapi.json 的生成结果。

如果你用 async / await

当业务代码中涉及 async/await 时,把路径操作函数声明为 async def 即可:

from fastapi import FastAPI

app = FastAPI()


@app.get("/")
async def read_root():
    return {"Hello": "World"}


@app.get("/items/{item_id}")
async def read_item(item_id: int, q: str | None = None):
    return {"item_id": item_id, "q": q}

如果对两者区别不熟悉,可以参考文档中关于 asyncawait 的章节(同步 def 会运行在线程池中,异步 def 则直接运行在事件循环上)。

启动开发服务器

在项目目录下执行:

$ uv run fastapi dev

 ╭────────── FastAPI CLI - Development mode ───────────╮
 │                                                     │
 │  Serving at: http://127.0.0.1:8000                  │
 │                                                     │
 │  API docs: http://127.0.0.1:8000/docs               │
 │                                                     │
 │  Running in development mode, for production use:   │
 │                                                     │
 │  fastapi run                                        │
 │                                                     │
 ╰─────────────────────────────────────────────────────╯

INFO:     Will watch for changes in these directories: ['/home/user/code/awesomeapp']
INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO:     Started reloader process [2248755] using WatchFiles
INFO:     Started server process [2248757]
INFO:     Waiting for application startup.
INFO:     Application startup complete.

关于 fastapi dev 命令:

  • 它会自动读取项目中的 main.py,探测其中的 FastAPI 实例app),并使用 Uvicorn 启动服务;
  • 默认开启 auto-reload(自动重载),方便本地开发——修改代码保存后服务会自动重启;
  • 终端面板明确提示:开发模式面向本地调试,生产部署请改用 fastapi run
  • 完整的 CLI 参数说明见 FastAPI CLI 文档

验证接口

用浏览器打开 http://127.0.0.1:8000/items/5?q=somequery,会得到如下 JSON 响应:

{"item_id": 5, "q": "somequery"}

至此你已创建了一个具备以下行为的 API:

  • 在路径 //items/{item_id} 上接收 HTTP 请求;
  • 两个路径都声明了 GET 操作(即 HTTP 方法);
  • /items/{item_id} 带有一个 路径参数 item_id,类型被声明为 int
  • /items/{item_id} 带有一个可选的 查询参数 q,类型为 str

注意验证背后的自动转换:当请求 http://127.0.0.1:8000/items/5?q=somequery 时,FastAPI 会读取 URL 路径中的 item_id 并把它从字符串解析为 int,把查询串里的 q 作为 str | None 传入函数。仓库测试 tests/test_tutorial/test_first_steps/test_tutorial001_tutorial002_tutorial003.py 即验证了 TestClient 下对路径返回 200 及预期 JSON 的行为。

自动生成的交互式 API 文档(Swagger UI)

访问 http://127.0.0.1:8000/docs,会看到由 Swagger UI 提供的自动交互文档,你可以直接在页面上浏览接口、传参并执行请求:

FastAPI 自动生成的 Swagger UI 交互式 API 文档界面

备选的交互式文档(ReDoc)

再访问 http://127.0.0.1:8000/redoc,则可以看到由 ReDoc 渲染的另一种文档界面:

FastAPI 自动生成的 ReDoc 版 API 文档界面

从仓库源码看,这两套文档端点由 fastapi/applications.pyFastAPI.setup() 统一挂载:当 openapi_url 非空时注册 /openapi.json 路由(返回描述接口的 OpenAPI Schema),当同时满足 openapi_urldocs_url/redoc_url 时才分别注册 /docs(Swagger UI)与 /redoc(ReDoc)页面。也就是说,文档是从同一份 OpenAPI Schema 自动生成的,而不是手写的。你也可以通过构造参数(如 app = FastAPI(openapi_url="/api/v1/openapi.json")app = FastAPI(docs_url="/documentation", redoc_url=None))自定义这些 URL,相关参数定义同样位于 fastapi/applications.py

演进示例:加入请求体与 PUT 操作

main.py 修改为:用 Pydantic 的 BaseModel 定义带类型的请求体,并新增一个 PUT 操作。

from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()


class Item(BaseModel):
    name: str
    price: float
    is_offer: bool | None = None


@app.get("/")
def read_root():
    return {"Hello": "World"}


@app.get("/items/{item_id}")
def read_item(item_id: int, q: str | None = None):
    return {"item_id": item_id, "q": q}


@app.put("/items/{item_id}")
def update_item(item_id: int, item: Item):
    return {"item_name": item.name, "item_id": item_id}

由于 fastapi dev 开启了自动重载,保存文件后服务器会自动重启。此刻你声明的 Item 模型已经定义了严格的接口契约:name 必须是 strprice 必须是 float、可选的 is_offer 必须是 bool

更新后的交互文档

再次打开 http://127.0.0.1:8000/docs

  • 文档会自动更新,新的请求体模型(body schema)已经出现在界面上:

FastAPI Swagger UI 展示更新后的请求体模型

  • 点击 "Try it out" 按钮,可以填写参数并直接与 API 交互:

在 Swagger UI 中点击 Try it out 填写参数

  • 点击 "Execute" 后,界面会真实地调用你的 API、发送参数并展示返回结果:

在 Swagger UI 中执行请求并查看响应结果

更新后的 ReDoc

访问 http://127.0.0.1:8000/redoc,备选文档同样会呈现新的查询参数与请求体结构:

FastAPI ReDoc 展示更新后的接口信息

数据校验的完整行为

回到上面的示例,FastAPI 在运行时会自动承担以下职责(无需你写任何 if/else 校验代码):

  • GETPUT 请求,校验路径中存在 item_id
  • 校验 item_id 确实是 int;若不是,客户端会收到清晰可读的错误信息;
  • GET 请求检查可选的查询参数 q:由于 q 被声明为 = None,它是可选的;去掉 None 后它就变成必填(就像 PUT 请求中的 body 一样);
  • 对发往 /items/{item_id}PUT 请求,读取 body 中的 JSON 并校验:
    • 存在必填属性 name 且为 str
    • 存在必填属性 price 且为 float
    • 若提供了可选的 is_offer,则必须是 bool
    • 这套校验对深度嵌套的 JSON 对象同样有效;
  • 自动完成 JSON 的解析与序列化(入站时从网络数据转为 Python 类型,出站时从 Python 类型转回 JSON);
  • 基于以上全部信息生成 OpenAPI Schema,可被交互文档系统以及多种语言的客户端代码自动生成工具消费;
  • 直接内置提供两套交互式文档 Web 界面。

这正是"声明一次,处处受益"的体现。你既不需要学习框架专用语法,也不需要掌握某个包的方法或类——只需要 Python 标准类型标注。比如路径参数只需写 item_id: int,请求体只需写 item: Item

编辑器体验与"一次声明"的完整收益

把示例代码中的返回语句由

return {"item_name": item.name, "item_id": item_id}

改为访问 item.price,观察编辑器如何为你自动补全属性并推断其类型:

VS Code 编辑器中的类型推断与自动补全

而"一次类型声明"换来的能力是成体系的。综合原文档的归纳,声明参数(路径、查询、body 等)后你会免费获得:

  • 编辑器支持:自动补全、类型检查;
  • 数据校验:数据非法时给出自动且清晰的错误;对深度嵌套的 JSON 对象同样生效;
  • 入站数据转换(网络数据 → Python 类型),数据来源覆盖:JSON、路径参数、查询参数、Cookie、请求头、表单、文件;
  • 出站数据转换(Python 类型 → 网络数据如 JSON):包括 str/int/float/bool/list 等基础类型,datetime 对象、UUID 对象、数据库模型等更多类型;
  • 自动化的交互式 API 文档:内置 Swagger UI 与 ReDoc 两套界面。

更进一步:仓库中可继续深挖的主题

首页示例只是入口。官方随后推荐的"教程-用户指南"(见 docs/es/docs/tutorial/index.md)还会带你掌握:

  • headerscookies表单字段文件等更多位置声明参数;
  • 设置校验约束,例如 maximum_lengthregex 等;
  • 强大且易用的**依赖注入(Dependency Injection)**系统;
  • 安全与认证,包括基于 JWT token 的 OAuth2 以及 HTTP Basic 认证;
  • 借助 Pydantic 声明深度嵌套的 JSON 模型
  • 通过 Strawberry 等库集成 GraphQL
  • 依托 Starlette 提供的更多能力,如 WebSockets、基于 HTTPX 与 pytest 的极简测试方式、CORSCookie 会话等。

作为佐证,这些主题在仓库中都有可运行的示例源码(docs_src/ 目录按主题组织,例如 docs_src/security/docs_src/dependencies/docs_src/websockets_/ 等)以及对应的自动化测试(tests/test_tutorial/),可对照文档逐项学习。

部署与运行方式

  • 生产运行:使用 fastapi run(而不是开发模式的 fastapi dev)。两者在 FastAPI CLI 文档中有详细说明——fastapi dev 默认开启热重载、面向本地开发;fastapi run 面向生产场景,直接由 Uvicorn 提供服务。
  • FastAPI Cloud 一键部署(可选):官方文档描述,若希望以最简步骤部署,可在安装对应 CLI 后执行 uv run fastapi deploy;CLI 会自动识别 FastAPI 应用并部署到云平台,未登录时浏览器会引导完成认证。FastAPI Cloud 由 FastAPI 原作者所在团队构建,属于商业托管服务。
  • 其他云厂商:由于 FastAPI 是开源且基于开放标准的,你可以把它部署到任意云厂商(自建服务器、容器平台、各类 Serverless 平台均可),按其部署指南操作即可。

许可证

FastAPI 项目以 MIT 许可证发布,许可证全文位于仓库根目录的 LICENSE 文件。

登录后查看全文
热门项目推荐
相关项目推荐