首页 > 其他分享 >【10.0】依赖注入系统

【10.0】依赖注入系统

时间:2023-10-01 15:47:36浏览次数:31  
标签:10.0 依赖 dep commons Depends async def 注入

【一】引入

【1】介绍

  • “依赖注入”是指在编程中,为保证代码成功运行,先导入或声明其所需要的 “依赖”,如子函数、数据库连接等

【2】优势

  • 提高代码的复用率
  • 共享数据库的连接
  • 增强安全、认证和角色管理

【3】FastAPI的兼容性

  • 所有的关系型数据库,支撑NoSQL数据库
  • 第三方的包和API
  • 认证和授权系统
  • 响应数据注入系统

【二】创建、导入和声明依赖

【1】创建

from fastapi import APIRouter, Depends
from typing import Optional

app05 = APIRouter()


# 创建公共函数

async def common_parameters(q: Optional[str] = None, page: int = 1, limit: int = 100):
    return {"q": q, "page": page, "limit": limit}

【2】导入和声明

# 定义视图
@app05.get('/dependency01')
async def dependency01(commons: dict = Depends(common_parameters)):
    return commons


# 可以在async def中调用def依赖,也可以在def中导入async def依赖
@app05.get('/dependency02')
def dependency01(commons: dict = Depends(common_parameters)):
    return commons

【3】使用

  • async def中调用def依赖

image-20230930131019844

  • def中导入async def依赖

image-20230930131103153

【三】类作为依赖项

【1】定义视图

from fastapi import APIRouter, Depends
from typing import Optional

app05 = APIRouter()


"""Classes as Dependencies 类作为依赖项"""

fake_items_db = [{"item_name": "Foo"}, {"item_name": "Bar"}, {"item_name": "Baz"}]


class CommonQueryParams:
    def __init__(self, q: Optional[str] = None, page: int = 1, limit: int = 100):
        self.q = q
        self.page = page
        self.limit = limit


@app05.get("/classes_as_dependencies")
# 写法一
# async def classes_as_dependencies(commons: CommonQueryParams = Depends(CommonQueryParams)):

# 写法二
# async def classes_as_dependencies(commons: CommonQueryParams = Depends()):

#写法三
async def classes_as_dependencies(commons=Depends(CommonQueryParams)):
    response = {}
    if commons.q:
        response.update({"q": commons.q})
    items = fake_items_db[commons.page: commons.page + commons.limit]
    response.update({"items": items})
    return response

【2】发起请求

image-20230930131441677

【四】子依赖的创建和调用

【1】定义视图

from fastapi import APIRouter, Depends
from typing import Optional

app05 = APIRouter()

"""Sub-dependencies 子依赖"""


def query(q: Optional[str] = None):
    return q


def sub_query(q: str = Depends(query), last_query: Optional[str] = None):
    if not q:
        return last_query
    return q


@app05.get("/sub_dependency")
async def sub_dependency(final_query: str = Depends(sub_query, use_cache=True)):
    """use_cache默认是True, 表示当多个依赖有一个共同的子依赖时,每次request请求只会调用子依赖一次,多次调用将从缓存中获取"""
    return {"sub_dependency": final_query}

【2】发起请求

image-20230930145607476

【五】路径装饰器中的多依赖

【1】定义视图

from fastapi import APIRouter, Depends, HTTPException, Header
from typing import Optional

app05 = APIRouter()


"""Dependencies in path operation decorators 路径操作装饰器中的多依赖"""


async def verify_token(x_token: str = Header(...)):
    """没有返回值的子依赖"""
    if x_token != "fake-super-secret-token":
        raise HTTPException(status_code=400, detail="X-Token header invalid")


async def verify_key(x_key: str = Header(...)):
    """有返回值的子依赖,但是返回值不会被调用"""
    if x_key != "fake-super-secret-key":
        raise HTTPException(status_code=400, detail="X-Key header invalid")
    return x_key


@app05.get("/dependency_in_path_operation",
           # 这时候不是在函数参数中调用依赖,而是在路径操作中
           dependencies=[Depends(verify_token), Depends(verify_key)])
async def dependency_in_path_operation():
    return [{"user": "user01"}, {"user": "user02"}]

【2】发起请求

  • token 和 key 都不相符的情况

image-20230930150050533

  • token 相符 key 不相符

image-20230930150158575

  • token 和 key 都相符

image-20230930150255380

【六】全局依赖的使用

"""Global Dependencies 全局依赖"""


# 单独在某个路由下的全局使用
app05 = APIRouter(dependencies=[Depends(verify_token), Depends(verify_key)])

# 也可以放在全局的总app下

【七】使用yield的依赖和子依赖

这个需要Python3.7才支持,
Python3.6需要pip install async-exit-stack async-generator
  • 伪代码示例
from fastapi import APIRouter, Depends, HTTPException, Header
from typing import Optional

app05 = APIRouter()


# 以下都是伪代码

async def get_db():
    db = "db_connection"
    try:
        # 使用数据库
        yield db
    finally:
        # 关闭数据库
        db.endswith("db_close")


async def dependency_a():
    dep_a = "generate_dep_a()"
    try:
        # 使用依赖 a
        yield dep_a
    finally:
        # 关闭依赖 数据库
        dep_a.endswith("db_close")


async def dependency_b(dep_a=Depends(dependency_a)):
    dep_b = "generate_dep_b()"
    try:
        # 使用依赖 b
        yield dep_b
    finally:
        # 关闭依赖 a
        dep_b.endswith(dep_a)


async def dependency_c(dep_b=Depends(dependency_b)):
    dep_c = "generate_dep_c()"
    try:
        # 使用依赖 c
        yield dep_c
    finally:
        # 关闭依赖 b
        dep_c.endswith(dep_b)

标签:10.0,依赖,dep,commons,Depends,async,def,注入
From: https://www.cnblogs.com/dream-ze/p/17738896.html

相关文章

  • 解决Maven依赖问题
    问题描述:pom文件报错:Cannotaccessnexus-aliyun(http://maven.aliyun.com/nexus/content/...)inofflinemode。问题解决:pom文件maven依赖一直导入失败。原因是由于网不好,maven在下载依赖时,文件未下载完整,.lastUpdated结尾的文件,因此你只需要找到那个出错的包,你把这个包直接......
  • sql注入原理分析
    SQL注入的原理与分析1、SQL注入的本质2、部分SQL语句3、SQL注入流程一、SQL注入的本质SQL注入的本质,就是把用户输入的数据当作代码执行Web应用程序对用户输入的数据校验处理不严或者根本没有校验,致使用户可以拼接执行SQL命令两个必要关键的条件:第一,用户能......
  • 202309272035-《maven依赖已下载,但还是报红,解决办法》
    1. 勾选设置,maven,选中“始终更新快照”。  2.点击“更新” ......
  • 202309272022-《idea编辑器,maven解析依赖慢,解决办法》
    法一:1.Preference2.Search"maven"keyword,,3.选中“运行程序(runner)”,4.在右侧“vm选项”一栏,输入:  -DarchetypeCatalog=internal 至于为什么,我也说不出一二。 法二:https://blog.csdn.net/weixin_43912822/article/details/114173413......
  • pipreqs:Python导出项目依赖包
    许多教程使用的是pipfreeze>requirements.txt指令,但是这个指令只能检索当前虚拟环境中安装的包。要想自动检索项目文件中的依赖包要使用pipreqs,使用方法如下:首先安装pipreqspipinstallpipreqs使用在项目根目录下执行命令pipreqs./#生成requirements.txtpip......
  • .NET Core|--调用C++库|--LibraryImport docker环境下,处理依赖问题--GCC--Docker
    前言万恶之源在于,C#程序中需要调用C++的一个函数库,在Windows环境下,只要保证引用的相关dll存在,就是ok的,但是在Linux环境下,并且我的Webapi程序是部署在docker中的,问题就比较麻烦一些.经历了新建软链接,缺失".so"文件,有了".so"文件后,版本错误:libstdc++.so.......
  • SQL注入 --【过滤or(包含information、orderby这种也寄了)和and的类型】
    来自:[SWPU2019]Web1详见博客:https://blog.csdn.net/plant1234/article/details/124205120payload如下:查看行数1'/**/group/**/by/**/1,'1......直到1'/**/group/**/by/**/23,'1报错也就是说有22行找出回显点//找出回显点-1'/**/union/**/select/**/1,2,3,4,5,6,7......
  • ASP.NET Core Web (三) 依赖注入
    依赖注入注入方法方法说明AddTransient每次service请求都是获得不同的实例,暂时性模式AddScoped对于同一个请求返回同一个实例,不同的请求返回不同的实例,作用域模式AddSingleton每次都是获得同一个实例,单一实例模式MVC控制器的DI构造函数输入创建接口......
  • 前端中循环依赖原因分析及解决方案
    前端中循环依赖什么是循环依赖:两个以上模块之间互相引用,构成闭环依赖。保持依赖引入的单向流通性!示例:不要觉得自己不会写出这样的代码,当项目庞大后一旦出现这样的问题将会造成无法排查的问题。//在a.js引用b.js内容import{b}from"./b.js"exportconsta=()=>......
  • JNDI注入
    简介根据官方教程,JNDI(JavaNamingandDirectoryInterface)是为Java程序提供的,一组用来统一调用命名服务和目录服务的API,逻辑结构如下:可以看到下面的SPI中,有熟悉的RMI服务和DNS服务,也有没用过的CORBA和LDAP服务等。那么到底什么是JNDI?一句话说:接口一词在计算机系统中再常见不......