Skip to main content
今日目标:FastAPI 是当下最火的 Python Web 框架。今天我们不只是写个 “Hello World”,而是要彻底搞懂 “什么是 RESTful API”“URL 如何传参”“如何启动服务器” 以及 “Swagger 文档如何自动生成” 这四个核心问题。今天不只是写代码,而是要彻底理解 “FastAPI 为什么比 Flask 快”“路径参数和查询参数的区别” 以及 “为什么需要 ASGI 服务器”

学习内容 (30 mins)

在开始写代码前,先搞懂这些核心概念,否则后面的代码你会看得云里雾里。
FastAPI 是什么?FastAPI 是一个现代、快速的 Python Web 框架,用于构建 API。它基于 Python 3.6+ 的类型提示(Type Hints)和异步编程(Async/Await)。为什么选择 FastAPI?
  • 性能极快:基于 Starlette 和 Pydantic,性能接近 Node.js 和 Go
  • 自动文档:自动生成 Swagger UI 和 ReDoc 文档
  • 类型安全:基于 Python 类型提示,IDE 支持好
  • 异步支持:原生支持异步编程,适合高并发场景
  • 数据验证:基于 Pydantic,自动验证请求数据
FastAPI vs Flask vs Django
  • Flask:轻量级,但需要手动写很多代码(路由、验证、文档)
  • Django:功能全面,但重量级,学习曲线陡
  • FastAPI:现代化,自动生成文档,性能好,适合 API 开发
FastAPI 的核心特性
  • 自动类型转换:URL 参数自动转换为指定类型
  • 自动数据验证:基于 Pydantic 自动验证请求数据
  • 自动文档生成:访问 /docs 即可查看交互式 API 文档
  • 异步支持:原生支持 async/await,适合高并发
什么是 RESTful API?REST(Representational State Transfer)是一种 API 设计风格,通过 HTTP 方法(GET、POST、PUT、DELETE)操作资源。RESTful 设计原则
  • 资源导向:URL 表示资源,如 /users/servers
  • HTTP 方法:GET(查询)、POST(创建)、PUT(更新)、DELETE(删除)
  • 状态码:200(成功)、201(创建)、400(错误)、404(未找到)
  • 无状态:每个请求都是独立的,不依赖之前的请求
路径参数 vs 查询参数
  • 路径参数 (Path Parameters)
    • 位置:URL 路径的一部分,如 /users/5 中的 5
    • 用途:定位特定资源(获取 ID 为 5 的用户)
    • 语法:在路径中写 {user_id},如 /users/{user_id}
    • 示例:GET /users/5 - 获取 ID 为 5 的用户
  • 查询参数 (Query Parameters)
    • 位置:URL 问号 ? 后面的键值对
    • 用途:过滤、排序、分页
    • 语法:函数参数,但不在路径中写 {xx}
    • 示例:GET /users?limit=10&sort=age - 获取前 10 个用户,按年龄排序
实际应用场景
  • 路径参数:获取详情、删除资源
  • 查询参数:列表查询、搜索、分页、筛选
什么是 ASGI?ASGI(Asynchronous Server Gateway Interface)是 Python 异步 Web 服务器和框架之间的标准接口。为什么需要 ASGI 服务器?
  • FastAPI 只是框架:它定义了路由、处理逻辑,但不负责监听端口
  • Uvicorn 是服务器:负责监听 HTTP 请求,将请求转交给 FastAPI 处理
  • 类比:FastAPI 是”厨师”(处理业务逻辑),Uvicorn 是”服务员”(接收订单并传递给厨师)
Uvicorn 的作用
  • 监听端口(默认 8000)
  • 接收 HTTP 请求
  • 将请求转交给 FastAPI 处理
  • 将 FastAPI 的响应返回给客户端
启动命令解析
uvicorn 15_main:app --reload
  • 15_main:Python 文件名(不含 .py)
  • app:FastAPI 实例的变量名
  • --reload:开发模式,代码修改后自动重启(生产环境不要用)
生产环境部署
  • 开发环境:直接使用 uvicorn(简单快速)
  • 生产环境:使用 gunicorn + uvicorn(多进程,更稳定)

代码任务 (90 mins)

1

环境准备

在开始之前,确保你的环境已准备好:
  • Python 环境:需要 Python 3.7+(推荐 3.9+)
  • 虚拟环境:确保虚拟环境已激活(参考 Day 08)
  • 文本编辑器:继续使用 nano 或 vi/vim(参考 Day 01)
# 检查 Python 版本
python3 --version
# 应该输出: Python 3.9.x 或更高版本

# 确保虚拟环境已激活(提示符前有 (.venv))
source .venv/bin/activate
为什么需要两个包?
  • fastapi:Web 框架,定义路由和处理逻辑
  • uvicorn:ASGI 服务器,负责监听端口和处理 HTTP 请求
验证步骤
  1. 检查 Python 版本是否符合要求
  2. 确认虚拟环境已激活
  3. 验证 fastapi 和 uvicorn 安装成功
2

任务 A:编写第一个 API

新建文件 15_main.py,实现第一个 FastAPI 应用。任务分解
  1. 创建 FastAPI 应用实例
  2. 定义根路由(GET /)
  3. 定义带路径参数的路由(GET /items/
#!/usr/bin/env python3
"""
Day 15 - FastAPI 快速入门
演示基础路由、路径参数和查询参数
"""

from fastapi import FastAPI

# ========== 1. 初始化 FastAPI 应用 ==========
# FastAPI 是一个类,需要实例化
# 参数说明:
# - title: API 的标题(会显示在 Swagger 文档中)
# - description: API 的描述(会显示在 Swagger 文档中)
# - version: API 的版本号
app = FastAPI(
    title="My First Ops API",
    description="这是一个用于演示 FastAPI 基础功能的文档",
    version="1.0.0"
)

# ========== 2. 定义根路由 (GET 请求) ==========
# @app.get("/") 是装饰器,表示这是一个 GET 请求的路由
# "/" 是路径,表示根路径
# 访问 http://localhost:8000/ 时触发这个函数
@app.get("/")
def read_root():
    """
    根路由:返回 API 状态信息
    
    返回:
        包含消息和状态的字典
    """
    return {
        "message": "Hello, FastAPI!",
        "status": "running"
    }

# ========== 3. 路径参数示例 ==========
# {item_id} 是路径参数,用花括号包裹
# item_id: int 是类型注解,FastAPI 会自动将 URL 中的字符串转换为整数
# 访问 http://localhost:8000/items/5 时,item_id 的值是 5
@app.get("/items/{item_id}")
def read_item(item_id: int):
    """
    获取单个项目信息
    
    参数:
        item_id: 项目 ID(路径参数)
    
    返回:
        包含项目 ID 和是否为偶数的字典
    """
    return {
        "item_id": item_id,
        "is_even": item_id % 2 == 0  # 判断是否为偶数
    }

# ========== 4. 查询参数示例 ==========
# skip 和 limit 没有在路径中,所以 FastAPI 自动识别为查询参数
# = 0 和 = 2 是默认值,如果请求中没有提供这些参数,使用默认值
# 访问 http://localhost:8000/servers?skip=1&limit=2 时:
#   - skip = 1
#   - limit = 2
# 访问 http://localhost:8000/servers 时:
#   - skip = 0(默认值)
#   - limit = 2(默认值)

# 模拟数据库数据
fake_db = [
    {"name": "Server A", "status": "running"},
    {"name": "Server B", "status": "stopped"},
    {"name": "Server C", "status": "running"},
    {"name": "Server D", "status": "running"},
]

@app.get("/servers")
def list_servers(skip: int = 0, limit: int = 2):
    """
    分页获取服务器列表
    
    参数:
        skip: 跳过多少条记录(默认 0)
        limit: 返回多少条记录(默认 2)
    
    返回:
        服务器列表(字典列表)
    """
    # 使用 Python 切片实现分页
    # fake_db[skip:skip+limit] 表示从 skip 开始,取 limit 条
    return fake_db[skip : skip + limit]
代码解释
  • FastAPI 实例app = FastAPI(...) 创建应用实例
  • 路由装饰器@app.get("/") 定义 GET 路由
  • 路径参数{item_id} 在路径中,item_id: int 自动类型转换
  • 查询参数:函数参数不在路径中,自动识别为查询参数
  • 默认值skip: int = 0 设置默认值,参数可选
运行脚本
# 启动服务器
uvicorn 15_main:app --reload

# 看到以下输出表示成功:
# INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
# INFO:     Started reloader process [xxxxx] using WatchFiles
# INFO:     Started server process [xxxxx]
# INFO:     Waiting for application startup.
# INFO:     Application startup complete.
验证步骤
  1. 启动服务器后,访问 http://localhost:8000/
    • 应该看到:{"message":"Hello, FastAPI!","status":"running"}
  2. 访问 http://localhost:8000/items/5
    • 应该看到:{"item_id":5,"is_even":false}
  3. 访问 http://localhost:8000/items/abc
    • 应该看到错误:{"detail":[{"loc":["path","item_id"],"msg":"value is not a valid integer"...}]}
    • 这说明 FastAPI 自动验证了类型
  4. 访问 http://localhost:8000/servers
    • 应该看到前 2 条记录(默认 limit=2)
  5. 访问 http://localhost:8000/servers?skip=1&limit=2
    • 应该看到从第 2 条开始的 2 条记录
常见错误
  • ModuleNotFoundError: No module named 'fastapi' - FastAPI 未安装,执行 pip install fastapi
  • ModuleNotFoundError: No module named 'uvicorn' - Uvicorn 未安装,执行 pip install uvicorn
  • Address already in use - 端口 8000 被占用,使用 --port 8001 指定其他端口
  • ValueError: invalid literal for int() - 路径参数类型转换失败,检查 URL 中的参数类型
3

任务 B:体验 Swagger UI 自动文档

FastAPI 的亮点:自动生成交互式 API 文档。访问 Swagger UI
  1. 确保服务器正在运行(uvicorn 15_main:app --reload
  2. 打开浏览器,访问:http://localhost:8000/docs
  3. 你会看到一个蓝色的界面,显示所有 API 端点
使用 Swagger UI 测试 API
  1. 点击 /servers 旁边的绿色 GET 按钮
  2. 点击右侧的 Try it out 按钮
  3. 在参数输入框中:
    • skip 输入 1
    • limit 输入 2
  4. 点击蓝色大按钮 Execute
  5. 查看 Response Body,应该能看到 Server BServer C
Swagger UI 的功能
  • 查看所有 API:自动列出所有定义的路由
  • 查看参数说明:显示每个参数的类型、是否必需、默认值
  • 在线测试:可以直接在浏览器中测试 API,无需 Postman
  • 查看响应格式:显示 API 返回的数据结构
其他文档界面
  • Swagger UIhttp://localhost:8000/docs(交互式,推荐)
  • ReDochttp://localhost:8000/redoc(更美观的文档样式)
  • OpenAPI JSONhttp://localhost:8000/openapi.json(机器可读的 API 规范)
为什么 Swagger UI 很重要?
  • 自动生成:不需要手写 API 文档,减少维护成本
  • 实时同步:代码修改后,文档自动更新
  • 交互测试:前端开发者可以直接在文档中测试 API
  • 类型准确:基于代码生成,不会出现文档和代码不一致的问题

拓展任务 (30 mins)

挑战 1:添加更多路由

任务:添加以下路由:
  • GET /health - 返回健康检查信息
  • GET /users/{user_id}/posts/{post_id} - 嵌套路径参数
  • GET /search?q=keyword&page=1 - 搜索接口(多个查询参数)
提示
  • 路径参数用 {变量名} 定义
  • 查询参数直接在函数参数中定义
  • 可以组合使用路径参数和查询参数

挑战 2:理解类型转换

任务:尝试以下 URL,观察 FastAPI 如何处理类型转换:
  • GET /items/123 - 整数
  • GET /items/abc - 非整数(应该报错)
  • GET /items/3.14 - 浮点数(应该报错,因为类型是 int)
思考:FastAPI 如何自动验证和转换类型?

今日产出物

  • 15_main.py - FastAPI 应用主文件
  • 运行中的 API 服务(可通过浏览器访问)

参考代码

查看参考代码

在 GitHub 查看完整的 FastAPI 示例代码

在线运行

使用在线编辑器测试 FastAPI

实际应用场景

FastAPI 在运维中的应用

  • 监控 API:提供服务器监控数据的查询接口
  • 配置管理:通过 API 管理服务器配置
  • 日志查询:提供日志搜索和查询接口
  • 自动化工具:为自动化脚本提供 RESTful API
  • 微服务架构:构建轻量级微服务

RESTful API 设计最佳实践

  • 资源命名:使用名词,如 /users/servers,不要用动词
  • HTTP 方法:GET(查询)、POST(创建)、PUT(更新)、DELETE(删除)
  • 状态码:正确使用 HTTP 状态码(200、201、400、404、500)
  • 版本控制:大型 API 应该使用版本号,如 /v1/users
  • 文档完善:利用 FastAPI 自动生成文档,保持文档和代码同步
与 Day 16 的关联:今天学习的 FastAPI 基础路由,明天会学习如何使用 Pydantic 进行数据验证,让 API 能够自动验证和转换请求数据。

上一周: Python 实战

Day 14 | 第二阶段复盘

下一天: 数据验证

Day 16 | Pydantic 数据验证