FastAPI 学习笔记 01 | 特性、安装与启动,从零跑起第一个接口
- 2026-11-05 08:29:59
FastAPI 学习笔记 01 | 特性、安装与启动,从零跑起第一个接口如果你写过 Flask,大概经历过这种循环:接口写好了,参数校验自己写一堆 if not isinstance(x, int);接口改了字段,前端跑来问"到底要传什么";上线前还要手写一份 Swagger 文档,写完就和代码一起过期了。 FastAPI 把这些活儿一次性收走了。它的核心思路只有一句话: 这不是比喻。你在函数签名里写 item_id: int,FastAPI 就真的会:把路径里的字符串转成 int、不是数字就返回结构化的 422 错误、在 /docs 里把 item_id 标注成 integer、并把返回值按声明序列化成 JSON。 一句话概括它的定位:一个基于 Python 标准类型注解的现代 Web 框架,底层用 Starlette 处理 Web,用 Pydantic 处理数据。 官方首页列了八条,逐条讲一下实际体感,比抄列表有用。 不用纠结,看场景:
一句话选型:做纯 API、要异步、要文档、要给前端或 AI 服务提供接口 → FastAPI;需要开箱即用的后台管理和 ORM 全家桶 → Django;就想跑个小脚本服务 → Flask 也够。 近两年 FastAPI 增长最快的场景其实是 AI 应用后端(模型服务、Agent 工具接口、SSE 流式输出),因为流式响应和异步天然合拍。 打开终端,先做两件事。 第一步,确认 Python 版本。 FastAPI 当前版本(0.162.x)要求Python 3.10 及以上,支持到 3.14。如果你的输出是 3.9 或更低,装的时候会直接被拒。macOS 用户建议用 uv 或 pyenv 管理版本,别动系统自带的 Python。 第二步,创建虚拟环境。这一步别省,虚拟环境能让你以后换版本、删环境都不影响系统。 激活成功的标志是命令行前面多了 (.venv)。 uv 是目前 Python 生态里最快的包管理器,也是 FastAPI 官方文档现在首推的方式。 国内网络建议加个镜像源,能少等几分钟: 这里有个关键细节:为什么是fastapi[standard]而不是fastapi? 裸装 fastapi 只有框架本体,不含服务器和命令行工具。[standard] 这个可选依赖组会额外带上: uvicorn[standard] —— 真正跑起来服务的 ASGI 服务器 fastapi-cli —— 提供 fastapi 命令(fastapi dev / fastapi run) httpx2 —— 测试客户端 TestClient 用 python-multipart —— 解析表单和文件上传必需 jinja2 、email-validator、pydantic-settings 等常用件 所以新手直接装fastapi[standard],别装裸的。否则你会遇到"装完了但没有 fastapi 命令"的经典问题。 引号也不能省。[ 在 zsh 里是通配符,不加引号可能被 shell 吃掉。同理,PowerShell 里也建议加引号。 一个小提醒:从近期版本起,standard 组里还包含 fastapi-cloud-cli(用于部署到 FastAPI Cloud)。如果你完全用不到、也不想让它被装进环境,可以换成: 功能一样,只是少了那个云部署的 CLI。 在项目里新建 main.py: 就这十几行,已经包含了一个带路径参数、带可选查询参数、带类型校验、带自动文档的接口。 用 uv 的话是: 你会看到类似这样的启动信息: fastapi dev 做三件事:自动找到 main.py 里的 app、用 Uvicorn 起服务、开启热重载。改完代码保存,服务自动重启,不用手动 Ctrl+C 再起。 这里有个容易踩的坑:fastapi dev 默认只监听 127.0.0.1,所以手机或局域网内其他机器访问不到。需要局域网调试时用: 浏览器打开 http://127.0.0.1:8000/items/5?q=hello,返回: 注意返回的 item_id 是数字 5,不是字符串 "5"——路径参数里拿到的原本是字符串,是 FastAPI 按你的注解自动转换的。 再试一下 http://127.0.0.1:8000/items/abc,会得到 HTTP 422: 这行错误信息是重点。你没有写任何校验代码,但 FastAPI 告诉你:错在 path 的 item_id、错因是无法解析成整数、原始输入是什么。对比一下自己手写校验的 return {"error": "参数错误"},这就是差距。 打开 http://127.0.0.1:8000/docs: 这是 Swagger UI。你可以直接在页面上点 "Try it out" 发真实请求,不需要 Postman。所有接口、参数类型、必填与否都列好了——因为你写了类型注解,它才知道。 再看 http://127.0.0.1:8000/redoc,同一份数据的另一种排版,适合当对外文档交给合作方。 还没完,机器读的版本在 http://127.0.0.1:8000/openapi.json。这份 JSON 就是 OpenAPI 规范,前端可以直接拿它生成请求代码,网关可以拿它做校验,测试可以拿它做契约测试。 记住这个关系:类型注解 → OpenAPI schema → Swagger UI / ReDoc / 代码生成。文档不是写出来的,是推导出来的。 把 main.py 改成这样: 因为开了热重载,保存后服务已经自动重启。回到 /docs,你会发现多了一个 PUT /items/{item_id},而且请求体的结构已经自动画出来了:name 是 string、price 是 number、is_offer 是 boolean 且可选。 直接用 curl 试一下(在 JSON 里 price 传字符串 "9.99"): 返回: 字符串"9.99"被自动转成了 float。这不是巧合,是 Pydantic 的宽松模式在做类型转换。而如果你传 {"name": "键盘"}(缺 price),会立刻收到 422,提示 price: Field required。 提前避掉,能省一晚上。 1.fastapi: command not found装的是裸 fastapi,没带 [standard],所以没有 CLI。补一句 pip install "fastapi[standard]"。临时救急也可以直接用 uvicorn: 2. 端口被占用报 Address already in use,换端口:fastapi dev main.py --port 8001。想找出谁占着 8000,lsof -i :8000。 3. 文件上传或表单报错提示 python-multipart must be installed。这就是裸装的后遗症,装 [standard] 即可,或单独 pip install python-multipart。 4. Python 版本太低pip 报 No matching distribution found,先看 python3 --version。低于 3.10 就要升级了。 5. 改了代码不生效先确认你起的是 fastapi dev(带重载),而不是 fastapi run(生产模式,不带重载)。 6.fastapi dev和fastapi run的区别dev 面向本地:127.0.0.1 + 热重载 + 彩色提示。run 面向生产:默认 0.0.0.0、不重载、性能更好。别拿dev上生产。真正的线上部署通常还要套一层 Nginx 或容器编排,这个后面单独写一篇。 FastAPI = Starlette(Web)+ Pydantic(数据),核心是用一遍类型注解,换四处收益:校验、转换、序列化、文档。 装 fastapi[standard],不要装裸 fastapi;引号不能省;Python 要 3.10+。 fastapi dev main.py 起开发服务,默认 127.0.0.1:8000,自带热重载。 /docs 是 Swagger UI,/redoc 是 ReDoc,/openapi.json 是给机器读的契约。 类型写错或没写,最直接的后果就是 422 和文档缺失——在 FastAPI 里,类型不是注释,是契约。 下一篇预告:把路由拆开,讲 APIRouter、路径/查询/请求体参数的完整用法,以及返回值和状态码怎么控制。这一篇里的 main.py 会正式长成一个有目录结构的项目。
如果这篇笔记对你有帮助,欢迎点赞、在看、转发给正在选框架的朋友。有问题可以留言,我会在下一篇里一起回答。
这是「FastAPI 学习笔记」合集的第一篇。整套笔记的目标很明确:不背文档,而是把 FastAPI 从"能跑"到"能上线"的每一步都走一遍。这一篇解决两件事——它凭什么值得学,以及怎么在本地把第一个接口跑起来。
一、先说结论:为什么是 FastAPI
你写一遍 Python 类型注解,框架拿它同时做四件事——参数校验、数据转换、序列化、生成接口文档。
二、官方八大特性,翻译成人话
快(Fast)官方说法是性能与 NodeJS、Go 同级,是 Python 框架里最快的之一。原因不神秘:Starlette 是纯 ASGI 实现,Pydantic v2 的核心校验逻辑用 Rust 写的。需要提醒的是,这个"快"指的是框架自身的开销。你的接口如果卡在一条慢 SQL 上,换什么框架都一样慢。 写代码快(Fast to code)官方给的数字是开发效率提升 200%~300%,这是他们内部团队做生产项目的估算,别当精确指标看。真实的体感来自"少写胶水代码":一个参数的声明同时完成了校验和文档,你不需要在两个地方维护同一份契约。 更少的 Bug同样来自官方估算,减少约 40% 的人为错误。可信度打折扣,但方向是对的——类型注解让编辑器在你写完之前就报错,而不是等到线上日志里出现 KeyError。 智能提示友好(Intuitive)这条是我个人最看重的。因为类型是真的类型(不是装饰器字符串),VS Code / PyCharm 里补全、跳转、重构全部有效。用 response_model 声明返回结构后,连返回值的字段都能补全。 简单(Easy)没有新的 DSL,没有要背的魔术方法。会写 Python 函数就能写路由。这也是它比 Django 更适合"快速做一个 API 服务"的原因。 短(Short)尽量减少重复。声明一次参数,校验、文档、转换全部到位——重复越少,改需求时漏改的地方就越少。 健壮(Robust)开箱即用的生产级能力:自动交互式文档、依赖注入、OAuth2/JWT 支持。新版还在持续补工程能力,比如原生的 OpenTelemetry 可观测性支持。 基于标准(Standards-based)完全兼容 OpenAPI 和 JSON Schema。这意味着你的接口能被任何标准工具消费:Swagger UI、ReDoc、Postman 导入、前端代码生成器。这是它和很多"自造文档"框架的本质区别——不是生成了一份文档,而是生成了一份机器可读的契约。
三、和 Flask、Django 怎么选
四、安装:先确认版本
python3 --versionmkdir fastapi-demo && cd fastapi-demopython3 -m venv .venvsource .venv/bin/activateWindows 用 .venv\Scripts\activate
方式一:用 uv(推荐,快)
安装 uv(macOS / Linux)curl -LsSf https://astral.sh/uv/install.sh | sh # 初始化项目并安装uv inituv add ”fastapi[standard]”
方式二:用 pip
pip install ”fastapi[standard]”pip install ”fastapi[standard]” -i https://pypi.tuna.tsinghua.edu.cn/simplepip install ”fastapi[standard-no-fastapi-cloud-cli]”五、第一个接口
from fastapi import FastAPIapp = 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}
启动
fastapi dev main.pyuv run fastapi dev main.py╭────────── 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: Uvicorn running on http://127.0.0.1:8000INFO: Started reloader process using WatchFiles
fastapi dev main.py --host 0.0.0.0 --port 8001验证
{”item_id”: 5, ”q”: ”hello”}{”detail”: [{”type”: ”int_parsing”,”loc”: [”path”, ”item_id”],”msg”: ”Input should be a valid integer, unable to parse string as an integer”,”input”: ”abc”}]}
六、白送的文档
七、加一个请求体,感受"声明一次"
from fastapi import FastAPIfrom pydantic import BaseModelapp = FastAPI()class Item(BaseModel):name: strprice: floatis_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}
curl -X PUT ”http://127.0.0.1:8000/items/1” \-H ”Content-Type: application/json” \-d '{”name”: ”键盘”, ”price”: ”9.99”}'
{”item_name”: ”键盘”, ”item_id”: 1}八、几个新手必踩的坑
python -m uvicorn main:app --reload九、本篇小结
本文来自网友投稿或网络内容,如有侵犯您的权益请联系我们删除,联系邮箱:wyl860211@qq.com 。