FastAPI从入门到实战(16)——依赖项

news2024/11/24 6:06:42

依赖注入是耳熟能详的一个词了,听起来很复杂,实际上并没那么复杂,正常的访问需要接受各种参数来构造一个对象,依赖注入就变成了只接收一个实例化对象,主要用于共享业务逻辑、共享数据库连接、实现安全、验证、权限等相关的业务功能,本文主要记录一下fastapi的依赖注入。

函数依赖项

# 创建、导入、声明依赖
async def user_verification(
        user: str,
        birthday: date,
        age: int
):
    return {
        "user": user,
        "birthday": birthday,
        "age": age
    }


# 同时依赖于user_verification
@app10.get("/user_verification/test1")
async def user_verification_test1(
        test1: dict = Depends(user_verification)
):
    return test1


@app10.get("/user_verification/test2")
async def user_verification_test2(
        test2: dict = Depends(user_verification),
        test2_param:Optional[str] = None
):
    return {
        "test2":test2,
        "test2_param":test2_param
    }

上面代码就完成了一个依赖项函数的创建和调用,首先是创建了一个依赖项函数user_verification,函数接受三个参数,并将三个参数以字典的形式返回;

后面的两个路径操作函数在本质上是一样的,对于test1,定义一个dict类型的参数test1用于接收依赖项函数的返回值,然后将test1进行返回,test2除了要接受依赖项user_verification需要的参数以外,还接受路径修饰函数的test2_param参数,并将其返回。

这个示例就很好的示例了依赖项函数的使用,fastapi的依赖注入系统会自动处理所有的依赖项及其子依赖项,并为每一步操作都注入结果。

  • http://127.0.0.1:8000/stu/user_verification/test1?user=MinChess&birthday=2021-12-23&age=11

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vw6YEGkL-1672050817200)(https://kodo.jiumoz.com/imgs/202212221801866.png)]

  • http://127.0.0.1:8000/stu/user_verification/test2?test2_param=%E6%9C%AC%E8%BA%AB%E7%9A%84%E4%B8%80%E4%B8%AA%E5%8F%82%E6%95%B0&user=%E4%B9%9D%E9%99%8C%E6%96%8B&birthday=2012-12-03&age=23

image-20221222181048641

类依赖项

# 类作为依赖项
class User:
    def __init__(self, name: str, age: Optional[str], birthday: date):
        self.name = name
        self.age = age
        self.birthday = birthday


@app10.get("/stu10_UserClass")
async def stu10_UserClass(
        user: User = Depends(User)
):
    return user

上面定义了一个User类,在默认的构造函数中,除了默认的self参数,另外指定了三个参数,和上面的例子一样;进一步在路径修饰函数中指定user参数依赖于User类。

FastAPI调用User类,以此会创建该类的一个"实例",该实例作为参数user传递给路径修饰函数。

image-20221222181813704

多层依赖

# 多层依赖

def first_verification(
        param1: Optional[str] = None
):
    print(param1)
    return param1


def second_verification(
        param_1: str = Depends(first_verification),
        param_2: Optional[str] = None
):
    if not param_1:
        return param_2
    return param_1


@app10.get("/stu10_more_verification")
async def stu10_more_vberification(
        param: str = Depends(second_verification)
):
    return {"param": param}

这段代码包含三个函数,第一个函数是第一层依赖,声明了一个可选的参数param1,并将这个参数进行返回;

第二个参数是另一个依赖项函数,它自身还依赖于第一个依赖项函数,判断传入的值是哪一个,有值就返回;

最后一个路径操作函数,声明一个param参数,依赖于第二个依赖项函数,最后将param参数返回。

fastapi对于多层依赖,一层一层的处理,先处理第一个再处理第二个。

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

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

image-20221223162757034

image-20221223162816998

路径操作装饰器依赖项

# 路径操作装饰器依赖项
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


@app10.get("/stu10/items/", dependencies=[Depends(verify_token), Depends(verify_key)])
async def read_items():
    return [{"item": "Foo"}, {"item": "Bar"}]

官方文档的解释是:有时,我们并不需要在路径操作函数中使用依赖项的返回值。

或者说,有些依赖项不返回值。

但仍要执行或解析该依赖项。

对于这种情况,不必在声明路径操作函数的参数时使用 Depends,而是可以在路径操作装饰器中添加一个由 dependencies 组成的 list

如上代码,在路径操作装饰器中添加 dependencies 参数,这个参数是由Depends()组成的list

它的解析和执行方法和普通的依赖项是一样的,但是它们的值不会传递给路径操作函数,不管有没有返回值,路径操作都不会使用这些值。

image-20221226162153311

全局依赖项

async def main_depends():
    print("main depends")


app = FastAPI(
    title='FastAPI学习教程文档——title',
    description='这是FastAPI教程的文档——description',
    version='1.0.0',
    docs_url='/docs',
    redoc_url='/redoc',
    dependencies=[Depends(main_depends)]
)

全局依赖项就是为整个应用添加依赖项,添加方式和定义路径装饰器依赖项类似,可以把依赖项添加到整个FastAPI主应用中。

如上就是在FastAPI应用中添加dependencies参数。

以此,所有的路径操作都会默认依赖上面的依赖项函数。

如下,随便访问一个路径,控制台都会打印main depends

image-20221226163722379

依赖项中使用 yield

# 依赖项中使用yield
async def get_yield():
    try:
        yield "yield param"
    finally:
        print("yield end!")


@app10.get("/stu10/yield")
async def stu10_yield(
        yieldparam: str = Depends(get_yield)
):
    return {
        "yield_param": yieldparam
    }

FastAPI 支持在依赖项返回后执行一些额外的步骤,但需要用 yield 代替 return 来达到这一目的。

也就是该依赖项函数返回值后还需要进行一些操作,这个时候就需要利用yield关键字。

如上代码,返回yield param后继续操作打印yield end!这里主要记录一下yield的简单使用,更多的可以参看下面的官网简介。

同样也可以多层依赖,还有很多底层的内容,可以参看官网:https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-with-yield/

image-20221226182224122


感谢阅读!

九陌斋地址:https://blog.jiumoz.com/archives/fastapi-cong-ru-men-dao-shi-zhan-16-yi-lai-xiang

欢 迎 关 注 博 主 个 人 小 程 序!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/116726.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

原油投资怎么样赚钱?原油投资赚钱技巧有哪些?

以前没有交易过原油的投资者,看到其他投资者从中获得了较好的盈利,也想通过原油投资来赚钱。那么原油投资到底能不能赚钱,是很多新手投资者比较想了解的问题。其实原油投资想盈利并不能全部依靠运气,只有掌握了原油投资赚钱技巧&a…

【Java基础】Java日志—什么是日志级别?如何配置数据源到不同的位置?配置文件内容都是什么含义?

目录 一、log4j1详情:记录器和日志级别 二、 log4j1详情:输出源【输出到不同的位置】 1、ConsoleAppender【将日志输出到控制台】 2、FileAppender【将日志输出到文件】 3、DailyRollingFileAppender【每日输出到一个新文件】 4、JDBCAppender【输…

FineReport开源报表系统-JS实现切换Tab块时进行数据联动

1. 概述 1.1 预期效果 在决策报表中,希望 Tab 块轮播切换时,可实现与报表块的数据联动。如下图所示: 1.2 实现思路 通过 JS 获取每个 Tab 块的轮播标题,转换为参数值,再通过控件进行界面传参,实现联动效果…

程序员工作五年后一般会怎样?

最近看到一些吐血言论“一个程序员工作5年后还没成为大牛,是不是该考虑别的路子了?”还有“程序员入行五年,有可能攒够80吗?”不是,程序员工作五年,是戳中了谁的痛点吗??大家对五年经…

128页4万字某智慧能源集团数字化管理平台项目建议书

【版权声明】本资料来源网络,仅用于行业知识分享,供个人学习参考,请勿商用。【侵删致歉】如有侵权请联系小编,将在收到信息后第一时间进行删除!完整资料领取见文末,部分资料内容: 方案设计 在当…

公司新来的软件测试工程师接私活被抓了,难怪他天天加班到凌晨

昨天和我一起进公司的测试部门同事上班接私活被老板抓了,这人才来不到两个月,每天加班到凌晨。刚开始还以为他是个卷王,没想到此人上班时间接单,用加班时间来完成公司需求,造成努力的假象。被老板在办公室骂了俩小时&a…

v$asm_disk中free_mb低于300m导致加盘报ora-15041

背景: 某项目扩容加盘到磁盘组中报磁盘组空间耗尽的错误,如下 明明是加盘,却报空间不足的错误,令人费解 报错的磁盘组为normal冗余,且Usable_file_MB为负,且Free_MB剩余很少或为0 问题排查: …

MS 训练笔记【2】:nnFormer

文章目录前言1. 安装2. 训练与测试2.1. 数据处理2.1.1. 整理数据路径2.1.2. 设置 nnFormer 读取文件的路径2.1.3. 数据集预处理2.2. 训练2.2.1. 训练代码2.2.2. 可能出现的问题及解决办法2.3. 预测总结前言 本文主要记载 nnFormer 从安装到训练再到推理的过程。nnFormer 的环境…

invokeBeanFactoryPostProcessors的理解

invokeBeanFactoryPostProcessors的理解 Spring中有两个非常重要的扩展点: BeanFactoryPostProcessorBeanPostProcessor 其中第一个是可以对BeanDefinition注册时进行扩展,而第二个是对spring中IOC容器中的对象进行实例化的时候进行扩展。 今天主要谈一…

【安全漏洞】水平权限漏洞和垂直权限漏洞

前言 权限校验非常重要。如果不对水平、垂直权限做校验,就会发生泄漏用户数据的事故,造成P0故障。 一、水平权限漏洞 1、水平权限漏洞基本概念 什么是水平权限漏洞呢? 简单来说,水平权限漏洞是用户CURD了本不属于他的资源。以上图…

复活天若OCR的谷歌翻译接口

文章目录1. 资源2. 效果3. 前言4. 网络相关4.1. 网络判断4.2. 网络设置5. 修改5.1. 代码修改原理5.2. 代码修改1. 资源 这里直接放出来我已经修改编译好的天若OCR,开箱即用:https://www.lanzoui.com/ifT8t0jfv1gd 访问码:24647 不过需要说明…

性能优化系列之如何为不同格式的图片选择合适的应用场景?

文章の目录一、JPEG(Joint Photographic Experts Group)1、介绍2、不适合情形3、非常适合的情形二、PNG(Portable Network Graphics)1、介绍2、不适合的情形3、非常适合的情形三、GIF(Graphics Interchange Format&…

【nowcoder】笔试强训Day9

目录 一、选择题 二、编程题 2.1另类加法 2.2走方格的方案数 一、选择题 1.下面程序的输出是:() String x"fmn"; x.toUpperCase(); String yx.replace(f,F); yy"wxy"; System.out.println(y); A FmNwxy B fmnwxy C wxyfmn D Fmnwxy String x “…

决胜「年货时代」:一场关于零食的品质突围

“都说冰糖葫芦儿酸,酸里面它裹着甜;都说冰糖葫芦儿甜,可甜里面它透着那酸。” 1995年春节,伴随着《冰糖葫芦》唱响大街小巷,小贩骑着自行车,后车座的草靶子上插满冰糖葫芦,或摆在集市上&#…

大数据系列——什么是hive?hive用来干什么的?hive常见问题是啥?

目录 一、什么是hive 二、为什么要使用Hive 三、Hive与Hadoop的关系 四、Hive与HDFS的关系 五、Hive与传统数据库区别 六、Hive中的数据存储是怎样的 七、对hive进行增删改查 八、排序逻辑 九、hive不支持update数据的解决方案 十、Hive中支持的分区类型有两种 十…

Linux部署前端Vue项目

Linux部署前端Vue项目 1 部署到tomcat上 1.1 部署Vue项目 打包项目 在命令行终端,输入命令,打包项目: npm run build将生成的dist文件夹下的所有内容复制到tomcat的webapps下 "推荐":在webapps下新建一个文件夹,例…

【互信息驱动:可逆神经网络】

Mutual Information-driven Pan-sharpening (互信息驱动的全色锐化) 全色锐化的目的是综合纹理丰富的全色图像和多光谱图像的互补信息,生成纹理丰富的多光谱图像。尽管已有的全色锐化方法取得了显著的进步,但它们并没有明确地加…

动态圣诞树-HTML

<!DOCTYPE HTML PUBLIC> <html> <head> <title>圣诞树</title> <meta charset"utf-8" > <style> html, body { width: 100%; height: 100%; margin: 0; padding: 0; border: 0; } div { margin: 0; padding: 0; border: 0…

docker高级篇:实战-自己开发的微服务怎么在docker上面运行?

通过前面的一系列学习,我们已经知道怎么制作dockerfile了。那么,本篇文章,咱们就把自己写的spring boot的demo项目,部署在docker上面。 案例目标: 我们自己开发的微服务怎么在docker上面运行呢? 1:通过IDEA新建一个普通的微服务模块 2:通过dockerfile发布微服务部署…

通过 api 和 keycloak 理解OIDC认证

参考资料 通过Keycloak API理解OAuth2与OpenID Connect 什么是keycloak如何在nodejs中使用它 如何通过 OIDC 协议实现单点登录&#xff1f; https://jwt.io/#encoded-jwt OIDC认证的简单demo 单点登录&#xff08;Single Sign On&#xff09;是目前比较流行的企业业务整合…