FastApi
fastapi
是一个用于构建API 的现代、快速(高性能)的web框架,它是建立在Starlette和Pydantic基础上的。
Pydantic是一个基于Python类型提示来定义数据验证、序列化和文档的库,Starlette是一种轻量级的ASGI框架/工具包,适合用Python构建异步Web服务。FastAPI 依赖 Python 3.8 及更高版本。
开始案例
先安装fastapi 和 ASGI服务器
pip install fastapi
pip install uvicorn
然后写一个FastAPI
from typing import Union
import uvicorn
from fastapi import FastAPI
# 创建一个FastAPI应用实例
app = FastAPI()
# 定义一个带有动态参数的GET请求处理器,用于打招呼
@app.get("/hello/{name}")
async def say_hello(name: str):
# 返回一个根据名字定制的打招呼消息
return {
"message": f"Hello {
name}"}
# 定义另一个根路由GET请求处理器,功能与前一个根路由处理器不同
@app.get("/")
def read_root():
# 返回一个简单的欢迎消息
return {
"Hello": "World"}
# 定义一个获取物品信息的GET请求处理器,接受一个物品ID和一个可选参数q
@app.get("/items/{item_id}")
def read_item(item_id: int, q: Union[str, None] = None):
# 返回物品ID和可选参数q的信息
return {
"item_id": item_id, "q": q}
在命令行用uvicorn
运行
PS D:\Users\user\PycharmProjects\fastApiProject> uvicorn main:app --reload
INFO: Will watch for changes in these directories: ['D:\\Users\\user\\PycharmProjects\\fastApiProject']
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO: Started reloader process [30468] using WatchFiles
INFO: Started server process [20408]
INFO: Waiting for application startup.
INFO: Application startup complete.
也可以在python文件中直接运行
if __name__ == "__main__":
uvicorn.run("main:app", host="127.0.0.1", port=8000,reload = True)
浏览器访问http://127.0.0.1:8000/
可以看到输出了欢迎消息
访问http://127.0.0.1:8000/items/5?q=runoob
可以看到输出
FastAPI 交互式 API 文档
FastAPI 提供了内置的交互式 API 文档,使开发者能够轻松了解和测试 API 的各个端点。这个文档是自动生成的,基于 OpenAPI 规范,支持 Swagger UI 和 ReDoc 两种交互式界面。通过 FastAPI 的交互式 API 文档,开发者能够更轻松地理解和使用 API,提高开发效率。在运行 FastAPI 应用时,Uvicorn 同时启动了交互式 API 文档服务。
默认情况下,可以通过访问 http://127.0.0.1:8000/docs
来打开 Swagger UI 风格的文档:
Swagger UI 提供了一个直观的用户界面,用于浏览 API 的各个端点、查看请求和响应的结构,并支持直接在文档中进行 API 请求测试。通过 Swagger UI,你可以轻松理解每个路由操作的输入参数、输出格式和请求示例。
通过 http://127.0.0.1:8000/redoc
来打开 ReDoc 风格的文档。
ReDoc 是另一种交互式文档界面,具有清晰简洁的外观。它使得开发者能够以可读性强的方式查看 API 的描述、请求和响应。与 Swagger UI 不同,ReDoc 的设计强调文档的可视化和用户体验。
交互式文档的优势
- 实时更新: 交互式文档会实时更新,反映出应用代码的最新更改。
- 自动验证: 输入参数的类型和格式会得到自动验证,降低了错误的可能性。
- 便于测试: 可以直接在文档中进行 API 请求测试,避免使用其他工具。
路径操作
FastAPI 支持多种常用的 HTTP 调用方式,包括:
- GET:用于获取资源,例如
@app.get("/items/{item_id}")
。 - POST:用于创建资源,例如
@app.post("/items/")
。 - PUT:用于更新资源,例如
@app.put("/items/{item_id}")
。 - DELETE:用于删除资源,例如
@app.delete("/items/{item_id}")
。 - PATCH:用于部分更新资源,例如
@app.patch("/items/{item_id}")
。
参数
路径操作装饰器的参数:
from typing import Union
import uvicorn
from fastapi import FastAPI
# 创建一个FastAPI应用实例
app = FastAPI()
# 定义一个post方法
@app.post("/items",tags=["这是items测试接口"],
summary="这是items接口的 summary",
description="这是items接口的description",
response_description="这是items接口返回参数的description"
)
def process_value(value: Union[int, float, str]) -> str:
return f"Processed value: {
value}"
if __name__ == "__main__":
uvicorn.run("main:app", host="127.0.0.1", port=8000,reload = True)
include_router
include_router
用于将一个或多个路由器(APIRouter
实例)包含到主应用中。这使得你可以将路由组织成模块化的部分,方便管理和扩展。
比如目录结构如下的项目中
注意:main.py 与apps模块同级,都是在shopping下
appone.urls.py
from fastapi import APIRouter
app01 = APIRouter()
@app01.get("/food")
def get_food():
return {
"food": "pizza"}
@app01.get("/drink")
def get_drink():
return {
"drink": "water"}
apptwo.urls.py
from fastapi import APIRouter
app02 = APIRouter()
@app02.post("/login")
def user_login():
return {
"user": "login"}
@app02.post("/register")
def user_register():
return {
"user": "register"}
main.py
from typing import Union
import uvicorn
from fastapi import FastAPI
from apps.appone.urls import app01
from apps.apptwo.urls import app02
# 创建一个FastAPI应用实例
app = FastAPI()
# 将app01路由器包含进app路由器中,所有路径以"/shop"为前缀,这些路由将被标记为"商城中心接口"
app.include_router(app01, prefix="/shop",tags=["商城中心接口"])
# 将app02路由器包含进app路由器中,所有路径以"/user"为前缀,这些路由将被标记为"用户中心接口"
app.include_router(app02, prefix="/user",tags=["用户中心接口"])
if __name__ == "__main__":
uvicorn.run("main:app", host="127.0.0.1", port=8000,reload = True)
查看API文档,可以看到分成了两个部分,商城中心接口以及用户中心接口
请求与响应
路径参数
可以在路径后用{}
自定义参数传入函数内,路径上传入的参数都是作为str
字符串类型传入的,如果一定要传入某种类型,比如整型可以在函数参数内声明 类型def get_user(id:int)
声明后只能传入int类型的参数,如果类型错误会返回错误信息
@app01.get("/user/{id}")
def get_user(id:int):
print(f"Getting user id:{
id},type:{
type(id)}")
return {
"user_id" : id,
"name": "John Doe",
"age": 30
}
注意:路径匹配会根据代码从上到下匹配,如果有路径重名的情况,会执行在上面的函数,比如有路径/user/1
,/user/{id}
当id = 1 的时候,只会返回上面的信息
@app01.get("/user/1")
def get_user():
return {
"user_id" : "/user/1",
"name": "John Doe",
&