Chapter 01

FastAPI 简介与环境搭建

了解 FastAPI 的设计哲学,与传统框架对比,搭建开发环境,编写第一个 API,并探索自动生成的交互式文档。

什么是 FastAPI

FastAPI 是由 Sebastián Ramírez(tiangolo)于 2018 年创建的现代 Python Web 框架,专为构建 API 而设计。它基于 Python 3.6+ 的类型提示,兼具极高的性能、优秀的开发体验和自动化文档生成能力。

FastAPI 不是从零造轮子,而是站在两个巨人肩膀上:Starlette(提供 ASGI 基础、路由、中间件等 Web 功能)和 Pydantic(提供数据验证与序列化)。这两层组合带来了生产级性能与开发友好性的完美平衡。

ASGI(Asynchronous Server Gateway Interface)
Python 异步 Web 服务器网关接口,是 WSGI 的现代继承者。WSGI 是同步的(每个请求占用一个线程),而 ASGI 支持异步处理,允许一个进程通过 async/await 并发处理数千个连接。FastAPI 完全基于 ASGI 构建,因此天然支持 WebSocket、SSE 等长连接协议。
Uvicorn
基于 uvloop 和 httptools 的高性能 ASGI 服务器,是运行 FastAPI 应用的推荐服务器。uvloop 是对 asyncio 事件循环的 Cython 重写,性能接近 Go 语言。开发时使用 --reload 参数实现热重载;生产环境通常与 Gunicorn 配合,用 Gunicorn 管理多个 Uvicorn worker 进程。
Starlette
FastAPI 底层使用的轻量级 ASGI 框架,提供路由、中间件、静态文件服务、WebSocket、后台任务等核心功能。FastAPI 在 Starlette 之上添加了类型提示集成、自动参数验证、OpenAPI 文档生成等能力。你可以直接使用 Starlette 的功能,因为 FastAPI 继承自 Starlette。
Pydantic v2
Python 最流行的数据验证库,FastAPI 0.100+ 开始使用 Pydantic v2(用 Rust 重写的核心)。Pydantic 通过 Python 类型注解自动验证数据、进行类型转换、生成 JSON Schema。FastAPI 用它处理请求体解析、响应数据序列化和 OpenAPI Schema 生成,v2 相比 v1 性能提升 5-50 倍。
OpenAPI 规范
业界标准的 REST API 描述格式(前身是 Swagger 规范),以 JSON/YAML 格式描述 API 的端点、参数、请求/响应格式、认证方式等。FastAPI 基于代码中的类型注解自动生成 OpenAPI 3.0 规范文档,无需手动编写。通过 /openapi.json 可获取原始规范,/docs 提供 Swagger UI,/redoc 提供 ReDoc 界面。

与 Flask、Django 的对比

选择框架前,先理解三大框架的定位差异:

特性 FastAPI Flask Django
定位 API 优先的现代框架 轻量微框架 全功能 Web 框架
性能 极高(ASGI 异步) 中等(WSGI 同步) 中等(WSGI 同步)
类型安全 原生支持,自动验证 需手动添加 有限支持
API 文档 自动生成 Swagger/ReDoc 需插件(flask-apispec) 需 DRF + drf-spectacular
数据验证 Pydantic 自动验证 需 marshmallow/WTForms Django Forms/Serializers
异步支持 原生 async/await 有限(Flask 2.0+) 有限(Django 3.1+)
学习曲线 平缓(熟悉类型提示后) 最平缓 陡峭(概念多)
适用场景 API 服务、AI 后端、微服务 小型 Web 应用、原型 内容管理、完整 Web 应用
选型建议 构建纯 API 服务(特别是 AI 后端)→ FastAPI;需要完整 Web 功能(模板、ORM、Admin)→ Django;快速原型或小项目 → Flask。2024 年 Python 开发者调查显示,FastAPI 已超过 Flask,成为最受欢迎的 Python Web 框架。

安装与环境配置

推荐使用虚拟环境隔离项目依赖。以下提供 venv(标准库)和 uv(新一代包管理器)两种方式:

方式一:使用 venv(传统方式)

# 创建虚拟环境
python3 -m venv .venv

# 激活虚拟环境
# macOS/Linux:
source .venv/bin/activate
# Windows:
.venv\Scripts\activate

# 安装 FastAPI 和 Uvicorn(含 standard 额外依赖:websockets、httptools 等)
pip install "fastapi[standard]"

# 验证安装
python -c "import fastapi; print(fastapi.__version__)"
# 输出: 0.115.x

方式二:使用 uv(推荐,速度提升 10-100x)

# 安装 uv(一次性操作)
curl -LsSf https://astral.sh/uv/install.sh | sh

# 创建项目并初始化
uv init my-fastapi-app
cd my-fastapi-app

# 添加 FastAPI 依赖
uv add "fastapi[standard]"

# 运行项目(uv 自动管理虚拟环境)
uv run uvicorn main:app --reload
推荐使用 uv uv 是 2024 年由 Astral(Ruff 的作者)发布的新一代 Python 包管理器,用 Rust 编写,安装速度比 pip 快 10-100 倍,并且内置了虚拟环境管理和 Python 版本管理,逐渐成为 Python 项目的标准工具链。

第一个 FastAPI 应用

创建 main.py,编写最简单的 FastAPI 应用:

from fastapi import FastAPI
from pydantic import BaseModel

# 创建 FastAPI 应用实例
# title、version 会出现在自动生成的文档中
app = FastAPI(
    title="我的第一个 FastAPI 应用",
    version="0.1.0",
    description="用 FastAPI 构建的高性能 API 示例"
)

# ── 请求体模型 ────────────────────────────────────────────
class Item(BaseModel):
    name: str
    price: float
    in_stock: bool = True

# ── 路径操作:GET / ───────────────────────────────────────
@app.get("/")
async def root():
    """根路径,返回欢迎信息。"""
    return {"message": "Hello, FastAPI!"}

# ── 路径操作:GET /items/{item_id} ───────────────────────
@app.get("/items/{item_id}")
async def read_item(item_id: int, q: str | None = None):
    """
    获取单个商品。
    - item_id: 路径参数(自动类型转换为 int)
    - q: 可选查询参数
    """
    result = {"item_id": item_id}
    if q:
        result["q"] = q
    return result

# ── 路径操作:POST /items/ ────────────────────────────────
@app.post("/items/", status_code=201)
async def create_item(item: Item):
    """
    创建商品。
    - 请求体自动解析并验证为 Item 模型
    - 返回 201 Created 状态码
    """
    return {"created": True, "item": item.model_dump()}

启动开发服务器

# --reload:文件变更时自动重启(仅开发环境使用)
uvicorn main:app --reload

# 输出:
# INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
# INFO:     Started reloader process [12345] using WatchFiles
# INFO:     Started server process [12346]
# INFO:     Waiting for application startup.
# INFO:     Application startup complete.

# 指定主机和端口(允许外部访问)
uvicorn main:app --reload --host 0.0.0.0 --port 8080

# 使用 FastAPI CLI(fastapi[standard] 包含)
fastapi dev main.py    # 开发模式
fastapi run main.py    # 生产模式

探索自动文档

启动后,FastAPI 自动在以下地址提供交互式 API 文档,无需任何额外配置:

http://127.0.0.1:8000/docs → Swagger UI(交互式测试界面) http://127.0.0.1:8000/redoc → ReDoc(阅读友好的文档界面) http://127.0.0.1:8000/openapi.json → 原始 OpenAPI 3.0 规范(JSON 格式)

Swagger UI(/docs)

  • 可直接在浏览器中发送 API 请求
  • 查看请求/响应 Schema
  • 支持认证 Token 输入测试
  • 展示所有端点与参数说明
  • 适合开发调试与团队演示

ReDoc(/redoc)

  • 三栏布局,阅读体验更好
  • 左侧导航、中间说明、右侧示例
  • 适合作为对外 API 文档发布
  • 代码示例支持多语言切换
  • 不支持直接发送请求

丰富文档内容

通过在函数 docstring 和 Field 中添加说明,可以让自动文档更完整:

from fastapi import FastAPI
from pydantic import BaseModel, Field
from typing import Annotated

app = FastAPI()

class Product(BaseModel):
    name: Annotated[str, Field(
        description="商品名称",
        example="MacBook Pro",
        min_length=1,
        max_length=100
    )]
    price: Annotated[float, Field(
        description="商品价格(人民币)",
        example=12999.0,
        gt=0  # greater than 0,自动验证
    )]
    category: Annotated[str, Field(
        description="商品分类",
        example="电子产品"
    )]

@app.post(
    "/products/",
    summary="创建新商品",         # 文档中的简短标题
    description="创建一个新的商品条目,价格必须大于 0。",
    response_description="成功创建的商品信息",
    tags=["商品管理"],            # 分组标签
    status_code=201
)
async def create_product(product: Product):
    """
    创建商品的完整流程:

    - **name**: 必填,1-100 个字符
    - **price**: 必填,必须大于 0
    - **category**: 必填,商品分类名
    """
    return {"id": 1, **product.model_dump()}

项目文件结构

一个规范的 FastAPI 项目结构,便于后续章节扩展:

my-fastapi-app/
├── app/
│   ├── __init__.py
│   ├── main.py            # FastAPI 应用入口
│   ├── core/
│   │   ├── config.py      # 配置管理(pydantic-settings)
│   │   └── security.py    # JWT / 密码哈希工具
│   ├── routers/
│   │   ├── users.py       # 用户相关路由
│   │   ├── items.py       # 商品相关路由
│   │   └── auth.py        # 认证路由
│   ├── models/
│   │   ├── user.py        # SQLAlchemy ORM 模型
│   │   └── item.py
│   ├── schemas/
│   │   ├── user.py        # Pydantic 请求/响应模型
│   │   └── item.py
│   ├── services/
│   │   ├── user_service.py  # 业务逻辑层
│   │   └── ai_service.py
│   └── database.py        # 数据库连接配置
├── tests/
│   ├── conftest.py        # pytest fixtures
│   └── test_users.py
├── alembic/               # 数据库迁移
│   └── versions/
├── .env                   # 环境变量(不提交 git)
├── pyproject.toml         # 项目配置(uv/pip)
└── Dockerfile
注意:从第一天就规范项目结构 将所有代码放在单个 main.py 中适合学习,但生产项目必须按功能分层(routers/models/schemas/services)。这种结构在第 2 章介绍 APIRouter 后会逐步建立起来。

完整示例:带类型提示的 Hello World

from fastapi import FastAPI
from pydantic import BaseModel
from datetime import datetime

app = FastAPI(title="FastAPI 示例", version="1.0.0")

# ── 响应模型 ─────────────────────────────────────────────
class HealthResponse(BaseModel):
    status: str
    version: str
    timestamp: datetime

# ── 健康检查端点 ──────────────────────────────────────────
@app.get("/health", response_model=HealthResponse)
async def health_check():
    """应用健康检查,返回运行状态与当前时间。"""
    return HealthResponse(
        status="ok",
        version="1.0.0",
        timestamp=datetime.now()
    )

# ── 数学运算端点(演示路径参数类型转换)────────────────────
@app.get("/add/{a}/{b}")
async def add_numbers(a: float, b: float):
    """将两个数字相加。URL 中的字符串自动转换为 float。"""
    return {"a": a, "b": b, "result": a + b}

# 访问 http://127.0.0.1:8000/add/3.14/2.86 → {"a":3.14,"b":2.86,"result":6.0}
# 访问 http://127.0.0.1:8000/add/abc/1   → 422 Unprocessable Entity(自动验证错误)
本章小结 FastAPI 的三大核心优势:自动文档(Swagger/ReDoc)、类型安全(Pydantic v2 自动验证)、高性能(ASGI + uvloop)。它站在 Starlette 和 Pydantic 两个巨人肩膀上,是构建现代 Python API 的最佳选择。下一章我们深入学习路径参数、查询参数、请求体的完整用法,以及如何用 APIRouter 组织大型项目。