FastAPI 是一个现代、快速(高性能)的 Web 框架,用于构建 API,基于 Python 3.7+ 的标准类型提示。它提供了自动生成交互式文档、数据验证、依赖注入等开箱即用的功能,是构建 RESTful API 的理想选择。

本教程将分两篇深入讲解 FastAPI 的核心知识。第一篇将涵盖 FastAPI 的安装、开发环境配置、第一个应用、自动 API 文档、路由基础、请求与响应处理,以及如何使用 Pydantic 模型进行数据验证和序列化。通过详细的实例,帮助你快速掌握 FastAPI 的基本使用。

1. FastAPI 简介

FastAPI 的主要特点包括:

  • 快速:与 Node.js 和 Go 相当的性能(归功于 Starlette 和 Pydantic)。
  • 快速编码:将开发速度提升约 200% 到 300%。
  • 更少的 Bug:减少约 40% 的人为错误。
  • 直观:强大的编辑器支持,自动补全随处可用。
  • 简单:设计易于使用和学习,减少阅读文档的时间。
  • 简短:代码重复最小化,每个参数声明可以完成多个功能。
  • 健壮:生产可用级别的代码,还有自动生成的交互式文档。
  • 基于标准:完全兼容 API 的开放标准:OpenAPI(以前称为 Swagger)和 JSON Schema。

2. 安装 FastAPI 和 Uvicorn

FastAPI 本身是一个框架,实际运行需要 ASGI 服务器,如 Uvicorn 或 Hypercorn。这里我们使用 Uvicorn。

2.1 安装 FastAPI

pip install fastapi

2.2 安装 ASGI 服务器

pip install uvicorn[standard]

[standard] 会安装一些推荐的额外依赖(如 uvloop 等),以提高性能。

3. 开发环境配置(VSCode 推荐)

虽然任何编辑器都可以编写 FastAPI 应用,但 VSCode 配合 Python 插件可以提供极佳的自动补全和类型检查体验。

  1. 安装 Python 插件(由 Microsoft 提供)。
  2. 打开项目文件夹,创建一个 Python 虚拟环境并激活:
    python -m venv venv
    source venv/bin/activate  # Linux/Mac
    venv\Scripts\activate     # Windows
    
  3. 在 VSCode 中按 Ctrl+Shift+P,选择 “Python: Select Interpreter”,然后选择虚拟环境中的 Python。
  4. 安装上述依赖到虚拟环境中。

现在,一切就绪,可以开始编写第一个 FastAPI 应用了。

4. 第一个 FastAPI 应用

创建一个文件 main.py,写入以下代码:

from fastapi import FastAPI

app = FastAPI()

@app.get("/")
def read_root():
    return {"message": "Hello, FastAPI!"}

4.1 运行应用

在终端执行:

uvicorn main:app --reload
  • main:模块文件名(即 main.py)。
  • app:FastAPI 实例的名称(在 main.py 中创建的 app 对象)。
  • --reload:开发模式下启用,代码修改后自动重启服务器。

看到输出如下,表示启动成功:

INFO:     Uvicorn running on http://127.0.0.1:8000
INFO:     Application startup complete.

4.2 测试 API

打开浏览器访问 http://127.0.0.1:8000/,你将看到 JSON 响应:

{"message": "Hello, FastAPI!"}

恭喜!你已经成功创建并运行了第一个 FastAPI 应用。

5. 交互式 API 文档

FastAPI 自动生成两种交互式 API 文档,无需额外配置。

5.1 Swagger UI

访问 http://127.0.0.1:8000/docs,你会看到一个自动生成的 Swagger UI 界面,列出了所有可用的路径操作(本例中只有 GET /)。你可以直接在界面上测试 API。

5.2 ReDoc

访问 http://127.0.0.1:8000/redoc,可以看到另一种风格的文档,同样由 FastAPI 自动生成。

这些文档不仅美观,而且完全基于 OpenAPI 规范,可以导出为 JSON 或 YAML 文件。

6. 基本路由

FastAPI 通过装饰器定义路由,支持常见的 HTTP 方法:@app.get(), @app.post(), @app.put(), @app.delete() 等。

6.1 路径参数

你可以在路径中使用 Python 格式的字符串参数,FastAPI 会自动将其作为路径参数传递给函数。

@app.get("/items/{item_id}")
def read_item(item_id: int):
    return {"item_id": item_id}
  • item_id 的类型声明为 int,FastAPI 会自动验证并转换为整数。如果传入非整数,将返回一个自动的错误响应。

6.2 查询参数

当你在函数中声明的参数不是路径参数时,它们会自动被解释为查询参数。

fake_db = [{"name": "Foo"}, {"name": "Bar"}, {"name": "Baz"}]

@app.get("/items/")
def list_items(skip: int = 0, limit: int = 10):
    return fake_db[skip : skip + limit]

访问 /items/?skip=1&limit=2 将返回从索引 1 开始的 2 个条目。查询参数支持默认值和可选值(通过 Optional 或默认值 None)。

6.3 路径参数和查询参数混合

@app.get("/items/{item_id}")
def get_item(item_id: int, q: str = None):
    return {"item_id": item_id, "q": q}

这里 item_id 是路径参数,q 是可选查询参数。访问 /items/5?q=test 将返回 {"item_id":5,"q":"test"}

7. 请求和响应

7.1 请求体(Request Body)

当需要接收 JSON 数据(例如 POST、PUT 请求)时,可以使用 Pydantic 模型来声明请求体(将在下一节详细讲解),也可以直接使用 fastapi.Request 对象获取原始请求,但通常推荐使用 Pydantic 模型。

7.2 响应模型

你可以通过 response_model 参数指定响应数据的结构,FastAPI 会自动进行数据过滤、转换和文档生成。

from pydantic import BaseModel

class Item(BaseModel):
    name: str
    price: float

@app.post("/items/", response_model=Item)
def create_item(item: Item):
    # 这里可以保存到数据库等操作
    return item  # 直接返回 item,FastAPI 会按照 Item 模型序列化

7.3 自定义响应状态码

使用 status_code 参数或直接返回 Response 对象。

from fastapi import status

@app.post("/items/", status_code=status.HTTP_201_CREATED)
def create_item(item: Item):
    # ...
    return item

7.4 直接返回 Response 对象

如果你需要完全控制响应,可以直接返回 Response 或其子类,如 JSONResponse, HTMLResponse 等。

from fastapi.responses import JSONResponse

@app.get("/custom")
def custom_response():
    return JSONResponse(content={"message": "custom"}, status_code=200)

8. Pydantic 模型

Pydantic 是 FastAPI 的核心依赖,用于数据验证和设置管理。它利用 Python 类型提示进行运行时数据验证,并提供了强大的序列化和反序列化能力。

8.1 定义模型

创建一个继承自 BaseModel 的类,并声明字段类型。

from pydantic import BaseModel
from typing import Optional

class Item(BaseModel):
    name: str
    description: Optional[str] = None
    price: float
    tax: Optional[float] = None
  • Optional[str] = None 表示该字段可选,默认为 None
  • 如果提供了 tax,则必须为 float,否则可以省略。

8.2 在路径操作中使用模型

作为请求体:

@app.post("/items/")
def create_item(item: Item):
    # item 已经是经过验证的 Item 实例
    return {"item_name": item.name, "item_price": item.price}

作为响应模型:

@app.get("/items/{item_id}", response_model=Item)
def read_item(item_id: int):
    # 假设从数据库获取了 item_data
    item_data = {"name": "Foo", "price": 50.2}
    return item_data  # 字典也会自动转换为 Item 模型

8.3 数据验证

Pydantic 会自动验证传入的数据:

  • 类型不匹配时,返回 422 错误,包含详细的验证信息。
  • 可以使用字段约束,如 Field(..., max_length=10) 或使用 constr, conint 等。
from pydantic import BaseModel, Field

class Item(BaseModel):
    name: str = Field(..., max_length=10)  # ... 表示必填
    price: float = Field(..., gt=0)        # 大于 0

8.4 嵌套模型

Pydantic 模型可以嵌套,非常适合表示复杂的数据结构。

class Image(BaseModel):
    url: str
    name: str

class Item(BaseModel):
    name: str
    price: float
    image: Image   # 嵌套模型
    tags: list[str] = []  # 类型为字符串列表

请求体 JSON 示例:

{
    "name": "Foo",
    "price": 42.0,
    "image": {
        "url": "http://example.com/foo.jpg",
        "name": "Foo Image"
    },
    "tags": ["food", "discount"]
}

8.5 验证错误处理

FastAPI 会自动捕获 Pydantic 的验证错误,并返回一个包含错误详情的 422 响应。你可以在应用中全局处理这些错误,但默认行为已经足够友好。

总结

在第一篇教程中,我们学习了:

  • FastAPI 的安装和开发环境配置。
  • 如何创建第一个 FastAPI 应用并运行。
  • 自动生成的交互式 API 文档。
  • 基本路由:路径参数和查询参数。
  • 请求和响应的基本处理,以及状态码定制。
  • Pydantic 模型的定义、使用和数据验证。

这些是构建任何 FastAPI 应用的基础。在下一篇教程中,我们将深入探讨更高级的主题,包括路径操作依赖项、表单数据、文件上传、中间件、数据库集成以及安全性等内容。敬请期待!

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐