三周精通FastAPI:21 子依赖项和路径操作装饰器依赖项

官方文档:https://fastapi.tiangolo.com/zh/tutorial/dependencies/sub-dependencies/#_6

子依赖项¶

FastAPI 支持创建含子依赖项的依赖项。

并且,可以按需声明任意深度的子依赖项嵌套层级。

FastAPI 负责处理解析不同深度的子依赖项。

第一层依赖项¶

下列代码创建了第一层依赖项:

def query_extractor(q: Union[str, None] = None):return q

这段代码声明了类型为 str 的可选查询参数 q,然后返回这个查询参数。

这个函数很简单(不过也没什么用),但却有助于让我们专注于了解子依赖项的工作方式。

第二层依赖项¶

接下来,创建另一个依赖项函数,并同时用该依赖项自身再声明一个依赖项(所以这也是一个「依赖项」):

def query_or_cookie_extractor(q: str = Depends(query_extractor),last_query: Union[str, None] = Cookie(default=None),
):if not q:return last_queryreturn q

这里重点说明一下声明的参数:

  • 尽管该函数自身是依赖项,但还声明了另一个依赖项(它「依赖」于其他对象)
    • 该函数依赖 query_extractor, 并把 query_extractor 的返回值赋给参数 q
  • 同时,该函数还声明了类型是 str 的可选 cookie(last_query
    • 用户未提供查询参数 q 时,则使用上次使用后保存在 cookie 中的查询

使用依赖项¶

接下来,就可以使用依赖项:

from typing import Unionfrom fastapi import Cookie, Depends, FastAPIapp = FastAPI()def query_extractor(q: Union[str, None] = None):return qdef query_or_cookie_extractor(q: str = Depends(query_extractor),last_query: Union[str, None] = Cookie(default=None),
):if not q:return last_queryreturn q@app.get("/items/")
async def read_query(query_or_default: str = Depends(query_or_cookie_extractor)):return {"q_or_cookie": query_or_default}

"信息"

注意,这里在路径操作函数中只声明了一个依赖项,即 query_or_cookie_extractor

FastAPI 必须先处理 query_extractor,以便在调用 query_or_cookie_extractor 时使用 query_extractor 返回的结果。

多次使用同一个依赖项¶

如果在同一个路径操作 多次声明了同一个依赖项,例如,多个依赖项共用一个子依赖项,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 组成的 list

from fastapi import Depends, FastAPI, Header, HTTPExceptionapp = FastAPI()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@app.get("/items/", dependencies=[Depends(verify_token), Depends(verify_key)])
async def read_items():return [{"item": "Foo"}, {"item": "Bar"}]

路径操作装饰器中添加 dependencies 参数¶

路径操作装饰器支持可选参数 ~ dependencies

该参数的值是由 Depends() 组成的 list

@app.get("/items/", dependencies=[Depends(verify_token), Depends(verify_key)])

路径操作装饰器依赖项(以下简称为“路径装饰器依赖项”)的执行或解析方式和普通依赖项一样,但就算这些依赖项会返回值,它们的值也不会传递给路径操作函数

"提示"

有些编辑器会检查代码中没使用过的函数参数,并显示错误提示。

路径操作装饰器中使用 dependencies 参数,可以确保在执行依赖项的同时,避免编辑器显示错误提示。

使用路径装饰器依赖项还可以避免开发新人误会代码中包含无用的未使用参数。

"说明"

本例中,使用的是自定义响应头 X-KeyX-Token

但实际开发中,尤其是在实现安全措施时,最好使用 FastAPI 内置的安全工具(详见下一章)。

依赖项错误和返回值¶

路径装饰器依赖项也可以使用普通的依赖项函数

依赖项的需求项¶

路径装饰器依赖项可以声明请求的需求项(比如响应头)或其他子依赖项:

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

触发异常¶

路径装饰器依赖项与正常的依赖项一样,可以 raise 异常:

raise HTTPException(status_code=400, detail="X-Token header invalid")raise HTTPException(status_code=400, detail="X-Key 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

为一组路径操作定义依赖项¶

稍后,大型应用 - 多文件一章中会介绍如何使用多个文件创建大型应用程序,在这一章中,您将了解到如何为一组路径操作声明单个 dependencies 参数。

全局依赖项¶

接下来,我们将学习如何为 FastAPI 应用程序添加全局依赖项,创建应用于每个路径操作的依赖项。

全局依赖项¶

有时,我们要为整个应用添加依赖项。

通过与定义路径装饰器依赖项 类似的方式,可以把依赖项添加至整个 FastAPI 应用。

这样一来,就可以为所有路径操作应用该依赖项:

from fastapi import Depends, FastAPI, Header, HTTPExceptionasync 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_keyapp = FastAPI(dependencies=[Depends(verify_token), Depends(verify_key)])@app.get("/items/")
async def read_items():return [{"item": "Portal Gun"}, {"item": "Plumbus"}]@app.get("/users/")
async def read_users():return [{"username": "Rick"}, {"username": "Morty"}]

路径装饰器依赖项 一章的思路均适用于全局依赖项, 在本例中,这些依赖项可以用于应用中的所有路径操作

为一组路径操作定义依赖项¶

稍后,大型应用 - 多文件一章中会介绍如何使用多个文件创建大型应用程序,在这一章中,您将了解到如何为一组路径操作声明单个 dependencies 参数。

实践

子依赖项

源代码

将代码写入dependssub.py文件

from typing import Unionfrom fastapi import Cookie, Depends, FastAPIapp = FastAPI()def query_extractor(q: Union[str, None] = None):return qdef query_or_cookie_extractor(q: str = Depends(query_extractor),last_query: Union[str, None] = Cookie(default=None),
):if not q:return last_queryreturn q@app.get("/items/")
async def read_query(query_or_default: str = Depends(query_or_cookie_extractor)):return {"q_or_cookie": query_or_default}

启动服务

uvicorn dependssub:app --reload

测试

curl "127.0.0.1:8000/items/?q=hello"
{"q_or_cookie":"hello"}

全局依赖项

源代码

将代码写入dependsglobal.py文件

from fastapi import Depends, FastAPI, Header, HTTPExceptionasync 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_keyapp = FastAPI(dependencies=[Depends(verify_token), Depends(verify_key)])@app.get("/items/")
async def read_items():return [{"item": "Portal Gun"}, {"item": "Plumbus"}]@app.get("/users/")
async def read_users():return [{"username": "Rick"}, {"username": "Morty"}]

启动服务

uvicorn dependsglobal:app --reload

测试

curl -X GET "http://127.0.0.1:8000/items/" -H "Content-Type: application/json" -H "x-token:fake-super-secret-token" -H "x-key:fake-super-secret-key"

 输出:

curl -X GET "http://127.0.0.1:8000/items/" -H "Content-Type: application/json" -H "x-token:fake-super-secret-token" -H "x-key:fake-super-secret-key"
[{"item":"Portal Gun"},{"item":"Plumbus"}]


 

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

模具生产管理系统软件:提升制造业效率的新利器

引言 我们都知道,企业面临着提高生产效率、降低成本和提升产品质量的压力。模具生产作为制造过程中至关重要的一环,如何有效管理和优化模具生产过程,成为企业关注的重点。模具生产管理系统应运而生,能够为企业提供实时监控、流程…

MySQL中,如何定位慢查询?定位到的慢SQL如何分析?

目录 1. 慢查询发生的场景? 2. MySQL中,如何定位慢查询? 2.1 详细解释 3. 定位到的慢SQL如何分析? 3.1 详细说明 1. 慢查询发生的场景? 2. MySQL中,如何定位慢查询? 介绍一下当时产生问题…

「C/C++」C++ 设计模式 之 单例模式(Singleton)

✨博客主页何曾参静谧的博客📌文章专栏「C/C」C/C程序设计📚全部专栏「VS」Visual Studio「C/C」C/C程序设计「UG/NX」BlockUI集合「Win」Windows程序设计「DSA」数据结构与算法「UG/NX」NX二次开发「QT」QT5程序设计「File」数据文件格式「PK」Parasoli…

华为云开源项目Sermant正式成为CNCF官方项目

近日,云原生计算基金会(CNCF)正式接纳由华为云发起的云原生无代理服务网格项目Sermant。Sermant的加入,极大地丰富了云原生微服务治理技术的探索、创新和发展,为CNCF社区注入了新的活力。 Sermant是华为云在微服务治理…

用sdcc给51单片机编译C程序

学习单片机大部分人用的是Keil uVision,虽然好用,可大部分人用的是盗版,其实单片机程序小的话,完全可以用文本编辑器(推荐notepad)编写,然后用免费的sdcc来编译,下面介绍一下大致的过程。 sdcc…

Ajax:表单 模板引擎

Ajax&#xff1a;表单 & 模板引擎 form 表单form 属性 Ajax操控表单事件监听阻止默认行为收集表单数据 模板引擎art-template{{}}语法原文输出条件输出循环输出过滤器 原理 form 表单 在HTML中&#xff0c;可以通过<form>创建一个表单&#xff0c;收集用户信息。而采…

【水下生物数据集】 水下生物识别 深度学习 目标检测 机器视觉 yolo(含数据集)

一、背景意义 随着全球海洋生态环境的日益变化&#xff0c;水下生物的监测和保护变得愈发重要。水下生物种类繁多&#xff0c;包括螃蟹、鱼类、水母、虾、小鱼和海星等&#xff0c;它们在海洋生态系统中扮演着关键角色。传统的水下生物监测方法通常依赖于人工观察&#xff0c;效…

[vulnhub]Kioptrix: Level 1.2 (#3)

https://www.vulnhub.com/entry/kioptrix-level-12-3,24/ 主机发现端口扫描 使用nmap扫描网段类存活主机 因为靶机是我最后添加的&#xff0c;所以靶机IP是169 nmap -sP 192.168.75.0/24 Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-10-29 13:16 CST …

TVM前端研究--Relay

文章目录 深度学习IR梳理1. IR属性2. DL前端发展3. DL编译器4. DL编程语言Relay的主要内容一、Expression in Relay1. Dataflow and Control Fragments2. 变量3. 函数3.1 闭包3.2 多态和类型关系3.3. Call4. 算子5. ADT Constructors6. Moudle和Global Function7. 常量和元组8.…

Ubuntu UFW防火墙规则与命令示例大全

在服务器安全领域&#xff0c;防火墙是守护网络安全的坚实盾牌。UFW&#xff08;Uncomplicated Firewall&#xff09;&#xff0c;即“不复杂的防火墙”&#xff0c;是一个运行在iptables之上的防火墙配置工具&#xff0c;它为Ubuntu系统默认提供了一个简洁的命令行界面&#x…

Linux高阶——1026—验证内存映射mmap函数使用

1、验证共享映射后修改文件内容&#xff0c;是否能够同步 先创建一个映射文件&#xff0c;写入数据 分为四个步骤 1、打开映射文件 设文件描述符&#xff0c;使用open函数 int fd; if((fdopen("mapfile",O_RDWR))-1) { perror("open failed");exit…

从零开始的 vue项目部署到服务器详细步骤(vue项目build打包+nginx部署+配置ssl证书)

从零开始的 vue项目部署到服务器详细步骤&#xff08;vue项目build打包nginx部署配置ssl证书&#xff09; 文章目录 从零开始的 vue项目部署到服务器详细步骤&#xff08;vue项目build打包nginx部署配置ssl证书&#xff09;一、前言二、vue项目部署前配置1、vite.config.js 增加…

快速遍历包含合并单元格的Word表格

Word中的合并表格如下&#xff0c;现在需要根据子类&#xff08;例如&#xff1a;果汁&#xff09;查找对应的品类&#xff0c;如果这是Excel表格&#xff0c;那么即使包含合并单元格&#xff0c;也很容易处理&#xff0c;但是使用Word VBA进行查找&#xff0c;就需要一些技巧。…

智慧园区 | 数智引领,让智慧触手可及

随着科技的飞速发展&#xff0c;智慧园区正成为现代城市发展的重要方向之一。在智慧园区中&#xff0c;各种高科技手段被应用于园区的管理和服务&#xff0c;为园区的运营和居民的生活带来无限可能。 智慧园区管理平台是智慧园区建设的核心。它集聚了大数据、物联网、云计算等技…

基于uniapp微信小程序的旅游系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏&#xff1a;…

【分布式知识】分布式对象存储组件-Minio

文章目录 什么是minio核心特点&#xff1a;使用场景&#xff1a;开发者工具&#xff1a;社区和支持&#xff1a; 核心概念什么是对象存储&#xff1f;MinIO 如何确定对对象的访问权限&#xff1f;我可以在存储桶内按文件夹结构组织对象吗&#xff1f;如何备份和恢复 MinIO 上的…

iQOO手机怎样将屏幕投射到MacBook?可以同步音频吗?

众所周知&#xff0c;苹果品牌的设备自己有AirPlay的投屏功能&#xff0c;iPhone要投屏到MacBook只要连接同一网络&#xff0c;然后开启AirPlay就可以投屏。但其他品牌的手机没有AirPlay&#xff0c;怎么将手机屏幕投射到MacBook呢&#xff1f; 安卓系统的手机可以使用无线投屏…

2. 从服务器的主接口入手

Webserver 的主函数 main.cpp&#xff0c;完成了哪些功能&#xff1f; #include "config.h"int main(int argc, char *argv[]) {string user "";string passwd "";string databasename "";Config config;config.parse_arg(argc, a…

四、Prompt工程——简单应用

Prompt工程——简单应用 一、提示工程&#xff08;Prompt Engineering&#xff09;二、Prompt基本法则三、Prompt 调优四、简单的例子文本总结文本判断文本提取文本转化——翻译文本转化——语气 更多结语 一、提示工程&#xff08;Prompt Engineering&#xff09; 提示工程也…

5G RedCap工业路由器赋能电力物联网应用

随着5G轻量化技术应用的推进&#xff0c;5G RedCap旨在提供低功耗、低成本、广覆盖等功能特点赋能电力智能化升级。特别适用于工业物联网、低空经济、车联网、消费电子和轻量级5G的需求。 5G RedCap工业路由器的特点 低功耗&#xff1a;5G RedCap工业路由器通过节能技术&#…