跳转至

FastAPI

FastAPI

FastAPI 速度快、上手快、开发快,生产环境可用

Test Coverage Package version


文档https://fastapi.tiangolo.com

源码https://github.com/tiangolo/fastapi


FastAPI 基于 Python 3.7+ 及 Python 标准类型提示,是快速构建高性能 API 的现代 Web 框架。

核心特性:

  • 速度快:归功于 Starlette 和 Pydantic,FastAPI 具有可与 NodeJSGo 比肩的极高性能,是最快的 Python 网络框架之一
  • 开发快:开发速度提高约 200% 至 300%*。
  • Bug 少:人为错误减少约 40%*。
  • 智能:强大的编辑器支持,处处皆可自动补全,减少调试时间。
  • 简单:易学、易用,阅读文档所需时间更短。
  • 简短:代码重复最小化,通过不同的参数声明实现丰富功能,Bug 更少。
  • 健壮:生产级别的代码,还有自动交互文档。
  • 标准:完全兼容并基于 API 开放标准:OpenAPI(曾用名为 Swagger)和 JSON Schema

* 根据对某线上应用内部开发团队的测试估算得出。

赞助商

其他赞助商

评价

[...] 最近我一直在用 FastAPI。[...] 实际上,我打算用 FastAPI 实现微软团队的所有机器学习服务。目前,我们正把一些服务集成至 WindowsOffice 等核心产品。

Kabir Khan - 微软 (ref)

我们用 FastAPI 创建获取预测结果REST 服务。[用于 Ludwig]

Piero Molino,Yaroslav Dudin 和 Sai Sumanth Miryala - Uber (ref)

Netflix 很荣幸地宣布,正式开源危机管理编排框架:Dispatch![使用 FastAPI 构建]

Kevin Glisson,Marc Vilanova,Forest Monsen - Netflix (ref)

FastAPI 让我欣喜若狂。它太棒了!

Brian Okken - Python Bytes 播客主持人 (ref)

老实说,您的作品看起来非常可靠和优美。这就是我心目中的 Hug - 看到有人实现了,真的很鼓舞人心。

Timothy Crosley - Hug 作者 (ref)

如果您想学习开发 REST API 的现代 Web 框架,看下 FastAPI 吧 [...] 它易学、易用、速度快 [...]

我们已经将 API 服务切换到了 FastAPI [...] 我觉得您也会喜欢 [...]

Ines Montani - Matthew Honnibal - Explosion AI 创始人 - spaCy 作者 (ref) - (ref)

Typer,命令行中的 FastAPI

如果您开发的不是 Web API,而是在终端中运行的命令行应用,不妨试下 Typer

Typer 是 FastAPI 的小兄弟,立志要成为命令行中的 FastAPI。 ⌨️ 🚀

依赖支持

Python 3.7+

FastAPI 站在以下巨人的肩膀上:

安装

$ pip install fastapi

---> 100%

FastAPI 还需要 ASGI 服务器,生产环境下可以使用 UvicornHypercorn

$ pip install uvicorn[standard]

---> 100%

示例

创建应用

  • 创建 main.py,写入以下代码:
from typing import Optional

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: Optional[str] = None):
    return {"item_id": item_id, "q": q}
或者使用 async def...

如果代码中使用了 async / await,请使用 async def

from typing import Optional

from fastapi import FastAPI

app = FastAPI()


@app.get("/")
async def read_root():
    return {"Hello": "World"}


@app.get("/items/{item_id}")
async def read_item(item_id: int, q: Optional[str] = None):
    return {"item_id": item_id, "q": q}

笔记

如果不清楚是否应该使用异步,请参阅文档等不及了?asyncawait 的介绍

运行

执行以下命令运行服务器:

$ uvicorn main:app --reload

INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO:     Started reloader process [28720]
INFO:     Started server process [28722]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
关于 uvicorn main:app --reload 命令......

uvicorn main:app 命令含义如下:

  • mainmain.py( Python 模块)。
  • appmain.py 中通过 app = FastAPI() 创建的对象。
  • --reload:代码更新后,重启服务器。仅在开发时使用。

查看文档

打开浏览器,访问 http://127.0.0.1:8000/items/5?q=somequery

返回如下 JSON 响应:

{"item_id": 5, "q": "somequery"}

至此,我们就创建了具有以下功能的 API:

  • 通过路径 //items/{item_id} 接收 HTTP 请求。
  • 这两个路径都能接收 GET 操作(也叫作 HTTP 方法)。
  • /items/{item_id} 路径包含类型为 int路径参数 item_id
  • /items/{item_id} 路径还包含可选的,类型为 str查询参数 q

API 交互文档

访问 http://127.0.0.1:8000/docs

查看由 Swagger UI 自动生成的 API 文档:

Swagger UI

备用 API 文档

访问 http://127.0.0.1:8000/redoc

查看由 ReDoc 自动生成的 API 文档:

ReDoc

更新示例

修改 main.py,从 PUT 请求中接收请求体。

借助 Pydantic 使用 Python 标准类型声明请求体。

from typing import Optional

from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()


class Item(BaseModel):
    name: str
    price: float
    is_offer: Optional[bool] = None


@app.get("/")
def read_root():
    return {"Hello": "World"}


@app.get("/items/{item_id}")
def read_item(item_id: int, q: Optional[str] = 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 文档

访问 http://127.0.0.1:8000/docs

  • 自动更新 API 文档,包括新的请求体:

Swagger UI

  • 点击「Try it out」按钮,填写参数,直接调用 API:

Swagger UI interaction

  • 然后,点击「Execute」按钮,用户界面和 API 通信,发送参数,获取结果,并在屏幕上显示:

Swagger UI interaction

更新备用文档

访问 http://127.0.0.1:8000/redoc

  • 备选文档也会显示新加入的请求参数和请求体:

ReDoc

小结

总的来说,和声明函数的参数一样,只需声明一次参数类型和请求体。

在此,使用了现代 Python 的标准类型进行声明。

开发者不用学习新语法,也不用了解特定库的方法或类。

只要使用标准的 Python 3.7+

例如,声明 int

item_id: int

或使用更复杂的 Item 模型:

item: Item

......只需一次声明,就可以获得以下好处:

  • 编辑器支持,包括:
    • 自动补全。
    • 类型检查。
  • 数据校验:
    • 校验失败时,自动生成清晰的错误信息。
    • 对多层嵌套的 JSON 对象依然执行校验。
  • 转换输入数据:转换为 Python 数据与类型。可从以下对象中读取:
    • JSON
    • 路径参数
    • 查询参数
    • Cookie
    • 请求头
    • 表单
    • 文件
  • 转换输出数据:把 Python 数据类型转换为供网络传输的( JSON )数据:
    • Python 基础类型 (strintfloatboollist 等)
    • datetime 对象
    • UUID 对象
    • 数据库模型
    • ......及更多其他类型
  • 自动生成 API 交互文档,包括两种用户界面:
    • Swagger UI
    • ReDoc

回顾本章的代码示例,FastAPI 可以:

  • 校验 GETPUT 请求的路径中是否含有 item_id
  • 校验 GETPUT 请求中的 item_id 是否为 int 类型
    • 如果不是 int 类型,客户端返回错误信息
  • 检查 GET 请求中是否包含可选查询参数 q(比如 http://127.0.0.1:8000/items/foo?q=somequery
    • q 声明为 = None,所以是可选的
    • 没有 Noneq 就是必选的(如 PUT 例子中的请求体)
  • 对于访问 /items/{item_id}PUT 请求,把请求体读取为 JSON,并且:
    • 检查是否包含必选属性 name,并且值的类型为 str
    • 检查是否包含必选属性 price,并且值的类型为 float
    • 检查是否包含可选属性 is_offer, 如果包含,值的类型应为 bool
    • 以上过程也适用于多层嵌套的 JSON 对象
  • 自动转换 JSON
  • 通过 OpenAPI 文档存档所有内容,可被用于:
    • API 文档
    • 其他编程语言的客户端代码自动生成系统
  • 直接提供两种 API 文档

虽然本篇的介绍比较浅,但涵盖了 FastAPI 的所有工作原理。

试着把下面这行代码:

    return {"item_name": item.name, "item_id": item_id}

......从:

        ... "item_name": item.name ...

......改为:

        ... "item_price": item.price ...

......注意,编辑器可以自动补全属性,还能识别属性的类型:

editor support

用户指南中介绍了包含更多功能的完整示例。

剧透警告: 用户指南中的内容有:

  • 声明各种来源的参数,如:请求头cookiesform 表单上传文件
  • 设置校验约束,如 maximum_lengthregex
  • 强大、但易用的依赖注入系统
  • 安全和身份验证,支持 OAuth2JWT TokenHTTP 基本身份验证等方式
  • (借助 Pydantic)使用更高级,但同样简单的技术声明深度嵌套 JSON 模型
  • (借助 Starlette)实现以下更多功能:
    • WebSockets
    • GraphQL
    • 基于 requestspytest 的简单测试
    • CORS,跨域资源共享
    • Cookie Sessions
    • ......以及更多

性能

独立机构 TechEmpower 的基准测试结果显示,基于 Uvicorn 运行的 FastAPI最快的 Python 网络框架之一,仅次于(FastAPI 内部使用的) Starlette 和 Uvicorn。(*)

详见基准测试一章。

可选依赖支持库

用于 Pydantic:

用于 Starlette:

  • requests - 使用 TestClient 时安装
  • aiofiles - 使用 FileResponseStaticFiles 时安装
  • jinja2 - 使用默认模板配置时安装
  • python-multipart - 通过 request.form() 解析表单时安装
  • itsdangerous - 需要 SessionMiddleware 支持时安装
  • pyyaml - 使用 Starlette 的 SchemaGenerator 时安装(FastAPI 可能不需要此支持库)
  • graphene - 需要 GraphQLApp 支持时安装
  • ujson - 使用 UJSONResponse 时安装

用于 FastAPI / Starlette:

  • uvicorn - 用于加载和运行应用的服务器
  • orjson - 使用 ORJSONResponse 时安装

使用 pip install fastapi[all] 可安装上述所有依赖支持库。

许可协议

本项目遵循 MIT 许可协议。