使用适用于 Python 的 FastAPI 构建应用程序

已发表: 2022-11-29

FastAPI 是一种快速且轻量级的 Web 框架,用于使用 Python 3.6 及更高版本构建现代应用程序编程接口。 在本教程中,我们将介绍使用 FastAPI 构建应用程序的基础知识,您将了解为什么它被提名为 2021 年最佳开源框架之一。

一旦您准备好开发您自己的 FastAPI 应用程序,您将无需寻找很远的地方来托管它们。 Kinsta 的应用程序托管和数据库托管服务提供了一个强大的 Python 平台即服务。

让我们先学习基础知识。


FastAPI的优势

下面是 FastAPI 框架给项目带来的一些优势。

  • 速度:顾名思义,FastAPI 是一个非常快速的框架。 它的速度可与 Go 和 Node.js 相媲美,后者通常被认为是构建 API 的最快选项之一。
  • 易于学习和编码: FastAPI 已经知道了制作可用于生产的 API 所需的几乎所有内容。 作为使用 FastAPI 的开发人员,您不需要从头开始编写所有代码。 只需几行代码,您就可以准备好部署的 RESTful API。
  • 全面的文档: FastAPI 使用 OpenAPI 文档标准,因此可以动态生成文档。 本文档提供了有关 FastAPI 的端点、响应、参数和返回代码的详细信息。
  • 错误更少的 API: FastAPI 支持自定义数据验证,这允许开发人员构建错误更少的 API。 FastAPI 的开发人员吹嘘该框架导致更少的人为错误——减少多达 40%。
  • 类型提示: types 模块是在 Python 3.5 中引入的。 这使您能够声明变量的type 。 当声明变量的类型时,IDE 能够提供更好的支持并更准确地预测错误。
考虑将 FastAPI 用于您的下一个项目? 在本指南中查看其优势: 点击推文

如何开始使用 FastAPI

要按照本教程开始使用 FastAPI,您需要先做几件事。

确保您拥有程序员的文本编辑器/IDE,例如 Visual Studio Code。 其他选项包括 Sublime Text 和 Espresso。

让您的 Python 应用程序及其实例在虚拟环境中运行是一种常见的做法。 虚拟环境允许不同的包集和配置同时运行,并避免因包版本不兼容而导致的冲突。

要创建虚拟环境,请打开终端并运行以下命令:

 $ python3 -m venv env

您还需要激活虚拟环境。 执行此操作的命令将根据您使用的操作系统和 shell 而有所不同。 以下是许多环境的一些 CLI 激活示例:

 # On Unix or MacOS (bash shell): /path/to/venv/bin/activate # On Unix or MacOS (csh shell): /path/to/venv/bin/activate.csh # On Unix or MacOS (fish shell): /path/to/venv/bin/activate.fish # On Windows (command prompt): \path\to\venv\Scripts\activate.bat # On Windows (PowerShell): \path\to\venv\Scripts\Activate.ps1

(一些支持 Python 的 IDE 也可以配置为激活当前的虚拟环境。)

现在,安装 FastAPI:

 $ pip3 install fastapi

FastAPI 是一个用于构建 API 的框架,但要测试您的 API,您需要一个本地 Web 服务器。 Uvicorn 是一个闪电般快速的异步服务器网关接口 (ASGI) Web 服务器,适用于 Python,非常适合开发。 要安装 Uvicorn,请运行以下命令:

 $ pip3 install "uvicorn[standard]"

安装成功后,在项目的工作目录中创建一个名为main.py的文件。 该文件将成为您的应用程序入口点。

IDE 中 FastAPI 项目的布局。
IDE 中基本 FastAPI 项目的视图。

一个快速的 FastAPI 示例

您将通过快速设置示例端点来测试您的 FastAPI 安装。 在您的main.py文件中,粘贴以下代码,然后保存文件:

 # main.py from fastapi import FastAPI app = FastAPI() @app.get("/") async def root(): return {"greeting":"Hello world"}

上面的代码片段创建了一个基本的 FastAPI 端点。 下面是每一行的作用的总结:

  • from fastapi import FastAPI :API 的功能由 FastAPI Python 类提供。
  • app = FastAPI() :这将创建一个 FastAPI 实例。
  • @app.get("/") :这是一个 python 装饰器,它向 FastAPI 指定它下面的函数负责请求处理。
  • @app.get("/") :这是一个指定路由的装饰器。 这会在站点的路由上创建一个GET方法。 然后结果由包装函数返回。
  • 其他可能用于通信的操作包括@app.post()@app.put()@app.delete()@app.options()@app.head()@app.patch() , 和@app.trace()

在文件目录中,在终端中运行以下命令以启动 API 服务器:

 $ uvicorn main:app --reload

在此命令中, main是您的模块的名称。 app对象是您的应用程序的一个实例,并被导入到 ASGI 服务器中。 --reload标志告诉服务器在您进行任何更改时自动重新加载。

你应该在你的终端看到类似这样的东西:

 $ uvicorn main:app --reload INFO: Will watch for changes in these directories: ['D:\\WEB DEV\\Eunit\\Tests\\fast-api'] INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) INFO: Started reloader process [26888] using WatchFiles INFO: Started server process [14956] INFO: Waiting for application startup. INFO: Application startup complete.

在您的浏览器中,导航到http://localhost:8000以确认您的 API 正在运行。 您应该在页面上看到“Hello”:“World”作为 JSON 对象。 这说明使用 FastAPI 创建 API 是多么容易。 您所要做的就是定义一个路由并返回您的 Python 字典,如上面代码片段的第六行所示。

在 Web 浏览器中运行的 FastAPI Hello World 应用程序。
Web 浏览器中的 FastAPI Hello World 应用程序。

使用类型提示

如果您使用 Python,您习惯于使用基本数据类型(例如intstrfloatbool )来注释变量。 然而,从 Python 3.9 版本开始,引入了高级数据结构。 这使您可以使用数据结构,例如dictionariestupleslists 。 借助 FastAPI 的类型提示,您可以使用 pydantic 模型构建数据模式,然后使用 pydantic 模型进行类型提示并从提供的数据验证中受益。

在下面的示例中,使用简单的餐费计算器calculate_meal_fee演示了 Python 中类型提示的使用:

 def calculate_meal_fee(beef_price: int, meal_price: int) -> int: total_price: int = beef_price + meal_price return total_price print("Calculated meal fee", calculate_meal_fee(75, 19))

请注意,类型提示不会改变代码的运行方式。

FastAPI 交互式 API 文档

FastAPI 使用 Swagger UI 提供自动交互式 API 文档。 要访问它,请导航至http://localhost:8000/docs ,您将看到一个包含所有端点、方法和模式的屏幕。

用于文档的 Swagger UI 界面的屏幕截图。
Swagger UI 的 FastAPI 文档。

这种基于浏览器的自动 API 文档由 FastAPI 提供,您无需执行任何其他操作即可利用它。

另一种基于浏览器的 API 文档,也是由 FastAPI 提供的,是 Redoc。 要访问 Redoc,请导航至http://localhost:8000/redoc ,您将在其中看到端点列表、方法及其各自的响应。

用于文档的 Redoc 界面的屏幕截图。
Redoc 的 FastAPI 文档。

在 FastAPI 中设置路由

@app装饰器允许您指定路由的方法,例如@app.get@app.post ,并支持GETPOSTPUTDELETE ,以及不太常见的选项HEADPATCHTRACE

使用 FastAPI 构建您的应用程序

在本教程中,您将逐步使用 FastAPI 构建 CRUD 应用程序。 该应用程序将能够:

  • 创建用户
  • 读取用户的数据库记录
  • 更新现有用户
  • 删除特定用户

要执行这些 CRUD 操作,您将创建公开 API 端点的方法。 结果将是一个可以存储用户列表的内存数据库。

CRUD 示例的数据库表结构图。
CRUD 示例的数据库表结构。

您将使用 pydantic 库通过 Python 类型注释执行数据验证和设置管理。 出于本教程的目的,您将数据的形状声明为具有属性的类。

本教程将使用内存数据库。 这是为了让您快速开始使用 FastAPI 构建 API。 但是,对于生产,您可以使用您选择的任何数据库,例如 PostgreSQL、MySQL、SQLite,甚至 Oracle。

构建应用程序

您将从创建用户模型开始。 用户模型将具有以下属性:

  • id :通用唯一标识符 (UUID)
  • first_name :用户的名字
  • last_name :用户的姓氏
  • gender : 用户的性别
  • roles ,这是一个包含adminuser角色的列表

首先在您的工作目录中创建一个名为models.py的新文件,然后将以下代码粘贴到models.py中以创建您的模型:

 # models.py from typing import List, Optional from uuid import UUID, uuid4 from pydantic import BaseModel from enum import Enum from pydantic import BaseModel class Gender(str, Enum): male = "male" female = "female" class Role(str, Enum): admin = "admin" user = "user" class User(BaseModel): id: Optional[UUID] = uuid4() first_name: str last_name: str gender: Gender roles: List[Role]

在上面的代码中:

  • 您的User类扩展BaseModel ,然后从pydantic导入。
  • 如上所述,您定义了用户的属性。

下一步是创建数据库。 用以下代码替换main.py文件的内容:

 # main.py from typing import List from uuid import uuid4 from fastapi import FastAPI from models import Gender, Role, User app = FastAPI() db: List[User] = [ User( id=uuid4(), first_name="John", last_name="Doe", gender=Gender.male, roles=[Role.user], ), User( id=uuid4(), first_name="Jane", last_name="Doe", gender=Gender.female, roles=[Role.user], ), User( id=uuid4(), first_name="James", last_name="Gabriel", gender=Gender.male, roles=[Role.user], ), User( id=uuid4(), first_name="Eunit", last_name="Eunit", gender=Gender.male, roles=[Role.admin, Role.user], ), ]

main.py 中

  • 您使用List类型初始化了db ,并传入了User模型
  • 您创建了一个包含四个用户的内存数据库,每个用户都具有first_namelast_namegenderroles等必需属性。 用户Eunit被分配了adminuser角色,而其他三个用户仅被分配了user角色。

读取数据库记录

您已成功设置内存数据库并用用户填充它,因此下一步是设置一个将返回所有用户列表的端点。 这就是 FastAPI 的用武之地。

在您的main.py文件中,将以下代码粘贴到您的Hello World端点下方:

为停机和 WordPress 问题苦苦挣扎? Kinsta 是旨在节省您时间的托管解决方案! 查看我们的功能
# main.py @app.get("/api/v1/users") async def get_users(): return db

此代码定义了端点/api/v1/users ,并创建了一个异步函数get_users ,它返回数据库db的所有内容。

保存您的文件,然后您可以测试您的用户端点。 在终端中运行以下命令以启动 API 服务器:

 $ uvicorn main:app --reload

在您的浏览器中,导航到http://localhost:8000/api/v1/users 。 这应该返回所有用户的列表,如下所示:

FastAPI GET 请求返回的用户数据截图。
FastAPI 数据库读取请求检索到的用户数据。

在此阶段,您的main.py文件将如下所示:

 # main.py from typing import List from uuid import uuid4 from fastapi import FastAPI from models import Gender, Role, User app = FastAPI() db: List[User] = [ User( id=uuid4(), first_name="John", last_name="Doe", gender=Gender.male, roles=[Role.user], ), User( id=uuid4(), first_name="Jane", last_name="Doe", gender=Gender.female, roles=[Role.user], ), User( id=uuid4(), first_name="James", last_name="Gabriel", gender=Gender.male, roles=[Role.user], ), User( id=uuid4(), first_name="Eunit", last_name="Eunit", gender=Gender.male, roles=[Role.admin, Role.user], ), ] @app.get("/") async def root(): return {"Hello": "World",} @app.get("/api/v1/users") async def get_users(): return db

创建数据库记录

下一步是创建端点以在数据库中创建新用户。 将以下代码片段粘贴到您的main.py文件中:

 # main.py @app.post("/api/v1/users") async def create_user(user: User): db.append(user) return {"id": user.id}

在此代码段中,您定义了端点以提交新用户并使用@app.post装饰器创建了POST方法。

您还创建了函数create_user ,它接受user模型的User ,并将新创建的user追加(添加)到数据库db 。 最后,端点返回新创建的用户id的 JSON 对象。

您将必须使用 FastAPI 提供的自动 API 文档来测试您的端点,如上所示。 这是因为您无法使用网络浏览器发出发布请求。 导航到http://localhost:8000/docs以使用 SwaggerUI 提供的文档进行测试。

显示 FastAPI POST 请求参数的屏幕截图。
FastAPI POST 请求的参数。

删除数据库记录

由于您正在构建一个 CRUD 应用程序,因此您的应用程序将需要能够删除指定的资源。 在本教程中,您将创建一个端点来删除用户。

将以下代码粘贴到您的main.py文件中:

 # main.py from uuid import UUID from fastapi HTTPException @app.delete("/api/v1/users/{id}") async def delete_user(id: UUID): for user in db: if user.id == id: db.remove(user) return raise HTTPException( status_code=404, detail=f"Delete user failed, id {id} not found." )

以下是该代码如何工作的逐行细分:

  • @app.delete("/api/v1/users/{id}") :您使用@app.delete()装饰器创建了删除端点。 路径仍然是/api/v1/users/{id} ,但随后它会检索id ,这是一个与用户 ID 对应的路径变量。
  • async def delete_user(id: UUID): :创建delete_user函数,它从 URL 中检索id
  • for user in db:这告诉应用程序遍历数据库中的用户,并检查传递的id是否与数据库中的用户匹配。
  • db.remove(user) :如果id匹配到一个用户,则删除该用户; 否则,将引发状态代码为 404 的HTTPException
显示 FastAPI DELETE 请求参数的屏幕截图。
FastAPI DELETE 请求的参数。

更新数据库记录

您将创建一个端点来更新用户的详细信息。 可以更新的详细信息包括以下参数: first_namelast_nameroles

在您的models.py文件中,将以下代码粘贴到您的User模型下,即在User(BaseModel):类之后:

 # models.py class UpdateUser(BaseModel): first_name: Optional[str] last_name: Optional[str] roles: Optional[List[Role]]

在此片段中,类UpdateUser扩展BaseModel 。 然后将可更新的用户参数(例如first_namelast_nameroles )设置为可选。

现在您将创建一个端点来更新特定用户的详细信息。 在您的main.py文件中,将以下代码粘贴到@app.delete装饰器之后:

 # main.py @app.put("/api/v1/users/{id}") async def update_user(user_update: UpdateUser, id: UUID): for user in db: if user.id == id: if user_update.first_name is not None: user.first_name = user_update.first_name if user_update.last_name is not None: user.last_name = user_update.last_name if user_update.roles is not None: user.roles = user_update.roles return user.id raise HTTPException(status_code=404, detail=f"Could not find user with id: {id}")

在上面的代码中,您完成了以下操作:

  • 创建@app.put("/api/v1/users/{id}") ,更新端点。 它有一个可变参数id ,对应于用户的id。
  • 创建了一个名为update_user的方法,它接受UpdateUser类和id
  • 使用for循环检查与传递的id关联的用户是否在数据库中。
  • 检查用户的任何参数is not None (非空)。 如果任何参数(例如first_namelast_nameroles )不为空,则更新它。
  • 如果操作成功,则返回用户 ID。
  • 如果找不到用户,则会引发状态代码为 404 的HTTPException异常和一条消息Could not find user with id: {id}

要测试此端点,请确保您的 Uvicorn 服务器正在运行。 如果它没有运行,请输入以下命令:

 uvicorn main:app --reload

下面是测试的截图。

显示更新请求参数的屏幕截图。
FastAPI 更新请求的参数。

了解 FastAPI 如何将人为引起的错误减少高达 40% 从这里开始: 点击推

概括

在本教程中,您了解了适用于 Python 的 FastAPI 框架,并亲眼目睹了启动和运行 FastAPI 支持的应用程序的速度有多快。 您学习了如何使用该框架构建 CRUD API 端点——创建、读取、更新和删除数据库记录。

现在,如果您想将 Web 应用程序开发提升到一个新的水平,请务必查看 Kinsta 的应用程序托管和数据库托管平台。 与 FastAPI 一样,它非常简单。