IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Python知识库 -> fastapi_No.11_依赖项(1) -> 正文阅读

[Python知识库]fastapi_No.11_依赖项(1)

依赖的介绍

依赖项可以是一个函数,也可以是一个类。通过在路径操作函数中引入依赖项,可以达到先调用依赖项,并将依赖项调用的结果作为路径操作函数的输入。
下面通过一个示例来引出依赖项。
当多个路径操作函数中都具有相同的处理逻辑时,可以将共同的处理逻辑提取出来,作为依赖项。然后将这个依赖项引入各个路径操作函数中。这样就可以复用代码,将代码重复最小化。
在这里插入图片描述
依赖项通常使用在如下场景:

  • 共享业务逻辑(复用相同的代码逻辑)
  • 共享数据库连接
  • 实现安全、验证、角色权限等

函数依赖

当依赖项是一个函数的时候,此时依赖项就是一个函数依赖。
常见和使用函数依赖主要有以下步骤:
步骤1:创建依赖函数
示例中创建一个返回字典的函数。

# 步骤1:创建依赖函数,和定义函数没有区别
async def common_parameters(
    q:Union[str,None] = None,
    skip:int = 0,
    limit:int = 100
):
    return {
        "q":q,
        "skip":skip,
        "limit":limit
    }

步骤2:在路径操作函数中使用依赖项

# 步骤2:在路径操作函数中使用依赖函数
# 要使用依赖项,需要引入fastapi中的Depends函数
@app.get("/items")
async def read_items(commons:dict = Depends(common_parameters)):
    return commons

完整代码:

from typing import Union
from fastapi import Depends,FastAPI
app = FastAPI()
# 步骤1:创建依赖函数,和定义函数没有区别
async def common_parameters(
    q:Union[str,None] = None,
    skip:int = 0,
    limit:int = 100
):
    return {
        "q":q,
        "skip":skip,
        "limit":limit
    }

# 步骤2:在路径操作函数中使用依赖函数
# 要使用依赖项,需要引入fastapi中的Depends函数
@app.get("/items")
async def read_items(commons:dict = Depends(common_parameters)):
    return commons
@app.get("/users")
async def read_users(commons:dict = Depends(common_parameters)):
    return commons
if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app="main:app",host="127.0.0.1",port=8080,reload=True)

这个示例中路径操作函数执行过程:

  1. 执行common_parameters函数,并得到返回值commons
  2. 路径操作函数将commons作为输入,执行其函数体中的逻辑

通过这个执行过程可以看出依赖项,在路径操作函数执行前,进行了一些逻辑处理。
或者可以说路径操作函数的结果依赖于依赖项的执行结果。

有一点需要新手注意:依赖项的输入参数是路径操作函数的一部分!
本示例验证结果:
在这里插入图片描述

类依赖

在fastapi中不仅仅函数可以作为依赖项,类也可以作为依赖项。这里仅修改函数依赖中的代码进行说明。
依赖也分两步使用:
步骤1:创建公共类

# 步骤1:创建公共类
class CommonQueryParams:
    def __init__(self,q:Union[str,None]=None,skip:int = 0,limit:int = 100):
        self.q = q
        self.skip = skip
        self.limit = limit

步骤2:路径操作函数中引用公共类

# 步骤2:在路径操作函数中引入公共类
@app.get("/item")
async def read_item(common:CommonQueryParams=Depends(CommonQueryParams)):
    return jsonable_encoder(common)

完整代码如下:

from typing import Union

from fastapi import Depends,FastAPI
from fastapi.encoders import jsonable_encoder

app = FastAPI()

# 步骤1:创建公共类
class CommonQueryParams:
    def __init__(self,q:Union[str,None]=None,skip:int = 0,limit:int = 100):
        self.q = q
        self.skip = skip
        self.limit = limit

# 步骤2:在路径操作函数中引入公共类
@app.get("/item")
# 引入依赖类的简写方式为common:CommonQueryParams=Depends()
async def read_item(common:CommonQueryParams=Depends(CommonQueryParams)):
    return jsonable_encoder(common)

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app="main:app",host="127.0.0.1",port=8080,reload=True)

测试结果如下:
在这里插入图片描述

对比函数依赖和类依赖的路径操作函数,需要注意:
在函数依赖中路径操作函数参数的类型声明为依赖函数的返回结果类型,Depends函数的参数是函数名
在类依赖中路径操作函数参数的类型声明为依赖类的类名,Depends函数的参数是依赖类名

嵌套依赖

fastapi中支持创建含依赖项的依赖项,并可以按需声明任意深度的子依赖项嵌套层级。

# 下面演示嵌套依赖
# 定义最外层依赖函数
def query_extractor(q:Union[str,None] = None):
	print("q")
    return q
# 定义依赖最外层依赖函数的依赖函数
def query_or_cookie_extractor(
    q:str=Depends(query_extractor),
    last_query:Union[str,None]=Cookie(default=None)
    ):
    print("cookie")
    if not q:
        return last_query
    return q
# 定义使用了嵌套依赖函数的路径操作函数
@app.post("/items")
def create_items(query_or_default:str = Depends(query_or_cookie_extractor)):
    return {"q_or_cookie":query_or_default}

从下图演示结果可以看出,fastapi运行依赖项时,最先运行最里层的依赖,然后依次运行外层的依赖项。
在这里插入图片描述
在这里插入图片描述

当路径操作函数中存在依赖项时,该路径操作函数的输入参数就是所有依赖项参数的和路径操作函数本身参数的集合。
上例的路径参数的输入参数是q查询参数和last_query cookie参数。

多次使用同一个依赖项

如果在同一个路径操作 多次声明了同一个依赖项,例如,多个依赖项共用一个子依赖项,FastAPI 在处理同一请求时,只调用一次该子依赖项。

FastAPI 不会为同一个请求多次调用同一个依赖项,而是把依赖项的返回值进行「缓存」,并把它传递给同一请求中所有需要使用该返回值的「依赖项」。

在高级使用场景中,如果不想使用「缓存」值,而是为需要在同一请求的每一步操作(多次)中都实际调用依赖项,可以把 Depends 的参数 use_cache 的值设置为 False

async def needy_dependency(fresh_value: str = Depends(get_value, use_cache=False)):
    return {"fresh_value": fresh_value}

路径操作装饰器依赖项

当依赖项没有返回值,但是仍要执行或解析该依赖项时,就不必在声明路径操作函数的参数时使用Depends,而是可以在路径操作装饰器中添加一个由dependencies组成的列表。

async def verify_token(x_token:str=Header()):
    if not x_token:
        raise HTTPException(status_code=400,detail="not X-Token header invalid")

async def verify_key(x_key:str=Header()):
    if not x_key:
        raise HTTPException(status_code=400,detail="not X-Key header invalid")

@app.get("/student",dependencies=[Depends(verify_key),Depends(verify_token)])
async def read_student():
    return {"msg":"hello"}

从测试结果可以看出,这里的依赖都会被执行一次。
在这里插入图片描述

全局依赖

当依赖项被每个路径操作函数依赖时,我们可以通过添加全局依赖的方式为每个路径操作函数添加依赖。而避免了在每个路径操作函数或路径装饰器中添加依赖。
这主要是通过在FastAPI创建实例对象时使用dependencies参数。

# 演示创建全局依赖,被某个应用中的所有路径依赖
app1 = FastAPI(dependencies=[Depends(verify_key),Depends(verify_token)])
@app1.get("/student")
async def read_student():
    return {"msg":"hello"}
  Python知识库 最新文章
Python中String模块
【Python】 14-CVS文件操作
python的panda库读写文件
使用Nordic的nrf52840实现蓝牙DFU过程
【Python学习记录】numpy数组用法整理
Python学习笔记
python字符串和列表
python如何从txt文件中解析出有效的数据
Python编程从入门到实践自学/3.1-3.2
python变量
上一篇文章      下一篇文章      查看所有文章
加:2022-10-22 21:11:19  更:2022-10-22 21:12:17 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/15 6:47:02-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码