FastAPI 初体验:运行第一个 API 应用并读懂 First Steps 全流程
本篇文章对应 FastAPI 官方教程的入门第一课,是你在本仓库(FastAPI 框架源码仓库)中理解"框架如何运行起来"的最佳起点。读完你将掌握:如何用一个最小文件启动开发服务器、fastapi dev 的输出如何解读、自动生成的 Swagger UI / ReDoc / openapi.json 各是什么,以及 pyproject.toml 中 entrypoint 的配置方法。文中所有示例均可在仓库中找到对应源码与测试,可逐行对照验证。
最小可运行文件:8 行代码即可启动
官方教程 docs/en/docs/tutorial/first-steps.md 给出的最简单的 FastAPI 文件位于 docs_src/first_steps/tutorial001_py310.py,全文如下:
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
async def root():
return {"message": "Hello World"}
把它复制并保存为 main.py,你就有了一个完整的 FastAPI 应用。这 8 行代码已经覆盖了 FastAPI 的核心抽象:FastAPI 应用类、实例化出的 app、路径操作装饰器 @app.get("/")、路径操作函数 root,以及返回 JSON 内容。后续所有复杂功能(路径参数、请求体、依赖注入、安全认证等)都是在这套骨架上叠加的。
启动开发服务器:uv run fastapi dev
在包含 main.py 的目录下,运行:
$ uv run fastapi dev
Searching for package file structure from directories
with __init__.py files
Importing from /home/user/code/awesomeapp
module 🐍 main.py
code Importing the FastAPI app object from the module with
the following code:
from main import app
app Using import string: main:app
server Server started at http://127.0.0.1:8000
server Documentation at http://127.0.0.1:8000/docs
tip Running in development mode, for production use:
fastapi run
INFO Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO Started reloader process [383138] using WatchFiles
INFO Started server process [383153]
INFO Application startup complete.
关键输出解读
Importing from ...:fastapi dev会从含__init__.py的目录结构中向上查找并导入模块。示例中以main.py中的app对象作为应用入口,等价于执行from main import app。Server started at http://127.0.0.1:8000:你的应用正在本地该地址提供服务,对应日志中的那一行:INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)Running in development mode:开发模式下会自动监听文件变更并触发重载(日志中可见Started reloader process ... using WatchFiles);生产环境请改用提示中的fastapi run。
前置条件:需要安装 fastapi[standard]
fastapi 命令本身并不内置于核心包中。查看仓库源码 fastapi/cli.py 可以发现:该文件尝试从 fastapi_cli.cli 导入真正的 CLI 入口,若导入失败(即未安装 CLI 依赖)会直接抛出提示信息:
message = 'To use the fastapi command, please install "fastapi[standard]":\n\n\tpip install "fastapi[standard]"\n'
也就是说,使用前需要先执行 pip install "fastapi[standard]"(或使用 uv 时执行 uv add "fastapi[standard]")。仓库测试 tests/test_fastapi_cli.py 也验证了这一点:当 cli_main 被置空时调用会抛出包含 To use the fastapi command, please install 的 RuntimeError;同时测试还通过 python -m fastapi dev non_existent_file.py 验证了当文件不存在时会输出 Path does not exist non_existent_file.py 并以退出码 1 结束。
验证接口响应
打开浏览器访问 http://127.0.0.1:8000,即可看到 JSON 响应:
{"message": "Hello World"}
这个结果由仓库中的测试精确定义,见 tests/test_tutorial/test_first_steps/test_tutorial001_tutorial002_tutorial003.py:它用 TestClient 请求 / 断言状态码为 200、响应体为 {"message": "Hello World"},同时请求不存在的路径 /nonexistent 断言返回 404 {"detail": "Not Found"}。
自动生成的交互式 API 文档
无需写任何文档代码,FastAPI 会自动为你的 API 生成两套文档界面。
Swagger UI:/docs
访问 http://127.0.0.1:8000/docs,你会看到由 Swagger UI 提供的交互式 API 文档:
在这里可以直接展开每个路径操作、查看参数与响应结构,甚至直接在浏览器里点击"Try it out"发起真实请求。
ReDoc:/redoc
再访问 http://127.0.0.1:8000/redoc,你看到的是由 ReDoc 渲染的另一套自动文档(更适合通读整个 API 结构):
两套 UI 都由同一个 OpenAPI schema 驱动(下文说明),因此展示的信息完全一致、只是呈现方式不同。
OpenAPI:所有 API 的"统一说明书"
FastAPI 会自动按照 OpenAPI 标准为你的整个 API 生成一份 schema(模式/纲要)。
什么是 "Schema"
"Schema" 是对某物的定义或描述——它不是实现它的代码,而是一份抽象描述。它可以指两类东西:
- API schema:描述你的 API 有哪些路径(paths)、每个路径接受哪些参数等。这里的 OpenAPI 是一份规范(specification),规定了如何定义 API 的 schema。
- Data schema:描述某份数据(例如 JSON 内容)的形状,即包含哪些 JSON 属性、各属性的数据类型等。
OpenAPI 定义了 API 的 schema,而该 schema 中关于请求/响应数据的部分,进一步使用 JSON Schema(JSON 数据 schema 的标准)来描述。三者关系可概括为:OpenAPI 描述"接口长什么样",JSON Schema 描述"数据长什么样"。
直接查看原始 openapi.json
如果想看最原始的 OpenAPI schema,FastAPI 会自动生成一个包含全部 API 描述的 JSON,访问 http://127.0.0.1:8000/openapi.json 即可,其开头形如:
{
"openapi": "3.1.0",
"info": {
"title": "FastAPI",
"version": "0.1.0"
},
"paths": {
"/items/": {
"get": {
"responses": {
"200": {
"description": "Successful Response",
"content": {
"application/json": {
...
仓库中的测试对这份 JSON 做了逐字段快照断言(见 tests/test_tutorial/test_first_steps/test_tutorial001_tutorial002_tutorial003.py 的 test_openapi_schema):openapi 版本为 3.1.0,info.title 默认取 FastAPI 实例的 title 参数默认值 "FastAPI",info.version 为 "0.1.0",路径 / 下有 get 操作,响应 200 的 content 类型为 application/json。从源码看,这些默认值正是 fastapi/applications.py 中 FastAPI.__init__ 的参数默认值(title: str = "FastAPI")。
OpenAPI 能用来做什么
这份 OpenAPI schema 是前面两套内置交互式文档的共同数据源,同时生态中还有大量基于 OpenAPI 的替代方案可以无缝接入你的 FastAPI 应用。更进一步,你可以用 OpenAPI 自动生成访问 API 的客户端代码——无论是前端、移动端还是 IoT 应用,都无需手写网络请求层。
在 pyproject.toml 中配置应用入口 entrypoint
与其每次手动告诉 fastapi 命令去哪找应用,更推荐在项目根目录的 pyproject.toml 中一次性声明入口:
[tool.fastapi]
entrypoint = "main:app"
entrypoint = "main:app" 告诉 fastapi 命令应这样导入应用:
from main import app
如果你的代码组织成包结构,例如:
.
├── backend
│ ├── main.py
│ ├── __init__.py
则应写成:
[tool.fastapi]
entrypoint = "backend.main:app"
它等价于:
from backend.main import app
为什么推荐用 pyproject.toml 而非命令行参数
fastapi dev 本身也支持另外两种定位应用的方式,但都有局限:
-
传入文件路径,由命令自动猜测要使用的 FastAPI 应用对象:
$ uv run fastapi dev main.py -
传入
--entrypoint选项:$ uv run fastapi dev --entrypoint main:app
但使用命令行方式时,你每次调用 fastapi 都得记得带上正确的路径或 entrypoint;而且其他工具无法读取它——例如仓库文档中提到的 VS Code 官方扩展(editor-support) 或其他基于 entrypoint 的部署工具。因此教程明确建议:优先把 entrypoint 写进 pyproject.toml,让所有工具共享同一份应用定位信息。
部署你的应用(可选)
在应用可运行之后,可选地一键部署到 FastAPI Cloud:
$ uv run fastapi deploy
Deploying to FastAPI Cloud...
✅ Deployment successful!
🐔 Ready the chicken! Your app is ready at https://myapp.fastapicloud.dev
CLI 会自动检测你的 FastAPI 应用并完成云端部署;如果尚未登录,浏览器会自动打开以完成身份认证流程。除此之外,由于 FastAPI 是开源且基于开放标准的框架,你完全可以把它部署到任意的云平台,只需遵循相应平台提供的 FastAPI 部署指南即可。
逐步回顾:理解每一行代码
官方教程把上面的最小示例拆解为六个步骤,逐行解释框架的核心概念。
Step 1:导入 FastAPI
from fastapi import FastAPI
FastAPI 是一个 Python 类,为你的 API 提供全部功能。
技术细节:从源码看,fastapi/applications.py 中 class FastAPI(Starlette)(第 42 行)直接继承自 Starlette,因此 FastAPI 应用可以无缝使用全部 Starlette 能力——中间件、WebSocket、静态文件、模板渲染等,都属于这一继承带来的底层能力。
Step 2:创建 FastAPI "实例"
app = FastAPI()
这里的 app 变量是 FastAPI 类的一个实例,它是你之后构建整个 API 的主要交互入口——添加路径操作、挂载中间件、注册异常处理器等都会发生在它身上。
Step 3:定义路径操作装饰器
什么是 Path(路径)
"Path" 指 URL 中从第一个 / 开始的后半部分。例如对于 URL:
https://example.com/items/foo
路径就是:
/items/foo
路径(path)也常被称为端点(endpoint)或路由(route)。在设计 API 时,路径是划分"关注点(concern)"与"资源(resource)"的主要方式。
什么是 Operation(操作)
"Operation" 指 HTTP 协议中的"方法(method)"之一,包括常用的:
POSTGETPUTDELETE
以及更少见的:
OPTIONSHEADPATCHTRACE
在 HTTP 协议中,你可以对同一条路径使用一个或多个这样的方法进行通信。构建 REST 风格 API 时通常用它们表达特定动作:
POST:创建数据GET:读取数据PUT:更新数据DELETE:删除数据
在 OpenAPI 中,每个 HTTP 方法被称为一个 "operation"——教程与框架文档中也沿用"操作"这个叫法。
定义路径操作装饰器
@app.get("/")
async def root():
return {"message": "Hello World"}
@app.get("/") 告诉 FastAPI:紧接着定义的这个函数负责处理发往路径 /、使用 get 操作的请求。语法上,Python 中 @something 这种写法称为"装饰器(decorator)"——它把下方的函数作为输入并对其做处理。在此例中,装饰器向 FastAPI 注册了"路径 / + 操作 get"的映射,因此它被称为"路径操作装饰器"。
除 @app.get() 外,FastAPI 对每种 HTTP 方法都提供了对应的装饰器:
@app.post()@app.put()@app.delete()- 以及
@app.options()、@app.head()、@app.patch()、@app.trace()
需要说明的是:FastAPI 不强制规定每种 HTTP 方法必须表达什么语义,你可以自由安排;上面的 CRUD 对应关系只是业界指导约定而非硬性要求(例如使用 GraphQL 时通常只用 POST 完成所有操作)。
Step 4:定义路径操作函数
路径操作函数就是装饰器下方紧跟着的这个 Python 函数,它由三部分组成:
- 路径:
/ - 操作:
get - 函数:装饰器
@app.get("/")下方的函数
每当 FastAPI 收到对 URL / 的 GET 请求,就会调用该函数。最小示例中的函数声明为 async def(异步函数);你也可以改用普通函数,效果相同:
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def root():
return {"message": "Hello World"}
上面这段同步版本代码位于 docs_src/first_steps/tutorial003_py310.py。仓库测试把 tutorial001_py310(async def 版)与 tutorial003_py310(def 版)放在同一个参数化夹具中逐一验证,说明两种写法对外表现一致。如果你不了解两者的区别,可参考教程 Async:"In a hurry?" 一节。
Step 5:返回内容
路径操作函数可以直接返回多种类型,FastAPI 会自动完成向 JSON 的转换:
- 可以返回
dict、list,以及str、int等单个值; - 也可以返回 Pydantic 模型(后续教程会详述);
- 还有大量其他对象与模型(包括 ORM 对象等)会被自动转换为 JSON。
由于这套序列化机制覆盖面广,你惯用的数据对象大概率已被原生支持,直接返回即可。
Step 6:部署
开发验证完成后,可通过 fastapi deploy 一条命令把应用部署到 FastAPI Cloud。FastAPI Cloud 由 FastAPI 同一作者与团队打造,把"构建 API"时的开发者体验延伸到"部署 API"环节。FastAPI 本身开源且基于标准实现,因此也可按所选云厂商的官方指南部署到任意平台。
回顾:核心步骤清单
对照教程最后给出的总结,一套完整的"起步流程"如下:
- 导入
FastAPI(from fastapi import FastAPI); - 创建
app实例(app = FastAPI()); - 用
@app.get("/")之类的装饰器写出路径操作装饰器; - 定义路径操作函数,例如
def root(): ...; - 用命令
fastapi dev启动开发服务器(生产部署使用fastapi run); - 可选地使用
fastapi deploy部署应用。
在这条主线上,本仓库为你提供了可逐行对照的三个锚点:示例代码见 docs_src/first_steps/tutorial001_py310.py 与 docs_src/first_steps/tutorial003_py310.py,应用类继承关系与构造参数默认值见 fastapi/applications.py,CLI 的依赖与行为见 fastapi/cli.py,而端到端的行为验证(/ 返回 200、/openapi.json 的快照结构、不存在的路径返回 404)都固化在 tests/test_tutorial/test_first_steps/test_tutorial001_tutorial002_tutorial003.py 中。你可以随时修改 main.py 中的路径、操作或返回值,观察 /docs 与 /openapi.json 如何实时反映你的改动——这正是理解 FastAPI 声明式开发风格最直观的一课。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0629
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00

