- 评价
- Typer,命令行中的 FastAPI
- 依赖
- 安装
- 示例
- 创建
- 运行
- 检查
- 交互式 API 文档
- 可选的 API 文档
- 示例升级
- 性能
- 可选依赖
- 许可协议
FastAPI 框架,高性能,易于学习,高效编码,生产可用
%20%20%20%20
%20%20%20%20
%20%20%20%20
文档:%20https://fastapi.tiangolo.com
源码:%20https://github.com/tiangolo/fastapi
FastAPI%20是一个用于构建%20API%20的现代、快速(高性能)的%20web%20框架,使用%20Python%20并基于标准的%20Python%20类型提示。
关键特性:
快速:可与%20NodeJS%20和%20Go%20并肩的极高性能(归功于%20Starlette%20和%20Pydantic)。最快的%20Python%20web%20框架之一。
高效编码:提高功能开发速度约%20200%%20至%20300%。*
- 更少%20bug:减少约%2040%%20的人为(开发者)导致错误。*
- 智能:极佳的编辑器支持。处处皆可自动补全,减少调试时间。
- 简单:设计的易于使用和学习,阅读文档的时间更短。
- 简短:使代码重复最小化。通过不同的参数声明实现丰富功能。bug%20更少。
- 健壮:生产可用级别的代码。还有自动生成的交互式文档。
- 标准化:基于(并完全兼容)API%20的相关开放标准:OpenAPI%20(以前被称为%20Swagger)%20和%20JSON%20Schema。
*%20根据对某个构建线上应用的内部开发团队所进行的测试估算得出。
评价
「[…]%20最近我一直在使用%20FastAPI。[…]%20实际上我正在计划将其用于我所在的微软团队的所有机器学习服务。其中一些服务正被集成进核心%20Windows%20产品和一些%20Office%20产品。」
Kabir%20Khan%20-%20微软%20(ref)「我们选择了%20FastAPI%20来创建用于获取预测结果的%20REST%20服务。[用于%20Ludwig]」
Piero%20Molino,Yaroslav%20Dudin%20和%20Sai%20Sumanth%20Miryala%20-%20Uber%20(ref)「Netflix%20非常高兴地宣布,正式开源我们的危机管理编排框架:Dispatch![使用%20FastAPI%20构建]」
Kevin%20Glisson,Marc%20Vilanova,Forest%20Monsen%20-%20Netflix%20(ref)「FastAPI%20让我兴奋的欣喜若狂。它太棒了!」
Brian%20Okken%20-%20Python%20Bytes%20播客主持人%20(ref)「老实说,你的作品看起来非常可靠和优美。在很多方面,这就是我想让%20Hug%20成为的样子%20-%20看到有人实现了它真的很鼓舞人心。」
Timothy%20Crosley%20-%20Hug%20作者%20(ref)「如果你正打算学习一个现代框架用来构建%20REST%20API,来看下%20FastAPI%20[…]%20它快速、易用且易于学习%20[…]」
「我们已经将%20API%20服务切换到了%20FastAPI%20[…]%20我认为你会喜欢它的%20[…]」
Ines%20Montani%20-%20Matthew%20Honnibal%20-%20Explosion%20AI%20创始人%20-%20spaCy%20作者%20(ref)%20-%20(ref)Typer,命令行中的%20FastAPI
如果你正在开发一个在终端中运行的命令行应用而不是%20web%20API,不妨试下%20Typer。
Typer%20是%20FastAPI%20的小同胞。它想要成为命令行中的%20FastAPI。%20⌨️%20🚀
依赖
Python%20及更高版本
FastAPI%20站在以下巨人的肩膀之上:
- Starlette%20负责%20web%20部分。
- Pydantic%20负责数据部分。
安装
console
$%20pip%20install%20fastapi
--->%20100%
你还会需要一个%20ASGI%20服务器,生产环境可以使用%20Uvicorn%20或者%20Hypercorn。
console
$%20pip%20install%20"uvicorn[standard]"
--->%20100%
示例
创建
- 创建一个%20
main.py%20文件并写入以下内容:
from%20typing%20import%20Unionfrom%20fastapi%20import%20FastAPIapp%20=%20FastAPI()@app.get("/")def%20read_root():%20%20%20%20return%20{"Hello":%20"World"}@app.get("/items/{item_id}")def%20read_item(item_id:%20int,%20q:%20Union[str,%20None]%20=%20None):%20%20%20%20return%20{"item_id":%20item_id,%20"q":%20q}
或者使用%20async%20def…
如果你的代码里会出现%20async%20/%20await,请使用%20async%20def:
Python%20hl_lines="9%20%2014"
from%20typing%20import%20Union
from%20fastapi%20import%20FastAPI
app%20=%20FastAPI()
@app.get("/")
async%20def%20read_root():
%20%20%20%20return%20{"Hello":%20"World"}
@app.get("/items/{item_id}")
async%20def%20read_item(item_id:%20int,%20q:%20Union[str,%20None]%20=%20None):
%20%20%20%20return%20{"item_id":%20item_id,%20"q":%20q}
Note:
如果你不知道是否会用到,可以查看文档的%20“In%20a%20hurry?”%20章节中%20关于%20async%20和%20await%20的部分。
运行
通过以下命令运行服务器:
console
$%20uvicorn%20main:app%20--reload
INFO:%20%20%20%20%20Uvicorn%20running%20on%20http://127.0.0.1:8000%20(Press%20CTRL+C%20to%20quit)
INFO:%20%20%20%20%20Started%20reloader%20process%20[28720]
INFO:%20%20%20%20%20Started%20server%20process%20[28722]
INFO:%20%20%20%20%20Waiting%20for%20application%20startup.
INFO:%20%20%20%20%20Application%20startup%20complete.
关于%20uvicorn%20main:app%20—reload%20命令……
%20uvicorn%20main:app%20命令含义如下:
%20main:main.py%20文件(一个%20Python%20“模块”)。
%20app:在%20main.py%20文件中通过%20app%20=%20FastAPI()%20创建的对象。
*%20--reload:让服务器在更新代码后重新启动。仅在开发时使用该选项。
检查
使用浏览器访问%20http://127.0.0.1:8000/items/5?q=somequery。
你将会看到如下%20JSON%20响应:
{"item_id":%205,%20"q":%20"somequery"}
你已经创建了一个具有以下功能的%20API:
- 通过%20路径%20
/%20和%20/items/{item_id}%20接受%20HTTP%20请求。 - 以上%20路径%20都接受%20
GET%20操作(也被称为%20HTTP%20方法)。 /items/{item_id}%20路径%20有一个%20路径参数%20item_id%20并且应该为%20int%20类型。/items/{item_id}%20路径%20有一个可选的%20str%20类型的%20查询参数%20q。
交互式%20API%20文档
现在访问%20http://127.0.0.1:8000/docs。
你会看到自动生成的交互式%20API%20文档(由%20Swagger%20UI生成):
可选的 API 文档
访问 http://127.0.0.1:8000/redoc。
你会看到另一个自动生成的文档(由 ReDoc 生成):

示例升级
现在修改 main.py 文件来从 PUT 请求中接收请求体。
我们借助 Pydantic 来使用标准的 Python 类型声明请求体。
```Python hl_lines=”4 9-12 25-27” 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}
服务器将会自动重载(因为在上面的步骤中你向 `uvicorn` 命令添加了 `--reload` 选项)。### 交互式 API 文档升级访问 <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>。* 交互式 API 文档将会自动更新,并加入新的请求体:* 点击「Try it out」按钮,之后你可以填写参数并直接调用 API:* 然后点击「Execute」按钮,用户界面将会和 API 进行通信,发送参数,获取结果并在屏幕上展示:### 可选文档升级访问 <a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a>。* 可选文档同样会体现新加入的请求参数和请求体:### 总结总的来说,你就像声明函数的参数类型一样只声明了**一次**请求参数、请求体等的类型。你使用了标准的现代 Python 类型来完成声明。你不需要去学习新的语法、了解特定库的方法或类,等等。只需要使用标准的 **Python 及更高版本**。举个例子,比如声明 `int` 类型:```Pythonitem_id: int
或者一个更复杂的 Item 模型:
item: Item
……在进行一次声明之后,你将获得:
- 编辑器支持,包括:
- 自动补全
- 类型检查
- 数据校验:
- 在校验失败时自动生成清晰的错误信息
- 对多层嵌套的 JSON 对象依然执行校验
- 转换 来自网络请求的输入数据为 Python 数据类型。包括以下数据:
- JSON
- 路径参数
- 查询参数
- Cookies
- 请求头
- 表单
- 文件
- 转换 输出的数据:转换 Python 数据类型为供网络传输的 JSON 数据:
- 转换 Python 基础类型 (
str、int、float、bool、list等) datetime对象UUID对象- 数据库模型
- ……以及更多其他类型
- 转换 Python 基础类型 (
- 自动生成的交互式 API 文档,包括两种可选的用户界面:
- Swagger UI
- ReDoc
回到前面的代码示例,FastAPI 将会:
- 校验
GET和PUT请求的路径中是否含有item_id。 - 校验
GET和PUT请求中的item_id是否为int类型。- 如果不是,客户端将会收到清晰有用的错误信息。
- 检查
GET请求中是否有命名为q的可选查询参数(比如http://127.0.0.1:8000/items/foo?q=somequery)。- 因为
q被声明为= None,所以它是可选的。 - 如果没有
None它将会是必需的 (如PUT例子中的请求体)。
- 因为
- 对于访问
/items/{item_id}的PUT请求,将请求体读取为 JSON 并:- 检查是否有必需属性
name并且值为str类型 。 - 检查是否有必需属性
price并且值为float类型。 - 检查是否有可选属性
is_offer, 如果有的话值应该为bool类型。 - 以上过程对于多层嵌套的 JSON 对象同样也会执行
- 检查是否有必需属性
- 自动对 JSON 进行转换或转换成 JSON。
- 通过 OpenAPI 文档来记录所有内容,可被用于:
- 交互式文档系统
- 许多编程语言的客户端代码自动生成系统
- 直接提供 2 种交互式文档 web 界面。
虽然我们才刚刚开始,但其实你已经了解了这一切是如何工作的。
尝试更改下面这行代码:
return {"item_name": item.name, "item_id": item_id}
……从:
... "item_name": item.name ...
……改为:
... "item_price": item.price ...
……注意观察编辑器是如何自动补全属性并且还知道它们的类型:

教程 - 用户指南 中有包含更多特性的更完整示例。
剧透警告: 教程 - 用户指南中的内容有:
- 对来自不同地方的参数进行声明,如:请求头、cookies、form 表单以及上传的文件。
- 如何设置校验约束如
maximum_length或者regex。 - 一个强大并易于使用的 依赖注入 系统。
- 安全性和身份验证,包括通过 JWT 令牌和 HTTP 基本身份认证来支持 OAuth2。
- 更进阶(但同样简单)的技巧来声明 多层嵌套 JSON 模型 (借助 Pydantic)。
- 许多额外功能(归功于 Starlette)比如:
- WebSockets
- GraphQL
- 基于 HTTPX 和
pytest的极其简单的测试 - CORS
- Cookie Sessions
- ……以及更多
性能
独立机构 TechEmpower 所作的基准测试结果显示,基于 Uvicorn 运行的 FastAPI 程序是 最快的 Python web 框架之一,仅次于 Starlette 和 Uvicorn 本身(FastAPI 内部使用了它们)。(*)
想了解更多,请查阅 基准测试 章节。
可选依赖
用于 Pydantic:
email_validator- 用于 email 校验。
用于 Starlette:
httpx- 使用TestClient时安装。jinja2- 使用默认模板配置时安装。python-multipart- 需要通过request.form()对表单进行「解析」时安装。itsdangerous- 需要SessionMiddleware支持时安装。pyyaml- 使用 Starlette 提供的SchemaGenerator时安装(有 FastAPI 你可能并不需要它)。graphene- 需要GraphQLApp支持时安装。
用于 FastAPI / Starlette:
uvicorn- 用于加载和运行你的应用程序的服务器。orjson- 使用ORJSONResponse时安装。ujson- 使用UJSONResponse时安装。
你可以通过 pip install "fastapi[all]" 命令来安装以上所有依赖。
许可协议
该项目遵循 MIT 许可协议。
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。









评论