☰
learn-to-cloud 阶段二实战:用 FastAPI 构建并测试你的第一个 API 服务
2026/10/12 3:04:35 网站建设 项目流程
  • 教程
  • 云原生

【免费下载链接】learn-to-cloud

A courseware built on the belief that anyone can learn foundational cloud engineering skills with the right guide and discipline

项目地址:https://gitcode.com/gh_mirrors/le/learn-to-cloud
点击查看免费下载

本篇技术指南围绕 learn-to-cloud 课程体系中 docs/phase2/3-fastapi.md 展开,系统讲解 FastAPI 的核心原理、L2C Journal 应用中的技术选型背景,以及以 pytest + httpx 为核心的 API 测试方法论。读完本文,你将掌握基于 Python 类型提示定义端点、使用 Pydantic 校验请求/响应、借助conftest.py组织测试夹具,并能在真实项目(如课程 Capstone 中的 Journal API)中编写和运行完整测试套件。


FastAPI 是什么:L2C Journal 的 API 技术底座

FastAPI 是一个现代化、高性能(fast)的 Python Web 框架,用于构建 API 服务,它基于 Python 3.6+ 的标准类型提示(type hints)体系工作。与传统的 Web 框架相比,它的核心优势在于:

  • 类型驱动:利用 Python 的 type hints 同时完成数据校验、序列化与 API 文档生成,一份类型定义多处复用;
  • 自动文档:框架内置 Swagger UI 等交互式文档界面,无需额外配置即可看到可调试的 API 页面;
  • 异步友好:原生支持async/await异步代码路径,适合对接 LLM API、数据库等 IO 密集型服务。

在 learn-to-cloud 课程中,FastAPI 是构建L2C Journal 应用(Phase 2 Capstone 的日记/学习日志分析应用)所采用的框架,你后续也将使用它。这门课程预计花费3–4 天完成本主题,核心学习路径是官方 FastAPI 教程,重点目标是"能独立创建一个 FastAPI 应用并定义端点"。

在课程体系中的定位

FastAPI 主题是 Phase 2(编程与 AI 集成)的第 3 个主题,位于 REST API 基础之后、数据库与 GenAI API 之前。从 docs/phase2/README.md 的课程表可以看到完整脉络:

序号主题与本主题的关系
1Python提供 pytest 等测试工具的语言基础
2APIs铺垫 REST 资源、HTTP 方法、状态码等概念
3FastAPI(本主题)用框架落地 REST API,并学会测试
4Databases为 Journal 应用接入持久化存储
5GenAI APIs为 Journal 应用接入 LLM 情感分析与摘要
6Prompt Engineering设计 /analyze 端点使用的提示词

其中 REST API 主题(docs/phase2/2-api.md)要求你理解 GET、POST、PUT、DELETE 的语义以及 200、201、400、404、500 等状态码的含义——这些正是后续 FastAPI 测试中验证的重点对象。Phase 3 与 Phase 4 还会把同一个 Journal API 依次部署到云 VM(docs/phase3/9-deploy-api.md)、容器化并接入 CI/CD 与监控(docs/phase4/6-build-app.md、docs/phase4/5-monitoring.md),因此本主题打下的测试基础会被反复复用。


你需要掌握的 FastAPI 核心能力

课程 Checklist 要求你在进入下一主题前,至少掌握以下六项能力:

1. 创建带基础端点的 FastAPI 应用

一个最小应用通常包含FastAPI()实例、若干路径装饰器和返回 JSON 的响应函数,例如:

from fastapi import FastAPI app = FastAPI() @app.get("/") def read_root(): return {"message": "Hello L2C"}

配合 ASGI 服务器(如 uvicorn)即可本地启动并访问。

2. 路径参数(Path Parameters)与查询参数(Query Parameters)

  • 路径参数:URL 路径中的变量段,如/entries/{entry_id},通过函数参数接收;
  • 查询参数:URL 中?key=value形式,未在路径中声明、带默认值的函数参数即成为查询参数。

两者均可配合类型提示获得自动校验与文档展示。

3. 用 Pydantic 模型校验请求与响应

FastAPI 的数据校验由 Pydantic 完成。定义一个继承BaseModel的类,即可声明请求体结构;FastAPI 会在请求进入时自动校验,非法数据直接返回 422 校验错误,合法数据则转换为对应模型实例。这也是本主题测试部分用pytest.raises(ValidationError)验证的重点。

4. 理解 FastAPI 的自动文档(Swagger UI)

基于类型提示与 Pydantic 模型,FastAPI 自动生成交互式 API 文档。你可以直接在浏览器中查看所有端点、请求/响应结构,并在线发起调用——这是课程 Checklist 中明确要求理解的特性。

5. 依赖注入(Dependency Injection)

通过Depends声明依赖(如共享数据库会话、认证逻辑、测试客户端),可将横切逻辑从端点中抽离,也便于在测试中用覆盖件替换真实依赖。

6. 异步代码支持

FastAPI 原生支持async def端点,课程中的 Capstone 项目正是使用httpx.AsyncClient做异步测试,以获得更好的测试性能。异步能力同样应用于后续对接 LLM API(docs/phase2/5-genai-apis.md 明确将异步支持列为关键概念之一)。


测试 FastAPI 应用:pytest + httpx 实战

本主题的核心实践章节围绕API 测试展开。你在 Python Crash Course 中已经学过 pytest 基础,现在把这些知识迁移到 API 测试场景。在 Phase 2 的 Capstone 项目中,你将运行一套完整的测试套件来验证实现是否正确——这也是后续云部署、CI/CD 流水线的质量闸门。

测试技术栈与关键概念

概念作用
httpx.AsyncClient以异步方式发起 HTTP 请求,测试异步 API 端点,性能更好
conftest.py中的 Fixtures提供共享测试环境:测试客户端、样例数据、数据库清理等
HTTP 方法测试覆盖 GET、POST、PATCH、DELETE 的完整 CRUD 路径
响应断言检查状态码与 JSON 内容是否符合预期
Pydantic 模型验证测试例如用pytest.raises(ValidationError)断言非法输入被拒绝
pytest.skip()跳过尚未实现功能的测试,保持测试套件可先行通过

1. 使用httpx.AsyncClient测试异步端点

httpx是 FastAPI 官方测试教程推荐使用的 HTTP 客户端,其AsyncClient天然适配 FastAPI 的异步特性。典型用法是利用ASGITransport直接驱动应用实例,无需启动真实服务器:

import pytest from httpx import ASGITransport, AsyncClient from main import app @pytest.mark.anyio async def test_read_root(): transport = ASGITransport(app=app) async with AsyncClient(transport=transport, base_url="http://test") as client: response = await client.get("/") assert response.status_code == 200

要点说明:

  • 测试函数标记为异步(async def),配合anyio等插件运行;
  • ASGITransport让请求在进程内直接进入应用,测试既快又无需网络端口;
  • 课程特别强调使用AsyncClient的动机是性能——异步测试可以并发执行多个请求,显著加快大型测试套件的运行。

2. 在conftest.py中组织共享 Fixtures

conftest.py是 pytest 的共享配置与夹具(fixture)文件,放在测试目录根级后,其定义的 fixture 可被该目录下所有测试文件自动使用。课程要求理解并实践三类典型 fixture:

  • 测试客户端:预配置好的AsyncClient,各测试用例直接注入使用,避免重复创建;
  • 样例数据:固定的输入/期望输出,保证断言可重复;
  • 数据库清理:在每个用例前创建、用例后清理数据库状态,隔离测试间数据污染。

一个精简示例:

# conftest.py import pytest from httpx import ASGITransport, AsyncClient from main import app @pytest.fixture async def client(): transport = ASGITransport(app=app) async with AsyncClient(transport=transport, base_url="http://test") as c: yield c # 每个用例结束后自动关闭 @pytest.fixture def sample_entry(): return {"title": "My first endpoint", "content": "Learned FastAPI today"}

3. 测试不同 HTTP 方法与响应断言

Journal API 的完整 CRUD 对应四种方法:创建用 POST、读取用 GET、局部更新用 PATCH、删除用 DELETE。测试时不仅调用方法,更要断言两件事:状态码是否符合语义(200/201/204 等成功码,400/404/422 等错误码),以及JSON 内容是否包含预期字段与取值。

async def test_create_entry(client, sample_entry): response = await client.post("/entries", json=sample_entry) assert response.status_code == 201 data = response.json() assert data["title"] == sample_entry["title"] async def test_get_entry(client): response = await client.get("/entries/1") assert response.status_code == 200 assert "content" in response.json()

4. 测试 Pydantic 模型验证

Pydantic 校验逻辑本身也是可测试的。对非法数据(缺失必填字段、类型错误、超出约束的值),可以直接断言模型抛ValidationError:

import pytest from pydantic import ValidationError from models import JournalEntry def test_invalid_entry_rejected(): with pytest.raises(ValidationError): JournalEntry(title="", content="") # 例如空字符串违反约束

这确保 API 的输入防线在端点层面之外依然成立,也是课程 AI 测验题"如何测试 Pydantic 模型对非法数据抛出 ValidationError"的标准答案。

5. 用pytest.skip()处理未实现功能

在 Capstone 开发过程中,功能往往分阶段完成。对尚未实现的端点,可用pytest.skip()让测试优雅跳过而不是报错,保持测试套件整体可运行、可增量推进:

def test_analyze_endpoint(): pytest.skip("AI analysis endpoint not implemented yet")

运行测试

在 Capstone 项目中,运行全部测试:

pytest

运行指定测试文件:

pytest tests/test_api.py pytest tests/test_models.py

pytest默认递归收集test_*.py/*_test.py文件,并自动加载conftest.py中的夹具配置。课程建议把 API 测试与模型测试拆分到不同文件(如tests/test_api.py、tests/test_models.py),便于单独运行与定位失败。


测试 Journal API 的 AI 分析端点

Phase 2 Capstone 的核心功能之一是/analyze端点:把日记文本发送给 LLM,返回情感倾向(positive/negative/neutral)与两句摘要。这在 docs/phase2/5-genai-apis.md 与 docs/phase2/6-prompt-engineering.md 中有完整的提示词设计范式(结构化 JSON 输出、temperature 控制、few-shot 示例等)。

针对该端点的测试策略要点:

  • Mock 外部 LLM 调用:真实 LLM API 按量计费且结果不确定,测试中应使用 fixture 替换(monkeypatch)LLM 客户端,返回固定 JSON,从而断言端点正确转发与解析;
  • 验证结构化输出:LLM 返回的sentiment/summary必须经 Pydantic 模型校验后返回给前端,非法输出应触发ValidationError路径;
  • 环境变量注入:LLM API Key 通过环境变量注入(docs/phase2/5-genai-apis.md 明确要求"绝不把密钥提交进 git"),测试 fixture 可注入临时假 Key。

这样的测试不仅覆盖业务逻辑,也为 Phase 4 的监控埋下伏笔——docs/phase4/5-monitoring.md 要求用prometheus_client对 FastAPI 应用插桩,跟踪/analyze端点的延迟、错误率与 token 用量。


从测试到生产:测试套件的后续价值

本主题的测试能力将在课程后续阶段反复被调用:

  • Phase 3 部署验证:云部署 Capstone(docs/phase3/9-deploy-api.md)的成功标准之一就是"所有 CRUD 操作经由 API 端点正常工作"——本主题的测试套件正是这一验收的自动化手段;
  • Phase 4 CI/CD:DevOps Capstone(docs/phase4/6-build-app.md)要求"每次提交时构建并测试应用",pytest测试套件会接入流水线,作为镜像构建与部署的前置检查;
  • Phase 4 容器化:同一 Capstone 要求将 Journal API 容器化(Dockerfile),本地先构建并运行容器验证功能——验证手段同样依赖本主题的测试。

换言之,现在写下的每一个断言,都是未来云上生产环境的验收标准。


AI 助手测验:用提示词检验你的掌握程度

完成学习后,可以用下面的提示词让 AI 助手对你进行提问与考察(覆盖本主题全部核心概念):

  1. 你能请我解释一下什么是 FastAPI 以及它是如何工作的吗?
  2. 你能考考我如何创建一个 FastAPI 应用并定义端点吗?
  3. 你能请我解释如何在 FastAPI 中处理请求和响应模型吗?
  4. 你能请我解释如何在 FastAPI 中使用路径参数和查询参数吗?
  5. 你能考考我如何在 FastAPI 中使用依赖注入吗?
  6. 你能请我解释如何在 FastAPI 中使用 Pydantic 模型吗?
  7. 你能请我解释如何在 FastAPI 中使用异步代码吗?
  8. 你能考考我 pytest fixtures 是如何工作的、conftest.py是做什么的吗?
  9. 你能请我说明如何测试 Pydantic 模型对非法数据抛出ValidationError吗?

建议让 AI 一次只问一题、在你答错时引导而非直接给答案,模拟真实面试场景。


主题完成清单

进入下一主题前,请逐项确认你都能回答"是":

  • 我能创建一个带基础端点的 FastAPI 应用
  • 我理解路径参数与查询参数
  • 我能使用 Pydantic 模型校验请求与响应
  • 我理解 FastAPI 的自动文档(Swagger UI)
  • 我理解 pytest fixtures 与conftest.py的用法
  • 我能用pytest运行测试并解读结果

继续前进

本主题属于 Phase 2(编程与 AI 集成)的第 3 步。完成 FastAPI 构建与测试后,接下来将进入数据库主题为 Journal 应用接入持久化存储,随后是 GenAI API 集成与提示词工程,最终完成带 AI 分析的 Journal Capstone。整阶段目标与进度可对照 Phase 2 总览查看。

  • 教程
  • 云原生

【免费下载链接】learn-to-cloud

A courseware built on the belief that anyone can learn foundational cloud engineering skills with the right guide and discipline

项目地址:https://gitcode.com/gh_mirrors/le/learn-to-cloud
点击查看免费下载
上一篇:如何使用App Privacy Policy Generator快速创建合规隐私政策
下一篇:cursor-vip高级功能探索:自定义模型集成与扩展开发终极指南

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询