跳至内容

FastAPI

FastAPI

FastAPI 框架,高性能,易于学习,快速编码,可用于生产

Test Coverage Package version Supported Python versions


文档https://fastapi.org.cn

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


FastAPI 是一个现代化、快速(高性能)的 Web 框架,用于使用基于标准 Python 类型提示的 Python 构建 API。

主要特性包括

  • 快速:非常高的性能,与 NodeJSGo 相当(感谢 Starlette 和 Pydantic)。现有的最快 Python 框架之一
  • 快速编码:将开发功能的速度提高约 200% 到 300%。*
  • 更少的错误:减少约 40% 的人为(开发人员)引起的错误。*
  • 直观:出色的编辑器支持。随处可见的代码补全。减少调试时间。
  • 简单:旨在易于使用和学习。减少阅读文档的时间。
  • 简洁:最大限度地减少代码重复。每个参数声明都有多个功能。更少的错误。
  • 健壮:获取可用于生产的代码。带有自动交互式文档。
  • 基于标准:基于(并完全兼容)API 的开放标准:OpenAPI(以前称为 Swagger)和JSON Schema

* 基于内部开发团队在构建生产应用程序时的测试估算。

赞助商

其他赞助商

观点

"[...] 我现在大量使用 FastAPI。 [...] 我实际上计划将其用于我的团队在 Microsoft 的所有 ML 服务。其中一些正在集成到核心 Windows 产品和一些 Office 产品中。"

Kabir Khan - Microsoft (参考)

"我们采用了 FastAPI 库来生成一个可以查询以获取 预测REST 服务器。[用于 Ludwig]"

Piero Molino、Yaroslav Dudin 和 Sai Sumanth Miryala - Uber (参考)

"Netflix 很高兴宣布我们 危机管理 编排框架 Dispatch 的开源发布![使用 FastAPI 构建]"

Kevin Glisson、Marc Vilanova、Forest Monsen - Netflix (参考)

"我对 FastAPI 非常兴奋。太有趣了!"

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

"老实说,您构建的内容看起来非常可靠且经过精心打磨。在许多方面,这正是我希望 Hug 成为的样子——看到有人构建它真的很有启发性。"

Timothy Crosley - Hug 创建者 (参考)

"如果您想学习一个用于构建 REST API 的 现代框架,请查看 FastAPI [...] 它速度快,易于使用和学习 [...]"

"我们已经切换到 FastAPI 用于我们的 API [...] 我认为您会喜欢它 [...]"

Ines Montani - Matthew Honnibal - Explosion AI 创始人 - spaCy 创建者 (参考) - (参考)

"如果有人想构建一个生产环境的 Python API,我强烈推荐FastAPI。它设计精良易于使用高度可扩展,它已成为我们 API 首发开发策略中的关键组件,并且正在驱动许多自动化和服务,例如我们的虚拟 TAC 工程师。"

Deon Pillsbury - 思科 (参考)

Typer,CLI 的 FastAPI

如果您正在构建一个用于终端而不是 Web API 的CLI应用程序,请查看Typer

Typer 是 FastAPI 的小兄弟。它的目标是成为CLI 的 FastAPI。⌨️ 🚀

要求

FastAPI 站在巨人的肩膀上

安装

创建并激活一个虚拟环境,然后安装 FastAPI

$ pip install "fastapi[standard]"

---> 100%

注意:确保将"fastapi[standard]"放在引号中,以确保它在所有终端中都能正常工作。

示例

创建它

  • 创建一个名为main.py的文件,内容如下:
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}
或者使用async def...

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

from typing import Union

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: Union[str, None] = None):
    return {"item_id": item_id, "q": q}

注意:

如果您不了解,请查看文档中关于asyncawait的“快速入门”部分。

运行它

使用以下命令运行服务器:

$ fastapi dev main.py

 ╭────────── FastAPI CLI - Development mode ───────────╮
 │                                                     │
 │  Serving at: http://127.0.0.1:8000                  │
 │                                                     │
 │  API docs: http://127.0.0.1:8000/docs               │
 │                                                     │
 │  Running in development mode, for production use:   │
 │                                                     │
 │  fastapi run                                        │
 │                                                     │
 ╰─────────────────────────────────────────────────────╯

INFO:     Will watch for changes in these directories: ['/home/user/code/awesomeapp']
INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO:     Started reloader process [2248755] using WatchFiles
INFO:     Started server process [2248757]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
关于命令fastapi dev main.py...

命令fastapi dev读取您的main.py文件,检测其中的FastAPI应用程序,并使用Uvicorn启动服务器。

默认情况下,fastapi dev将在本地开发中启用自动重新加载。

您可以在FastAPI CLI 文档中了解更多信息。

检查它

在浏览器中打开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}有一个路径参数item_id,它应该是一个int
  • 路径/items/{item_id}有一个可选的str查询参数q

交互式 API 文档

现在访问http://127.0.0.1:8000/docs

您将看到自动生成的交互式 API 文档(由Swagger UI提供)

Swagger UI

备选 API 文档

现在,访问http://127.0.0.1:8000/redoc

您将看到备选的自动文档(由ReDoc提供)

ReDoc

示例升级

现在修改文件main.py以接收来自PUT请求的正文。

使用标准 Python 类型声明正文,这要归功于 Pydantic。

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}

fastapi dev服务器应该会自动重新加载。

交互式 API 文档升级

现在访问http://127.0.0.1:8000/docs

  • 交互式 API 文档将自动更新,包括新的正文

Swagger UI

  • 点击“试用”按钮,它允许您填写参数并直接与 API 交互

Swagger UI interaction

  • 然后点击“执行”按钮,用户界面将与您的 API 通信,发送参数,获取结果并在屏幕上显示它们

Swagger UI interaction

备选 API 文档升级

现在,访问http://127.0.0.1:8000/redoc

  • 备选文档也将反映新的查询参数和正文

ReDoc

回顾

总之,您只声明一次参数、正文等类型作为函数参数。

您可以使用标准的现代 Python 类型来做到这一点。

您无需学习特定库的新语法、方法或类等。

只需标准的Python

例如,对于int

item_id: int

或者对于更复杂的Item模型

item: Item

...并且通过这个单一的声明,您将获得

  • 编辑器支持,包括
    • 代码补全。
    • 类型检查。
  • 数据验证
    • 数据无效时自动生成清晰的错误。
    • 即使对于嵌套很深的 JSON 对象也能进行验证。
  • 转换输入数据:从网络到 Python 数据和类型。读取自
    • JSON。
    • 路径参数。
    • 查询参数。
    • Cookie。
    • 标头。
    • 表单。
    • 文件。
  • 转换输出数据:将 Python 数据和类型转换为网络数据(作为 JSON)
    • 转换 Python 类型(strintfloatboollist等)。
    • datetime对象。
    • UUID对象。
    • 数据库模型。
    • ...以及更多。
  • 自动生成的交互式 API 文档,包括 2 个备选的用户界面
    • Swagger UI。
    • ReDoc。

回到前面的代码示例,FastAPI

  • 验证GETPUT请求的路径中是否存在item_id
  • 验证GETPUT请求的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 转换。
  • 使用 OpenAPI 记录所有内容,这些内容可被
    • 交互式文档系统使用。
    • 自动客户端代码生成系统使用,适用于多种语言。
  • 直接提供 2 个交互式文档 Web 界面。

我们只是触及了表面,但您已经了解了它的工作原理。

尝试更改以下代码行:

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

...从

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

...到

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

...看看您的编辑器如何自动完成属性并识别其类型

editor support

有关包含更多功能的更完整示例,请参阅教程 - 用户指南

剧透警告:教程 - 用户指南包含

  • 从其他不同位置声明参数,例如:标头Cookie表单字段文件
  • 如何设置验证约束,例如maximum_lengthregex
  • 一个功能强大且易于使用的依赖注入系统。
  • 安全性和身份验证,包括对使用JWT 令牌OAuth2HTTP 基本身份验证的支持。
  • 声明嵌套很深的 JSON 模型的更高级(但同样简单)的技术(感谢 Pydantic)。
  • 使用Strawberry和其他库进行GraphQL集成。
  • 许多额外的功能(感谢 Starlette),例如
    • WebSocket
    • 基于 HTTPX 和pytest的极其简单的测试
    • CORS
    • Cookie 会话
    • ...等等。

性能

独立的 TechEmpower 基准测试表明,在 Uvicorn 下运行的FastAPI应用程序是目前可用的最快 Python 框架之一,仅次于 Starlette 和 Uvicorn 本身(FastAPI 内部使用)。(*)

要了解更多信息,请参阅基准测试部分。

依赖项

FastAPI 依赖于 Pydantic 和 Starlette。

standard 依赖项

当您使用pip install "fastapi[standard]"安装 FastAPI 时,它会附带standard组的可选依赖项

Pydantic 使用

Starlette 使用

  • httpx - 如果您想使用TestClient,则需要此依赖项。
  • jinja2 - 如果您想使用默认的模板配置,则需要此依赖项。
  • python-multipart - 如果您想支持表单"解析"(使用request.form()),则需要此依赖项。

FastAPI/Starlette 使用

  • uvicorn - 用于加载和服务您的应用程序的服务器。这包括uvicorn[standard],其中包含一些用于高性能服务的依赖项(例如uvloop)。
  • fastapi-cli - 提供fastapi命令。

不带standard依赖项

如果您不想包含standard可选依赖项,可以使用pip install fastapi而不是pip install "fastapi[standard]"进行安装。

其他可选依赖项

您可能希望安装一些其他依赖项。

其他可选的 Pydantic 依赖项

其他可选的 FastAPI 依赖项

  • orjson - 如果您想使用ORJSONResponse,则需要此依赖项。
  • ujson - 如果您想使用UJSONResponse,则需要此依赖项。

许可证

本项目根据 MIT 许可证的条款授权。