2. 开发环境与项目骨架搭建

FastAPI 项目能否稳定运行、方便协作、顺利部署,很大程度上取决于开发环境是否干净、依赖是否可复现、进程模型是否选对、目录结构是否清晰。本节围绕四件事展开:Python 虚拟环境、依赖管理、Uvicorn 与 Gunicorn 选型、项目目录结构设计。它们不是孤立的配置项,而是一条从“本机可跑”到“服务器可部署”的工程链路。

一、虚拟环境:把项目依赖与系统 Python 隔离

虚拟环境的核心价值是隔离。系统 Python 往往被操作系统或其他工具占用,直接 pip install 容易造成版本冲突。推荐使用 Python 3.11 或 3.12,并在项目根目录创建 .venv:

python -m venv .venv
# Windows
.venv\Scripts\activate
# macOS / Linux
source .venv/bin/activate
python -V

激活后,python 与 pip 都指向虚拟环境内部。判断是否生效,可执行 which python(Windows 用 where python),路径中应包含 .venv。虚拟环境目录不要提交到 Git,应在 .gitignore 中排除 .venv/、__pycache__/、.env 等。

二、依赖管理:区分运行依赖与开发依赖

依赖管理要解决“装什么、装哪个版本、别人怎么复现”。FastAPI 项目通常至少包含:fastapi、uvicorn[standard]、pydantic-settings;开发阶段再加 pytest、httpx、ruff、mypy。建议拆成两个文件:requirements.txt 放运行依赖,requirements-dev.txt 放开发依赖,后者通过 -r requirements.txt 继承前者。

# requirements.txt
fastapi==0.115.0
uvicorn[standard]==0.30.6
pydantic-settings==2.5.2

# requirements-dev.txt
-r requirements.txt
pytest==8.3.3
httpx==0.27.2
ruff==0.6.9

安装时使用 pip install -r requirements-dev.txt。生产环境只装运行依赖,减少攻击面与镜像体积。若团队规模扩大,可迁移到 pyproject.toml + uv 或 poetry,但初期用 requirements 文件足够清晰。关键原则是:所有直接依赖都锁定版本号,避免“今天能跑、明天报错”。

三、Uvicorn 与 Gunicorn 选型:开发与生产的进程模型

Uvicorn 是基于 ASGI 的服务器,支持 HTTP/1.1 与 WebSocket,启动快、调试友好,适合开发阶段使用 --reload 热重载。Gunicorn 本身是 WSGI 服务器,但可以通过 UvicornWorker 管理多个 ASGI 工作进程,提供进程守护、优雅重启和负载分发能力,更适合生产环境。

选型判断可以归纳为:开发用 uvicorn main:app --reload;生产用 gunicorn -k uvicorn.workers.UvicornWorker -w 4 -b 0.0.0.0:8000 main:app。工作进程数不是越多越好,经验公式为 (2 × CPU 核数) + 1,但 FastAPI 多为 I/O 密集型,实际应结合压测调整。若部署在 Kubernetes,也可直接用 Uvicorn 多进程模式,由编排层负责重启与扩缩容。

FastAPI 运行进程模型与请求链路 客户端 HTTP / WebSocket Nginx / 负载均衡 TLS 终止 · 静态资源 Gunicorn Master 进程守护 · 优雅重启 -k uvicorn.workers.UvicornWorker -w 4 UvicornWorker #1 FastAPI app 实例 UvicornWorker #2 FastAPI app 实例 UvicornWorker #3 FastAPI app 实例 开发模式 uvicorn main:app --reload --port 8000 单进程 · 热重载 · 调试友好 适合本地迭代与接口联调 生产模式 gunicorn -k uvicorn.workers.UvicornWorker -w 4 多进程 · 进程守护 · 优雅重启 适合容器与云主机部署

四、项目目录结构设计:按职责分层

目录结构决定代码可维护性。推荐采用“应用包 + 分层”的方式,把路由、模型、依赖、配置、测试分开,避免所有代码堆在 main.py。一个可直接使用的骨架如下:

fastapi-project/
├── app/
│   ├── __init__.py
│   ├── main.py              # 创建 FastAPI 实例、注册路由与中间件
│   ├── core/
│   │   ├── config.py        # Pydantic Settings 读取环境变量
│   │   └── security.py      # 认证与密码工具
│   ├── api/
│   │   ├── deps.py          # 公共依赖(数据库会话、当前用户)
│   │   └── v1/
│   │       ├── router.py    # 汇总 v1 子路由
│   │       └── endpoints/
│   │           ├── users.py
│   │           └── items.py
│   ├── models/              # SQLAlchemy ORM 模型
│   ├── schemas/             # Pydantic 请求/响应模型
│   ├── services/            # 业务逻辑
│   └── db/
│       ├── session.py       # 引擎与会话工厂
│       └── base.py          # Base 类
├── tests/
│   ├── conftest.py
│   └── test_users.py
├── .env.example
├── .gitignore
├── requirements.txt
└── requirements-dev.txt

这个结构的关键点:main.py 只负责组装,不写业务;api/v1 带版本号,方便未来平滑升级;schemas 与 models 分离,避免 ORM 对象直接暴露给客户端;core/config.py 集中管理配置,通过环境变量注入数据库地址、密钥等敏感信息。启动命令中的 main:app 对应 app/main.py 中的 app 实例,因此包名与变量名必须一致。

建议在 .env.example 中列出所有必需环境变量(如 DATABASE_URL、SECRET_KEY、DEBUG),新成员复制为 .env 后即可启动,减少“在我机器上能跑”的问题。

五、验证骨架是否可用