{count, plural, other {课程}}
API(应用程序编程接口)是现代架构的基石,因为它使应用可以模块化并解耦。这意味着您可以快速、轻松地构建应用,从而便于维护与更新。
在机器学习中,API 同样至关重要,因为它让不同的应用可以共享数据并协同工作,从而节省时间和精力。用于在 Python 中构建 API 的框架有很多。其中最受欢迎的包括 Django、Flask 和 FastAPI。本文将深入介绍其中的一个框架——FastAPI。
如果您想更深入地学习该主题,推荐课程:使用 FastAPI 将 AI 部署到生产环境。
什么是 API?
API 是 Application Programming Interface 的缩写。API 是一种软件中介,允许两个应用相互通信。当您在手机上使用一个应用时,应用会连接互联网并向服务器发送数据。服务器随后处理数据并将结果发回您的手机。您手机上的应用再对数据进行解释,并以可读的方式呈现给您。
API 就像餐厅的服务员。服务员记录您的点单并传到后厨。厨房做好菜后再交给服务员,服务员随后把菜端给您。
同理,API 会从应用接收请求并发送到服务器。服务器处理请求后将数据返回给应用,应用再解释数据并呈现给用户。

图片来源: https://www.techfunnel.com/wp-content/uploads/2021/07/api.png
如果您想进一步了解机器学习流水线、API 与 MLOps,可参阅我们的机器学习、流水线、部署与 MLOps 教程。
什么是 FastAPI
FastAPI 是一个高性能的 Web 框架,基于标准的 Python 类型提示,用于在 Python 3.7+ 上构建 API。它可帮助开发者快速高效地构建应用。FastAPI 构建于 Starlette Web 服务器之上,集成了许多简化 Web 应用开发的功能,如自动数据校验、错误处理和交互式 API 文档。
本节将分别介绍这些功能。首先,看看 FastAPI 原始文档中提到的关键特性。
- 性能:与 NodeJS 和 Go 语言相当。
- 速度:将开发速度提升 2-3 倍。
- 易用:优秀的编辑器支持,随处可用的补全功能,易学易用。
- 健壮:生产级代码,自动生成交互式文档。
- 基于 OpenAPI:与 OpenAPI 和 JSON Schema 完全兼容。
安装 FastAPI
FastAPI 需要 Python 3.7+。可以通过 pip 安装。您需要安装 FastAPI 和 ASGI 服务器 `uvicorn`。
``
# install fastapi
pip install fastapi
# install uvicorn
pip install uvicorn
``
创建一个简单的 API
我们直接上手创建一个非常简单的玩具 API。我使用 VS Code 来实现,您也可以用任何喜欢的编辑器。
```
from typing import Union
from fastapi import FastAPI
app = FastAPI()
@app.get("")
def read_root():
return {"Hello": "World"}
@app.get("/items/{item_id}")
def read_item(item_id: int, q: Union[str, None] = None):
return {"item_id": item_id, "q": q}
```
(示例摘自官方文档)。感谢 @tiangolo。
现在使用命令行终端,运行以下命令启动该 API:
```
uvicorn main:app –reload
```
`main` 是 Python 文件名,`app` 是保存 FastAPI 类实例的变量名。您可以按需命名。运行上述命令后,终端会显示类似如下的信息:

在浏览器中访问该链接,如果看到显示 `Hello World` 的页面,说明 API 已成功运行。

作者供图
恭喜您构建了第一个 API。
交互式 API 文档
FastAPI 使用 OpenAPI 标准为所有 API 生成一个“模式(schema)”。“模式”是对某物的定义或描述。它不是实现该功能的代码,而是抽象的描述。FastAPI 内置的两种交互式文档系统即由 OpenAPI 模式驱动。
要查看文档,只需在 URL 后添加 `/docs`(`http://127.0.0.1:8000/docs`)。该链接将显示自动生成的交互式 API 文档。

作者供图
点击右上角的 `Try it out` 按钮即可测试 API。

作者供图
您可以看到响应体是一个字典。这是 `main.py` 中定义的 `read_item` 函数的返回结果。还可以看到请求 URL `http://127.0.0.1:8000/items/1?q=orange`,其中 `1` 和 `orange` 是我们传入 API 的输入。
FastAPI 还提供另一种交互式自动文档。要查看,请访问 http://127.0.0.1:8000/redoc`。效果如下:

作者供图
更高级的示例
在构建 API 时,“path(路径)”定义了请求的路由或端点。不过,这里我们还需做一个选择,即“Operation(操作)”。此处的 `operation` 指的是 HTTP 的一种“方法”。通过使用这些所谓的“方法”(可为一种或多种),您可以与 HTTP 协议支持的各个路径进行交互。通常,您会使用:
- POST:创建数据。
- GET:读取数据。
- PUT:更新数据。
- DELETE:删除数据。
- 以及其他一些高级方法
FastAPI 支持所有 HTTP 方法。
FastAPI 建立在 Python 类型提示之上,这也是该框架的另一个关键点。类型提示在 Python 3.6 及更高版本中得到支持。类型提示是一种特殊语法,用于声明变量的类型。
为变量声明类型可以让编辑器和其他工具为您提供更好的辅助。下面来看一个高级示例。
我们将修改 `main.py` 文件,新增一个 `PUT` 请求,它会接收多种不同数据类型的输入。
```
from typing import Union
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
price: float
is_offer: Union[bool, None] = None
@app.get("")
def read_root():
return {"Hello": "World"}
@app.get("/items/{item_id}")
def read_item(item_id: int, q: Union[str, None] = None):
return {"item_id": item_id, "q": q}
@app.put("/items/{item_id}")
def update_item(item_id: int, item: Item):
return {"item_name": item.name, "item_id": item_id}
```
(示例摘自官方文档)。感谢 @tiangolo。
变更说明:
添加了一个 `put` 请求,接收两个输入。`item_id` 是整数,`item` 的类型指向自定义类 `Item`,该类继承自 `pydantic` 的 `BaseModel`。`Item` 类包含三个属性:`name`、`price`、`is_offer`,且它们的数据类型各不相同。
FastAPI 将检查:
- `name` 是否为 `str`。
- `price` 是否为 `float`。
- `is_offer`(如提供)是否为 bool。
使用类型提示的好处在于,您只需用标准 Python(3.6+)在函数参数中一次性声明参数、请求体等的类型。您将获得:
- 编辑器支持,包括自动补全与类型检查
- 数据校验
- 输入数据转换
- 输出数据转换
- 更易理解的错误信息。
FastAPI 与 Django、Flask 的对比
这三者都是 Python Web 框架,可用于开发 Web 应用。它们各有优劣。
Django 是一个全功能框架,自带上手所需的一切,包括内置 ORM 和管理后台。对于初学者可能略显繁琐,但其完善的文档也使其易于学习。
Flask 是一个微框架,轻量且易于上手。它不如 Django 功能齐全,但非常适合简单项目。
FastAPI 是一款较新的框架,旨在快速且易用。它包含自动数据验证与文档等功能。
|
Django |
Flask |
FastAPI |
|
|
社区 |
庞大。 GitHub 星标 66K |
庞大。 GitHub 星标 61K |
庞大。 GitHub 星标 50K |
|
性能 |
Django 体系庞大,性能并非最优。 |
Flask 是微型 Web 框架,性能好于 Django。 |
FastAPI 是最快的 Web 框架之一,原生异步支持进一步提升了效率。 |
|
异步支持 |
支持,但延迟上有一定限制。 |
不支持。 需要 Asyncio |
FastAPI 提供原生异步支持。 |
|
易用性 |
Django 体系庞大,因此学习起来稍显复杂。 |
Flask 易学,使用相当直接。 |
FastAPI 在三者中最为简单。 |
|
交互式文档 |
非交互式 |
无 |
有(OpenAI,Redoc) |
|
数据校验 |
无 |
无 |
有 |
FastAPI 性能基准
根据 techempower 进行的测试结果,FastAPI 在整体性能方面优于其他框架。

来源: https://www.techempower.com/benchmarks/
示例:使用 PyCaret 构建端到端机器学习流水线,并用 FastAPI 部署
本节中,我们将快速搭建一个机器学习流水线,并创建 API 来提供模型服务。我们将使用低代码 Python 库 PyCaret 来构建流水线并创建 API。PyCaret 与 FastAPI 集成,使得将机器学习模型作为 API 创建与服务变得非常容易。
PyCaret
PyCaret 是一个开源的低代码 Python 机器学习库,可自动化机器学习工作流。它是端到端的机器学习与模型管理工具,能成倍加速实验周期,显著提升您的工作效率。
```
pip install pycaret
```
```
import pycaret
pycaret.__version__
>>> 2.3.10
```
本例将使用 `insurance` 数据集。它是一个回归用例,基于年龄、性别、BMI 和地区预测医疗费用。
```
from pycaret.datasets import get_data
data = get_data(‘insurance’)
```

作者供图
接下来我们将初始化 pycaret 的 `setup` 函数。该函数会在 PyCaret 中初始化实验,并基于传入的参数创建转换流水线。
`setup` 必须在其他任何函数之前执行。它需要两个参数:`data` 和 `target`。其余参数均为可选。`setup` 函数负责控制全部的数据预处理流程。关于 PyCaret 支持的所有预处理流程的完整说明,请参阅PyCaret 文档。
```
from pycaret.regression import *
s = setup(data, target = 'charges')
```

作者供图(输出截断)。
完成 setup 后,我们只需一行代码即可开始模型训练与选择:`compare_models`。该函数通过交叉验证训练并评估模型库中所有估计器的性能。其结果是一个评分网格,包含交叉验证得到的平均分数。
```
best = compare_models()
```

作者供图
基于此,表现最佳的模型是 `Gradient Boosting Regressor`。如果需要,我们可以通过可视化来分析模型,并进一步通过超参数调优或模型集成来提升性能,但本教程不展开。
接下来我们直接构建最佳模型的 API,使用 FastAPI 将预测服务部署到生产环境。请记住,PyCaret 集成了 FastAPI,因此可通过 `create_api` 函数从模型自动创建 REST API。
```
create_api (best, 'insurance_prediction_model')
```

现在要运行该 API,请打开命令行终端,定位到 Notebook 所在的文件夹,并运行命令 `python insurance_prediction_model.py`。

前往 `http://127.0.0.1:8000/docs`,您将看到与本教程前面相同的界面。

作者供图

作者供图
您也可以访问 `http://127.0.0.1:8000/redoc` 查看另一种交互式文档。

作者供图
请记住,默认与 redoc 两种交互式文档都是基于 OpenAPI 标准提供支持的。
如果您想查看使用 `create_api` 函数时 PyCaret 创建的文件,您可以在 Notebook 同级文件夹中找到。文件内容如下:
```
import pandas as pd
from pycaret.regression import load_model, predict_model
from fastapi import FastAPI
import uvicorn
# Create the app
app = FastAPI()
# Load trained Pipeline
model = load_model('my_lr_api')
# Define predict function
@app.post('/predict')
def predict(age, sex, bmi, children, smoker, region):
data = pd.DataFrame([[age, sex, bmi, children, smoker, region]])
data.columns = ['age', 'sex', 'bmi', 'children', 'smoker', 'region']
predictions = predict_model(model, data=data)
return {'prediction': list(predictions['Label'])}
if __name__ == '__main__':
uvicorn.run(app, host='127.0.0.1', port=8000)
```
结论
本文讨论了 API 的概念及其使用原因。API 在现代架构中非常重要,因为它让不同的软件程序共享数据与功能,从而可以构建更可靠、且更易维护的复杂系统。
随后我们深入介绍了 Python 中一个相对较新的框架 FastAPI。FastAPI 是一个更易用且高效的 API 框架,是希望快速、轻松创建 API 的开发者的理想之选。

GitHub 星标历史 - 使用 star-history.com 生成
如果您也想学习如何使用 Flask 将 Python 中的机器学习模型快速做成简单 API,请查看这篇易于上手的《将机器学习模型转为 Python API》教程。
FastAPI 常见问题
FastAPI 是异步的吗?
FastAPI 原生支持使用 async/await 关键字编写异步代码。
FastAPI 适合生产环境吗?
FastAPI 完全可用于生产环境,拥有优秀的文档、支持与易用的接口。
FastAPI 与 Flask 有何不同?
FastAPI 支持异步调用。它更轻量、更快,也比 Flask 更易学。Flask 和 FastAPI 都拥有庞大的社区。
FastAPI 是否也有内置的开发服务器?
不,FastAPI 不包含内置开发服务器。对此您需要使用 `uvicorn`。
FastAPI 支持 Python 2 吗?
不。FastAPI 仅支持 Python 3.6+。
FastAPI 只在 Python 中可用吗?
是的。
FastAPI 比 Go 语言更快吗?
不是。根据 techempower,Golang 的 Fiber 在全球 API 性能中排名第 50,FastAPI 排名第 183。
FastAPI 与 Pydantic 兼容吗?
是的,FastAPI 与 Pydantic 完全兼容(且基于它)。