FastAPI 框架,高性能,易学,快速编码,随时可供生产
文档:https://fastapi.tiangolo.com
源码:https://github.com/tiangolo/fastapi
FastAPI 是一个现代、快速(高性能)的 Web 框架,基于标准 Python 类型提示,使用 Python 3.6+ 构建 API。
主要功能包括:
-
快速: 与NodeJS和Go相当,拥有高性能(感谢 Starlette 和 Pydantic)。 现有最快的Python框架之一。
-
快速编码:将功能开发速度提高约200%至300%。
-
更少的Bug:减少约40%的人为(开发人员)导致的错误。
-
直观:更好的编辑支持。补全任何地方(也称为自动完成,自动完成,IntelliSense)。更少的调试时间。
-
简单:方便使用和学习。减少阅读文档的时间。
-
简洁:最小化代码重复。每个参数声明的多个要素。更少的错误。
-
Robust:获取便于生产的代码。带自动交互式文档。
-
基于标准:基于(并完全兼容)API 的开放标准:OpenAPI(以前称为Swagger)和 JSON Schema。
* 根据内部开发团队的测试进行估算,以构建生产应用程序。
观点
"[...] I'm using FastAPI a ton these days. [...] I'm actually planning to use it for all of my team's ML services at Microsoft. Some of them are getting integrated into the core Windows product and some Office products."
"I’m over the moon excited about FastAPI. It’s so fun!"
"Honestly, what you've built looks super solid and polished. In many ways, it's what I wanted Hug to be - it's really inspiring to see someone build that."
---"If you're looking to learn one modern framework for building REST APIs, check out FastAPI [...] It's fast, easy to use and easy to learn [...]"
"We've switched over to FastAPI for our APIs [...] I think you'll like it [...]"
---"We adopted the FastAPI library to spawn a REST server that can be queried to obtain predictions. [for Ludwig]"
Typer,CLI中的FastAPI
如果要构建用于终端而不是Web API的CLI(Command Line Interface)应用,请查看Typer。
Typer是FastAPI的小兄弟。它打算成为CLI中的FastAPI。
依赖
Python 3.6+
FastAPI站在巨人的肩膀上:
安装
$ pip install fastapi
---> 100%
你还需要一个ASGI服务器来进行生产,例如Uvicorn 或者 Hypercorn。
$ pip install uvicorn
---> 100%
示例
创建
- 创建一个
main.py
文件:
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: str = None):
return {"item_id": item_id, "q": q}
或者使用async def
...
如果你的代码使用 async
/ await
,请使用 async def
:
from fastapi import FastAPIapp = FastAPI()
@app.get("/") async def read_root(): return {"Hello": "World"}
@app.get("/items/{item_id}") async def read_item(item_id: int, q: str = None): return {"item_id": item_id, "q": q}
注意:
如果你不知道,请在文档中的 "急吗?" 查看有关 async
和 await
的部分。
运行
使用以下命令运行服务:
$ 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
命令指:
main
:main.py
文件(Python“模块”)。app
:在main.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}
有一个 路径参数item_id
应该是一个int
。 - 路径
/items/{item_id}
有一个可选的str
类型的 查询参数q
。
交互式API文档
现在前往 http://127.0.0.1:8000/docs。
你将看到自动交互式API文档(由Swagger UI提供):
备用的API文档
现在,前往 http://127.0.0.1:8000/redoc。
你将看到备用的自动文档(由ReDoc提供):
示例升级
现在修改文件main.py
以接收来自PUT
请求的主体。
使用标准的Python类型声明主体,感谢Pydantic。
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
price: float
is_offer: bool = None
@app.get("/")
def read_root():
return {"Hello": "World"}
@app.get("/items/{item_id}")
def read_item(item_id: int, q: 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文档将自动更新,包含新的正文:
- 单击按钮“Try it out”,它允许你填充参数并直接与API交互::
- 然后单击“Execute”按钮,用户界面将与你的API通信,发送参数,获取结果并将其显示在屏幕上:
备用API文档升级
现在,前往 http://127.0.0.1:8000/redoc。
- 替代文档也将体现新的查询参数和正文:
概括
总而言之,你一次性将参数的类型,主体等声明为函数参数。
你可以使用标准的现代Python类型来做到这一点。
你不必学习新的语法,特定库的方法或类等。
只是标准的Python 3.6 +。
例如,对于一个int
:
item_id: int
或更复杂的Item
模型:
item: Item
...通过单个声明,你将得到:
- 编辑器支持,包括:
- 代码补全。
- 类型检查。
- 数据验证:
- 数据无效时自动清除错误。
- 甚至对深度嵌套的JSON对象也进行验证。
- 输入数据的转换(也称为:序列化,解析,编组):从网络转换为Python数据和类型。 阅读:
- JSON。
- 路径参数。
- 查询参数。
- Cookies。
- 标头。
- 表单。
- 文件。
- 输入数据的转换(也称为:序列化,解析,编组):从Python数据类型转换为网络数据(如JSON):
- 转换Python类型(
str
,int
,float
,bool
,list
等)。 datetime
对象。UUID
对象。- 数据库模型。
- ...还有很多。
- 转换Python类型(
- 自动交互式API文档,包括2个备用用户界面:
- Swagger UI.
- ReDoc.
回到前面的代码示例,FastAPI将:
- 验证路径中是否有用于
GET
和PUT
请求的item_id
。 - 验证
item_id
的类型是否为GET
和PUT
请求的int
类型。- 如果不是,客户端将看到一个有用的明确错误。
- 检查是否有一个名为
q
的可选查询参数(如http://127.0.0.1:8000/items/foo?q=somequery
中的内容)用于GET
请求。- 由于
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 ...
...并查看编辑器如何自动补全属性并了解其类型:
有关包含更多功能的更完整示例,请参阅教程-用户指南。
剧透警报:教程-用户指南包括:
- 从其他不同地方声明参数:标头,Cookies,表单字段和文件。
- 如何将验证约束设置为
maximum_length
或regex
。 - 一个非常强大且易于使用的依赖注入(也称为组件,资源,提供者,服务,可注入)系统。
- 安全性和身份验证,身份验证支持OAuth2包括通过JWT令牌和HTTP Basic。
- 用于声明深度嵌套的JSON模型的更高级(但同样容易)的技术(感谢Pydantic)。
- 许多额外的功能(感谢Starlette):
- WebSockets
- GraphQL
- 基于
requests
和pytest
的极其简单的测试 - CORS
- Cookie会话
- ...和更多。
性能
独立的TechEmpower基准测试显示FastAPI应用程序在Uvicorn下运行为最快的Python框架之一,仅在Starlette和Uvicorn(由FastAPI内部使用)之下。
要了解更多信息,请参阅基准测试。
可选依赖项
使用Pydantic:
ujson
- 为了更快的JSON“解析”(将来自HTTP请求的字符串转换为Python数据)。email_validator
- for email validation.
使用Starlette:
requests
- 如果要使用TestClient
,则为必需。aiofiles
- 如果要使用FileResponse
或StaticFiles
,则为必需。jinja2
- 如果要使用默认模板配置,则为必需。python-multipart
- 如果你想使用request.form()
支持“解析”(将来自HTTP请求的字符串转换为Python数据),则为必需。itsdangerous
- 对于SessionMiddleware
支持是必需的。pyyaml
- 是支持Starlette的SchemaGenerator
所必需的(FastAPI可能不需要它)。graphene
- 对于GraphQLApp
支持是必需的。ujson
- 如果要使用UJSONResponse
,则为必需。
使用FastAPI/Starlette:
你可以使用pip install fastapi[all]
安装所有这些。
许可证
该项目根据MIT许可条款获得许可。