FastAPI教程:快速构建高性能Python API – wiki基地

FastAPI教程:快速构建高性能Python API

在现代Web开发中,构建高性能、易于维护的API是核心需求。Python生态系统中有多种Web框架可供选择,但 FastAPI 以其卓越的性能、现代化的特性和出色的开发者体验脱颖而出。本文将详细介绍FastAPI,并指导您如何快速构建高性能的Python API。

1. 什么是FastAPI?

FastAPI 是一个用于构建 API 的现代、快速(高性能)的 Web 框架,使用 Python 3.7+ 版本,基于标准的 Python 类型提示。它的设计哲学是“尽可能地快地开发生产就绪的 API,并且尽可能地快地运行”。

核心优势:

  • 极高的性能:与Starlette(Web部分)和Pydantic(数据部分)紧密集成,拥有与NodeJS和Go语言媲美的性能。
  • 快速编码:显著提升开发速度,减少至少20%的开发时间。
  • 更少的Bug:类型提示和数据验证减少了人为错误。
  • 直观易用:出色的编辑器支持,代码补全,更少的调试时间。
  • 健壮性:自动生成交互式API文档(Swagger UI / ReDoc),支持数据验证、序列化、安全性(OAuth2,JWT等)。
  • 标准化:完全兼容并基于 OpenAPI (以前的 Swagger) 和 JSON Schema 等开放标准。

2. 核心特性解析

FastAPI 的强大功能来源于其对几个关键库和标准的深度整合:

  • Starlette:轻量级的ASGI框架,FastAPI 的Web部分基于它提供高性能的路由、中间件、会话等功能。
  • Pydantic:数据验证和设置管理库。FastAPI 使用Pydantic模型进行请求数据验证、响应数据序列化,并自动生成 JSON Schema。
  • Type Hinting (类型提示):Python 3.5+ 引入的特性,FastAPI 大量利用类型提示来定义数据结构和函数参数,从而实现自动数据验证、序列化和文档生成。
  • OpenAPI (Swagger):一个API描述规范。FastAPI 自动根据您的代码生成符合 OpenAPI 规范的 JSON Schema,并提供开箱即用的交互式API文档(Swagger UI 和 ReDoc)。

3. 环境准备与安装

开始之前,请确保您的 Python 版本为 3.7 或更高。

“`bash

创建并激活虚拟环境 (推荐)

python -m venv .venv
source .venv/bin/activate # macOS/Linux

.venv\Scripts\activate # Windows

安装 FastAPI 和 Uvicorn (ASGI 服务器)

pip install fastapi “uvicorn[standard]”
“`

uvicorn 是一个快速的 ASGI 服务器,FastAPI 应用需要它来运行。[standard] 会安装一些额外的依赖,提供更丰富的功能。

4. 你的第一个FastAPI应用

让我们创建一个简单的“Hello World”API:

创建一个名为 main.py 的文件:

“`python
from fastapi import FastAPI

创建 FastAPI 应用实例

app = FastAPI()

定义一个根路径的GET请求处理器

@app.get(“/”)
async def read_root():
return {“message”: “Hello, World!”}

定义另一个路径的GET请求处理器

@app.get(“/items/{item_id}”)
async def read_item(item_id: int, q: str = None):
“””
通过 item_id 获取一个物品。
可选参数 q 用于过滤。
“””
if q:
return {“item_id”: item_id, “q”: q, “message”: f”Fetching item {item_id} with query {q}”}
return {“item_id”: item_id, “message”: f”Fetching item {item_id}”}
“`

运行应用:

在命令行中,进入 main.py 所在的目录,然后运行:

bash
uvicorn main:app --reload

  • main: 指的是 main.py 文件。
  • app: 指的是 main.py 文件中创建的 FastAPI() 实例对象。
  • --reload: 当代码修改时,自动重新加载服务器(开发模式下非常有用)。

现在,打开浏览器访问 http://127.0.0.1:8000,您应该会看到 {"message": "Hello, World!"}
访问 http://127.0.0.1:8000/items/5,您会看到 {"item_id": 5, "message": "Fetching item 5"}
访问 http://127.0.0.1:8000/items/5?q=somequery,您会看到 {"item_id": 5, "q": "somequery", "message": "Fetching item 5 with query somequery"}

交互式API文档:

FastAPI 自动为您生成了交互式文档。
访问 http://127.0.0.1:8000/docs 可以看到 Swagger UI 界面。
访问 http://127.0.0.1:8000/redoc 可以看到 ReDoc 界面。

您可以在这些页面中测试您的API端点,查看请求和响应模型。

5. 路径参数与查询参数

在上面的例子中,我们已经看到了如何使用路径参数和查询参数。

  • 路径参数 (Path Parameters):用于识别资源中的特定项。它们是URL路径的一部分,例如 /items/{item_id}。FastAPI 会自动根据类型提示进行验证。
    python
    @app.get("/items/{item_id}")
    async def read_item(item_id: int): # item_id 被自动转换为 int 类型
    return {"item_id": item_id}

    如果传入的 item_id 不是整数,FastAPI 会自动返回一个验证错误。

  • 查询参数 (Query Parameters):用于筛选、排序或提供可选信息。它们出现在URL的 ? 之后,例如 ?q=somequery
    python
    @app.get("/items/{item_id}")
    async def read_item(item_id: int, q: str = None, skip: int = 0, limit: int = 10):
    # q: 带有默认值 None,表示可选的字符串查询参数
    # skip: 带有默认值 0,表示可选的整数查询参数
    # limit: 带有默认值 10,表示可选的整数查询参数
    return {"item_id": item_id, "q": q, "skip": skip, "limit": limit}

    所有带有默认值的函数参数都会被视为查询参数。没有默认值的函数参数(且不是路径参数)会被视为必填的查询参数。

6. 请求体 (Request Body)

对于 POSTPUT 等请求,数据通常包含在请求体中。FastAPI 使用 Pydantic 模型来定义请求体的结构和验证规则。

首先,导入 BaseModel 并定义一个 Pydantic 模型:

“`python
from typing import Optional
from pydantic import BaseModel

class Item(BaseModel):
name: str
description: Optional[str] = None
price: float
tax: Optional[float] = None
“`

然后,在您的路径操作函数中将其声明为参数:

“`python
from fastapi import FastAPI
from pydantic import BaseModel
from typing import Optional

app = FastAPI()

class Item(BaseModel):
name: str
description: Optional[str] = None
price: float
tax: Optional[float] = None

@app.post(“/items/”)
async def create_item(item: Item):
“””
创建一个新物品。
“””
item_dict = item.dict() # 将 Pydantic 模型转换为字典
if item.tax:
price_with_tax = item.price + item.tax
item_dict.update({“price_with_tax”: price_with_tax})
return item_dict
“`

当您向 /items/ 发送 POST 请求时,FastAPI 会:
1. 读取请求体。
2. 将请求体解析为 JSON。
3. 根据 Item 模型验证数据。
4. 将验证后的数据作为 Item 类型的对象传递给 create_item 函数。

如果请求体不符合 Item 模型的定义(例如,缺少 nameprice,或类型不匹配),FastAPI 会自动返回一个清晰的验证错误。

7. 数据验证与错误处理

FastAPI 最大的亮点之一是其内置的强大数据验证。所有路径参数、查询参数和请求体都通过 Pydantic 进行验证。

  • 自动验证:当接收到请求时,FastAPI 会自动检查数据类型、必填字段等。
  • 详细错误信息:如果验证失败,FastAPI 会返回标准的 HTTP 422 Unprocessable Entity 响应,其中包含详细的 JSON 错误信息,指出哪个字段出了问题以及原因。这极大地简化了客户端开发。
  • 自定义验证:Pydantic 允许您在模型中添加自定义验证器,以实现更复杂的业务规则。

8. 依赖注入系统 (Dependency Injection)

FastAPI 拥有一个非常强大且易于使用的依赖注入系统。它允许您在路径操作函数中声明“依赖项”(可以是函数、类或其他可调用对象),FastAPI 会负责解析并提供这些依赖项。

这对于以下场景非常有用:

  • 数据库连接:每个请求获取一个数据库会话。
  • 身份验证:检查用户是否已登录,并获取当前用户信息。
  • 权限管理:验证用户是否有权执行某个操作。
  • 共享逻辑:在多个路径操作之间重用代码。

“`python
from fastapi import FastAPI, Depends, HTTPException, status

app = FastAPI()

async def get_current_user(token: str = “some_fixed_token”): # 简化示例
if token != “some_fixed_token”:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail=”Invalid authentication credentials”,
headers={“WWW-Authenticate”: “Bearer”},
)
return {“username”: “fastapi_user”, “email”: “[email protected]”}

@app.get(“/users/me/”)
async def read_users_me(current_user: dict = Depends(get_current_user)):
return current_user
“`

Depends(get_current_user) 会在 read_users_me 执行前先调用 get_current_user 函数,并将其返回值注入到 current_user 参数中。

9. 异步操作 (async/await)

FastAPI 完全支持 Python 的异步特性 (asyncawait)。这意味着您可以编写高效的异步代码,在等待 I/O 操作(如数据库查询、外部 API 调用)时,服务器可以处理其他请求,从而提高吞吐量。

在上面的示例中,我们已经使用了 async def 来定义路径操作函数。当您的路径操作函数涉及到 await 一个耗时的 I/O 操作时,应该使用 async def。如果您的函数只是进行 CPU 密集型计算,没有 await 操作,那么使用 def 即可,FastAPI 会将其放在单独的线程池中运行,避免阻塞主事件循环。

10. 总结

FastAPI 是一款极具潜力的现代化 Python Web 框架,它将高性能、高生产力、健壮性和良好的开发者体验完美结合。通过充分利用 Python 类型提示、Pydantic 的数据验证能力以及 OpenAPI 的文档生成,FastAPI 使得构建高性能、易于维护的 API 变得前所未有的简单。无论您是开发小型微服务还是复杂的企业级应用,FastAPI 都是一个值得考虑的优秀选择。

现在,您已经掌握了 FastAPI 的基本概念和核心用法,可以开始着手构建您自己的高性能 Python API 了!

滚动至顶部