
1. 安装前必须想明白的三件事版本、虚拟环境与包管理器1.1 Python版本不是越新越好但也不能太旧先把结论放在前面FastAPI 要求 Python 3.8 及以上版本但如果你准备正式开发我建议直接上 Python 3.11 或 3.12。为什么这么推荐因为 FastAPI 的核心依赖是 Pydantic而 Pydantic v2 从底层用 Rust 重写后对 Python 版本的支持策略越来越激进。Python 3.7 及以下版本装不了新版的 Pydantic自然也就拖住了 FastAPI 的版本。虽然你可以通过安装旧版 FastAPI比如 0.103.x在 Python 3.7 上运行但我劝你别这么干——你不仅会失去新特性还会在遇到 bug 时陷入到底是代码问题还是版本太老导致的问题的泥潭。Python 3.8 虽然在 FastAPI 的支持列表里但它已经在 2024 年 10 月正式停止维护第三方库正在慢慢放弃对它的兼容。Python 3.9、3.10 算是还能用但没必要选的区间。Python 3.13 刚发布那阵子某些依赖的预编译 wheel 还没跟上安装时容易触发从源码编译的等待流程体验比较一般。所以我的个人经验是新项目优先 Python 3.12稳妥又不落后。这里有个很常见的误区很多人直接在系统自带 Python 上做全局安装。如果你的机器上已经有多个 Python 版本混着用那么在终端里敲python --version看到的那个版本很可能不是你真正想用的那个。建议用python3 --version或者完整路径确认一下避免装了半天发现装到了另一个解释器上。1.2 虚拟环境venv 够用别一上来就上 conda安装 FastAPI 这件事九成的问题出在没有隔离环境。你直接pip install fastapi装到系统全局短期看没什么但过几个月再装别的项目依赖就会发现版本冲突、权限问题接连不断。Python 自带的venv模块足够应付绝大多数 FastAPI 项目不需要额外安装任何东西。它在 Windows、Linux、macOS 上都好用能力虽然朴素但干净、可控。什么情况下我会考虑 conda当你同时要处理科学计算包、需要特定版本的 Python 解释器、或者公司内部统一用 conda 管理环境的时候。否则不要为了让一个 FastAPI 项目引入 conda 这种重量级选手虚拟环境本身只是隔离手段不是学习成本。还需要提醒的是有些初学者喜欢用virtualenv这个第三方库其实它的核心功能和venv没什么区别。既然 Python 3.8 出厂自带 venv就没必要再多装一个。少一个工具少一份出错的概率。1.3 包管理器pip 是基本盘uv 是效率神器安装 FastAPI 最标准的方式是pip install fastapi这没什么好争论的。但如果你经常创建新环境、反复安装依赖pip 的速度确实让人着急。我试过uv之后就回不去了——它是用 Rust 写的 Python 包管理器安装速度能达到 pip 的十倍以上。不过我的建议是分场景对待如果只是按这篇指南装一个 FastAPI 环境用 pip 就够了因为所有文档、教程、CI 脚本默认都用 pip通用性最好。但如果你决定长期用 FastAPI 写项目并且每天要重建环境可以试试 uv它会自动管理 Python 版本、虚拟环境命令上也很接近 pip 的使用习惯。还有一种情况是使用 poetry。它是完整的项目级依赖管理工具能生成 lock 文件锁定所有依赖版本适合多人协作的正式项目。但对于先看 FastAPI 能不能跑起来这个目标poetry 的引入会分散注意力。我的原则很简单先跑通再规范。2. 从零到能跑FastAPI 基础安装与验证2.1 创建虚拟环境并确认 Python 环境下面这段操作流程适用于 Windows 和 macOS/Linux 两种平台我尽量把差异点标出来。首先选一个干净的项目目录建议英文路径不要有空格和中文。然后创建虚拟环境# 在项目根目录执行 python -m venv .venv这里.venv是虚拟环境目录的名字用.venv开头是因为很多工具默认忽略以点开头的目录不会一不小心把环境里的文件提交到 Git。随后激活虚拟环境。Windows 下使用.venv\Scripts\activatemacOS/Linux 下使用source .venv/bin/activate激活成功的标志是命令提示符前面出现了(.venv)前缀。看到它就说明后续的pip、python命令都指向了虚拟环境内部的解释器不会再污染系统环境。激活完先确认一下 Python 版本避免之前残留的路径干扰python --version如果版本号不是你能接受的 3.11/3.12不要急着往下走先解决解释器的问题。常见的情况是python命令指向了 Windows 应用商店的占位程序或者旧版本可以用py -0Windows或which pythonmacOS/Linux查看可用的版本再通过py -3.12 -m venv .venv强制指定版本创建环境。2.2 安装 FastAPI 和 Uvicorn先搞清什么叫 ASGI 服务器FastAPI 的官方安装命令很简单pip install fastapi但你会发现装完之后你没法直接启动一个 Web 服务。原因是 FastAPI 本身只是框架它负责路由、参数校验、依赖注入这些应用层的工作但真正接收 HTTP 请求并把请求交给 FastAPI 处理的是 ASGI 服务器。两者是互相配合的关系。我经常用一个类比来解释FastAPI 是发动机Uvicorn 是整车。只有发动机你哪儿也去不了你得有转向、有轮子、有刹车才能在路上跑。所以下一步安装 ASGI 服务器pip install uvicorn[standard]这里我强烈建议使用带[standard]的版本而不是裸的uvicorn。[standard]会额外安装 uvloop高性能事件循环、httptools更快的 HTTP 解析、websocketsWebSocket 支持、watchfiles文件变更监听后面讲热更新时还会提到它等一堆提升性能和开发体验的依赖。如果你只装裸的uvicorn跑起来虽然没毛病但性能和开发便利性都会打折扣。拿到的是开发环境。如果要上生产后面还要加 gunicorn这个我在第四章详细展开。装完这两个包可以顺手确认一下pip list | grep -E fastapi|uvicorn正常会看到类似fastapi 0.115.x和uvicorn 0.30.x这样的输出。注意版本号前面用的是 0. 开头——FastAPI 目前仍然是 0.x 阶段但接口已经非常稳定你不用被版本号吓到它在生产环境大规模使用很多年了。2.3 验证安装不要只 print 一个版本号就结束很多教程到pip install fastapi就结束了但实际开发中装完能不能用是另一回事。我习惯在装完立刻做一个更完整的验证特别是确认核心依赖链没有问题。python -c import fastapi; import uvicorn; import pydantic; print(fastapi, fastapi.__version__); print(pydantic, pydantic.__version__)能干净地输出版本号说明导入路径正常、动态链接库没有缺、C 扩展也编译没问题。如果 Pydantic v2 在特定平台上没装好会在import pydantic这一步直接崩溃报错而且错误信息非常长容易吓到新手这一步能提前暴露问题。另外如果你的终端是从 PyCharm、VSCode 这类 IDE 内嵌打开的建议验证一下 IDE 默认的 Python 解释器是不是你刚创建的那个.venv。在 IDE 里新建的项目经常会出现终端里明明激活了环境但 IDE 实际用的是另一个解释器的情况。VSCode 可以在命令面板里执行Python: Select Interpreter来手动指定PyCharm 则在 Settings 的 Project Interpreter 里设置。这个小细节能省掉你后面调试半天代码没问题就是不生效的时间。3. 装完就跑启动第一个应用、理解热更新、排查高频报错3.1 最小可运行应用与启动参数即使目标是安装指南我也强烈建议在安装结束后立刻写一个最小的 FastAPI 应用并启动它。这样你才能百分百确认整个链路是通的。在项目目录下新建main.pyfrom fastapi import FastAPI app FastAPI() app.get(/) def read_root(): return {message: hello fastapi}然后在终端执行uvicorn main:app --host 0.0.0.0 --port 8000解释一下这个命令的含义main:app指的是main.py文件里的app对象。冒号左边是文件名去掉 .py右边是 FastAPI 实例的变量名。--host 0.0.0.0表示监听所有网络接口这样同一局域网内的设备也能访问到你的服务如果只想本机访问用127.0.0.1即可。--port 8000是端口默认其实是 8000写不写都行。启动后终端会显示一条日志Uvicorn running on http://0.0.0.0:8000此时在浏览器访问http://127.0.0.1:8000你会看到 JSON 响应{message:hello fastapi}。更关键的是访问http://127.0.0.1:8000/docsFastAPI 会自动生成一份交互式 API 文档页面你可以直接在页面上测试接口这对后面的开发调试帮助极大。安装工作到这里才算是真正闭环。3.2 命中热搜的启动不热更新根因与解决链路很多人在搜索FastAPI 安装指南时其实是带着装了但用起来不顺手的问题来的其中最常见的就是热更新不生效。你修改了代码保存服务没有自动重启还是返回旧结果。热更新依赖的是启动参数--reload。你只执行uvicorn main:app时文件变更不会触发重启。改成uvicorn main:app --reload重启一次服务后再修改代码保存终端会出现Reloading...的日志随后自动重启。这一步能解决掉大约七成的不热更新问题。剩下三成里最典型的坑是编辑器把文件保存成了替换式写入。某些编辑器比如特定配置下的 Vim、部分远程开发插件在保存文件时不是直接在原文件上修改而是把内容写到一个临时新文件再通过 rename 替换旧文件。这个行为在某些场景下不会被文件监听识别到导致--reload没反应。遇到这种情况可以试一下在启动命令里加上--reload-dir参数明确告诉 uvicorn 去监控哪个目录uvicorn main:app --reload --reload-dir .另一个容易踩的场景是 Docker。如果你把 FastAPI 跑在容器里并将宿主机代码目录挂载到容器内文件系统事件的传递在 Windows WSL2 的组合下经常出问题。我在这个坑上耗了整整一个下午最后是在 uvicorn 的启动命令里加--reload-dir /app并配合文件轮询监听在 Docker 环境下设置WATCHFILES_FORCE_POLLINGtrue环境变量才解决。如果你的使用场景涉及容器建议先把--reload-dir用起来。3.3 两个必知的启动报错端口占用与模块找不到报错一Address already in use端口被占用这种情况常见于之前启动的服务没有正常关闭或者 8000 端口被其他程序占用。报错信息很直白解决方法就是把占用端口的进程找出来并结束掉。Windows 下在新的终端窗口执行netstat -ano | findstr :8000输出最后一列是 PID然后用taskkill /PID 12345 /FmacOS/Linux 下用lsof -i :8000找到 PID 后执行kill -9 12345。处理完再重新启动 uvicorn 就正常了。报错二ModuleNotFoundError: No module named uvicorn这种情况大概率是你激活的虚拟环境和安装包的虚拟环境不是同一个。常见的情况是你之前用系统 Python 执行了pip install uvicorn但激活虚拟环境后uvicorn命令却指向了另一个位置。排查方式很简单在终端输入which uvicorn # Windows 下用 where uvicorn如果输出路径不在你的.venv目录里说明命令没有走当前环境。解决办法是不要直接用uvicorn命令而是用python -m uvicorn main:app --reload。python -m会强制使用当前激活的 Python 解释器去加载 uvicorn 模块能绕开绝大多数路径混乱的问题。4. 从能跑到能上线生产环境依赖与项目骨架4.1 开发依赖 vs 生产依赖装之前先分清安装 FastAPI 这件事如果只是本地学习fastapi uvicorn[standard]两个包就足够了。但当你准备部署到服务器时就需要重新审视依赖清单。我在生产环境部署 FastAPI 时的标准做法是用 gunicorn 作为进程管理器用 uvicorn 的工作器worker模式去处理 ASGI 请求。原因是 gunicorn 作为老牌 WSGI 服务器在进程管理、worker 数量控制、优雅重启方面非常成熟而 uvicorn 作为 ASGI worker 在性能和协议支持上表现出色两者组合是当前 FastAPI 生产部署最主流的搭配。安装命令pip install gunicorn启动方式变为gunicorn -w 4 -k uvicorn.workers.UvicornWorker main:app-w 4表示启动 4 个 worker 进程-k uvicorn.workers.UvicornWorker指定使用 uvicorn 提供的 ASGI worker 类。这样既获得了多进程并发能力又能让每个 worker 内部跑着高效的事件循环。有一点必须提醒gunicorn 不支持 Windows。如果你在 Windows 上开发本地调试用 uvicorn 单进程就够了生产环境通常是 Linux 服务器不用太担心这个问题。但也有人会遇到Windows 服务器怎么部署 FastAPI的场景——这时可以用hypercorn或者在 uvicorn 外面再套一层进程守护工具来实现多进程只是没有 gunicorn 那么顺手。如果项目需要读取配置文件我还会在生产环境装 pydantic-settings它是 Pydantic 官方出的配置管理库。相比用os.getenv到处读环境变量pydantic-settings 支持从一个.env文件集中读取配置并在启动时做类型校验配置错误会在一开始就暴露。pip install pydantic-settings4.2 requirements.txt 还是 pyproject.toml依赖管理的取舍项目跑起来后下一步是固定依赖版本否则过几个月重新部署时FastAPI 升级到新版本很可能带来不兼容变更。最省事的方式是pip freeze requirements.txt这个命令会把当前环境里所有已安装的包包括传递依赖全部列出来。但我不建议直接用这个文件作为项目的顶层依赖声明因为pip freeze输出的内容很冗余比如它会把uvicorn[standard]拆成 uvloop、httptools、websockets 等多个独立包名你根本看不出哪些是自己主动安装的。更好的做法是手动维护一份精简的requirements.txt只写顶层依赖fastapi0.115.6 uvicorn[standard]0.34.0 gunicorn23.0.0 pydantic-settings2.7.1安装时用pip install -r requirements.txt这样所有依赖版本都能追溯到明确的来源升级时你只需要改自己关心的那几个包名。如果你的项目要发布成 Python 包、或者团队协作要求极高的可复现性那可以考虑迁移到pyproject.toml poetry/uv 这套体系它能生成 lock 文件锁定完整依赖树。但若只是常规的 Web 后端项目一份精简的requirements.txt已经能覆盖九成需求。别为了规范而规范项目规模到了再说。4.3 一个能直接开工的 FastAPI 目录结构安装不只是装包更是搭架子。很多教程装完 FastAPI 就让读者在单文件里写接口这在小 demo 阶段没问题但项目一旦超过三五个路由单文件就会迅速失控。这里给出一个我常用的目录结构你可以直接抄作业myproject/ ├── app/ │ ├── __init__.py │ ├── main.py │ ├── api/ │ │ ├── __init__.py │ │ └── routes/ │ ├── core/ │ │ ├── __init__.py │ │ └── config.py │ ├── models/ │ │ └── __init__.py │ ├── schemas/ │ │ └── __init__.py │ └── services/ │ └── __init__.py ├── tests/ │ └── test_main.py ├── .env.example ├── .gitignore ├── requirements.txt └── README.md我先解释几个关键目录的作用避免你只是照搬但不理解main.py应用入口创建 FastAPI 实例注册路由和中间件。api/routes/按业务模块划分的接口定义比如users.py、orders.py每个文件里放一组相关路由。core/config.py读取 .env 配置的封装生产环境和开发环境方便切换。models/数据库模型定义如果你接入了数据库。schemas/Pydantic 模型负责请求参数校验和响应格式定义。services/业务逻辑层比如调用第三方 API、处理复杂计算这些逻辑不要直接塞进路由函数。main.py里只需要这样from fastapi import FastAPI from app.api.routes import users app FastAPI() app.include_router(users.router)启动命令变成uvicorn app.main:app --reload注意main:app变成了app.main:app因为入口文件从根目录的main.py移到了app/main.py。很多人在调整目录结构后启动失败原因就是没同步修改这个对象路径。4.4 环境变量与 .env 文件的安装级配置另一个和安装关系很大但容易被忽略的是环境变量配置。我见过不少项目数据库连接串、密钥直接写在代码里上线后被拉去讨论安全问题。这不是安装环节必须做的事但如果你按这篇指南从零搭建环境顺手做好会让你后面省心。在项目根目录创建.env文件APP_NAMEmyproject APP_ENVdevelopment DATABASE_URLsqlite:///./test.db然后在core/config.py里用 pydantic-settings 读取from pydantic_settings import BaseSettings class Settings(BaseSettings): app_name: str myproject app_env: str development database_url: str sqlite:///./test.db class Config: env_file .env settings Settings()这样配置的加载、校验、默认值都在一处管理比散落在各个模块里的os.environ.get清晰得多。注意.env本身不要提交到 Git正确做法是提交一份.env.example里面只放键名和示例值让团队成员自行复制成.env再填充真实信息。这一步虽然不是安装 FastAPI的必要环节但对于一个正经项目来说它就是环境安装的一部分。5. 绕开这些坑我装 FastAPI 这些年总结的实操经验5.1 不要硬碰老版本 Python该升级就升级我见过一个场景同事在公司服务器上辛辛苦苦敲完pip install fastapi随后看到一长串依赖解析错误最后发现服务器跑的是 Python 3.6而 FastAPI 早已不再支持这个版本。最先想到的方案是在老版本上装旧版 FastAPI但新项目怎么可能愿意用旧版折腾半天最后还是申请升级 Python 解释器彻底解决。我的建议是项目初始化前先把 Python 版本确定下来并且团队其他人也要同步。升级解释器这件事越早做成本越低。另外如果你的服务器是由包管理器比如 apt、yum自动安装的 Python升级时要注意系统服务和第三方工具可能依赖这个 Python 路径不要贸然删除旧版本最好通过官方源码或 pyenv 安装新版本并软链到独立路径。5.2 国内网络环境下pypi 镜像是个保命配置如果你在安装过程中遇到下载超时或者依赖包一直拉不下来问题多半出在网络延迟上而不是你的命令写错了。解决方式是在 pip 命令里临时指定国内镜像源pip install fastapi -i https://pypi.tuna.tsinghua.edu.cn/simple如果不想每次都写这一长串可以在用户目录下创建~/.pip/pip.confWindows 是%APPDATA%\pip\pip.ini写入[global] index-url https://pypi.tuna.tsinghua.edu.cn/simple这会让 pip 默认走国内镜像。清华源、阿里源、中科大源我都用过稳定性差别不算大选一个就行。不过要注意如果你的公司内部有私有 PyPI 仓库或者项目发布需要上传包到内部源全局改镜像可能会影响这些操作需要结合实际情况判断。5.3 别用 sudo pip install权限问题会越搞越乱在 macOS/Linux 上很多人图省事直接sudo pip install fastapi。这样装完确实全局可用但隐患很大系统 Python 的目录被第三方包污染以后你升级系统包、使用系统自带的工具都可能出问题。而且一旦你进入虚拟环境这个通过 sudo 装的包又不在环境里还是 import 不到。我在实际使用中养成的习惯是所有 Python 项目一律用虚拟环境没有例外。如果创建虚拟环境这一步觉得麻烦可以配置 shell 的 alias 一键完成。比如在 bashrc/zshrc 里加一个函数mkvenv() { python -m venv .venv source .venv/bin/activate }以后再也不用想要不要 sudo的问题全部依赖都隔离在项目内部出问题直接删掉.venv目录重新创建五分钟又是一个干净环境。5.4 锁版本要趁早别等项目跑起来再亡羊补牢我早期做项目时候从不固定依赖版本每次都在服务器上现装直到有次 FastAPI 小版本升级引入了一个路由匹配行为的变化导致线上接口行为异常查了很久才发现是依赖升级导致的。从那以后我每个项目都提前准备好精确到小版本的requirements.txt。做法是初次安装时先不锁版本功能跑通后直接pip list看看当前版本号手动整理进 requirements.txt再配合一次性重新安装来验证。这个流程只需要多花十分钟但能避免未来某个深夜突如其来的为什么生产环境和我本地不一样。还有一个细节如果你用的是uvicorn[standard]这种带 extra 的写法写在 requirements.txt 里时记得保留方括号形如uvicorn[standard]0.34.0。很多人复制的时候只复制了uvicorn结果装完缺了一堆配套依赖热更新和 WebSocket 功能都不完整。5.5 新版本 FastAPI 带来的两个小惊喜最后说一下近期版本装完可能会发现的两个变化。第一个是 FastAPI 0.111 之后项目里新增了fastapi-cli这个依赖你可以用fastapi dev main.py命令启动开发服务器它内部会帮你处理 uvicorn 和热更新参数。安装 FastAPI 时会自动带上这个工具如果你在开发环境看到多装了几个包不用惊讶那是官方在简化开发体验。不过我个人仍然习惯直接用 uvicorn因为fastapi dev会默认开启 reload如果在生产环境不小心执行了它性能会有明显损耗。命令用错场景反而容易踩坑。第二个是 0.115 之后OpenAPI 文档的生成默认使用新的方式如果你之前的项目里自定义了文档标题、描述、版本号等元信息一定要测试一下/docs页面是否还符合预期。绝大多数情况下不受影响但老的教程里那种改 title 就能改文档标题的行为在新版本里建议统一通过FastAPI(...)的参数来传而不是依赖旧版本默认值。5.6 最后分享一个我自己的安装习惯每次在全新机器上配置 FastAPI 开发环境我会按这个固定顺序执行# 1. 检查基础工具 python --version pip --version # 2. 更新 pip这一步能避免很多依赖解析问题 python -m pip install --upgrade pip # 3. 创建并激活虚拟环境 python -m venv .venv source .venv/bin/activate # 4. 安装核心依赖 pip install fastapi[all]可能有人对最后一行有疑问fastapi[all]是什么这是 FastAPI 官方提供的一个扩展安装选项它会一次性装好 uvicorn[standard]、jinja2、python-multipart 等一堆常用依赖对于探索学习阶段的同学来说非常省事。但正式项目我不会用它因为这种全家桶安装方式会在环境里堆积很多你根本用不到的包削弱依赖声明的准确性。学习时图省事用它做项目时还是回到按需安装。装完之后做个快照确认pip list看到自己真正需要的包都在再启动uvicorn app.main:app --reload去/docs页面点两下环境就彻底稳了。整个过程不超过五分钟但换来的是后面写业务代码时完全不被打扰的状态。很多时候我们抱怨环境问题多其实是因为安装阶段太随意框架本身并不难装难的是把整个环境的边界划得清清楚楚。