FastAPI 介绍及示例开发
1、文档及安装
在线文档:FastAPI,源码:https://github.com/fastapi/fastapi
pip安装:
pip install fastapi
pip install "uvicorn[standard]"
2、FastAPI 特点
(1)高性能
FastAPI 基于 ASGI(异步服务器网关接口)和 Starlette 框架,支持异步编程,能够高效处理大量并发请求。其性能接近 Node.js 和 Go,比传统的 Python 框架(如 Django 和 Flask)快 3-5 倍,特别适合高并发场景。
(2)自动生成 API 文档
FastAPI 能够根据代码中的类型提示和注解自动生成交互式 API 文档(如 Swagger UI 和 ReDoc),能在浏览器中直接调用和测试你的 API 。这不仅减少了手动编写文档的工作量,还方便了开发和调试。
(3)类型提示与数据验证
FastAPI 利用 Python 的类型提示机制和 Pydantic 库,提供强大的数据验证和序列化功能。这确保了输入数据的正确性,减少了运行时错误,并提高了代码的可读性和可维护性。
(4)异步支持
FastAPI 原生支持异步编程(async/await),能够高效处理 I/O 密集型任务(如数据库查询、API 调用),特别适合实时数据处理和高并发场景。
(5)易于使用和学习
FastAPI 的设计注重用户体验,代码简洁易懂,支持代码自动补全和编辑器提示,降低了学习曲线,提高了开发效率。
(6)安全性
FastAPI 内置支持多种安全机制,如 OAuth2、JWT 等认证方式,并提供 HTTPS 支持,确保 API 的安全性。
3、示例demo
3.1、基础服务
from typing import Union
from fastapi import FastAPIapp = 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}if __name__ == "__main__":import uvicornuvicorn.run(app, host="0.0.0.0", port=8000)
运行:
http://127.0.0.1:8000/docs,查看由 Swagger UI 生成的自动生成的交互式 API 文档。页面刷新不出来,直接跳到第4节。
http://127.0.0.1:8000/redoc,查看由 ReDoc 生成的自动生成文档。
3.2、 借助 Pydantic 来使用标准的 Python 类型声明请求体
修改 main.py 文件来从 PUT 请求中接收请求体。
from typing import Unionfrom fastapi import FastAPI
from pydantic import BaseModelapp = FastAPI()class Item(BaseModel):name: strprice: floatis_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}
运行:
http://127.0.0.1:8000/docs,新增对参数类型的声明描述。点击Try it out,就可以输入参数,测试接口。
3.3、小结
总的来说,只需要像声明函数的参数类型一样只声明了一次请求参数、请求体等的类型。只需要使用标准的 Python 及更高版本。如,参数类型声明:
item_id: int # 声明 int 类型
item: Item # 声明 Item 模型
在进行一次声明之后,即可获得:
(1)编辑器支持,包括:自动补全、类型检查;
(2)数据校验:在校验失败时自动生成清晰的错误信息、对多层嵌套的 JSON 对象依然执行校验;
(3)转换,网络请求的输入数据为 Python 数据类型。包括:JSON、路径参数、查询参数、Cookies、请求头、表单、文件;
(4)转换,输出的数据:转换 Python 数据类型为供网络传输的 JSON 数据:转换 Python 基础类型 (str、 int、 float、 bool、 list 等)、datetime 对象、UUID 对象、数据库模型,以及更多其他类型;
(5)自动生成的交互式 API 文档,包括两种可选的用户界面:Swagger UI、ReDoc。
回到前面的代码示例,FastAPI 将会:
(1)校验 GET 和 PUT 请求的路径中是否含有 item_id。
(2)校验 GET 和 PUT 请求中的 item_id 是否为 int 类型。如果不是,客户端将会收到清晰有用的错误信息。
(3)检查 GET 请求中是否有命名为 q 的可选查询参数(比如 http://127.0.0.1:8000/items/foo?q=somequery)。
因为 q 被声明为 = None,所以它是可选的。如果没有 None 它将会是必需的 (如 PUT 例子中的请求体)。
(4)对于访问 /items/{item_id} 的 PUT 请求,将请求体读取为 JSON 并:
检查是否有必需属性 name 并且值为 str 类型 。
检查是否有必需属性 price 并且值为 float 类型。
检查是否有可选属性 is_offer, 如果有的话值应该为 bool 类型。
以上过程对于多层嵌套的 JSON 对象同样也会执行
(5)自动对 JSON 进行转换或转换成 JSON。
(6)通过 OpenAPI 文档来记录所有内容,可被用于:交互式文档系统、许多编程语言的客户端代码自动生成系统。
(7)直接提供 2 种交互式文档 web 界面。
可选依赖:
用于 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]" 命令来安装以上所有依赖。
4、使用本地静态资源(重要)
在测试FastAPI时,/docs、/redoc访问总是时好时坏,坏的时候页面加载不出来。按F12查看,发现部分静态资源加载失败:
解决办法:修改代码,手动下载 Swagger UI 的静态文件,然后在 FastAPI 中挂载本地静态资源目录。
步骤1、下载 Swagger UI 静态文件
从 Swagger UI 的 GitHub 仓库的发布页面下载最新的静态文件压缩包如:swagger-ui-5.28.0-dist.zip,下载地址:https://github.com/swagger-api/swagger-ui/releases 。
下载完成后,解压压缩包:swagger-ui-5.28.0.zip。当前工程目录下创建swagger_ui目录,将压缩包下的dist目录,放在swagger_ui下。
从ReDoc官方CDN,右键下载https://cdn.jsdelivr.net/npm/redoc@latest/bundles/redoc.standalone.js文件到dist目录下。目录结构为:
项目根目录/
├── main.py
└── swagger_ui/└── dist # 静态资源目录└── swagger-ui.css └── swagger-ui-bundle.js└── redoc.standalone.js
步骤 2、同时重置 /docs 和 /redoc 接口的代码
from typing import Union
from fastapi import FastAPI
from pydantic import BaseModel
from fastapi import FastAPI, Request
from fastapi.responses import HTMLResponse
from fastapi.staticfiles import StaticFilesfrom pathlib import Pathapp = FastAPI(docs_url=None) # 彻底禁用默认的 /docs 路由# 挂载本地 Swagger UI 静态文件(必须确保路径正确)
app.mount("/swagger-ui", # 客户端访问静态资源的路径前缀StaticFiles(directory=Path(__file__).parent / "swagger_ui" / "dist"),name="swagger-ui"
)# 自定义 /docs 页面,完全使用本地资源
@app.get("/docs", response_class=HTMLResponse)
async def custom_docs(request: Request):# 读取并返回自定义的 HTML(使用本地资源路径)html_content = f"""<!DOCTYPE html><html><head><link type="text/css" rel="stylesheet" href="/swagger-ui/swagger-ui.css"><title>FastAPI - 本地 Swagger UI</title></head><body><div id="swagger-ui"></div><script src="/swagger-ui/swagger-ui-bundle.js"></script><script>const ui = SwaggerUIBundle({{url: '/openapi.json', // 指向你的 API 描述文件dom_id: '#swagger-ui',layout: 'BaseLayout',deepLinking: true,showExtensions: true,showCommonExtensions: true,oauth2RedirectUrl: window.location.origin + '/docs/oauth2-redirect'}})</script></body></html>"""return HTMLResponse(content=html_content)# 自定义 /redoc 接口
@app.get("/redoc", response_class=HTMLResponse)
async def custom_redoc():return """<!DOCTYPE html><html><head><title>FastAPI - ReDoc</title><!-- 引用本地 ReDoc 资源 --><script src="/swagger-ui/redoc.standalone.js"></script></head><body><!-- 加载本地 openapi.json --><redoc spec-url="/openapi.json"></redoc></body></html>"""# 测试接口
@app.get("/")
def read_root():return {"message": "Hello World"}
验证:
1、 验证静态文件访问:启动 FastAPI 应用后,通过访问
http://localhost:8000/swagger-ui/index.html 验证静态文件是否可访问。若能正常显示 Swagger UI 页面,则说明配置成功。
2、浏览器验证,可以正常访问。
http://localhost:8000/docs
http://localhost:8000/redoc
3、访问验证:
curl http://localhost:8000/docs