FastAPI 依赖注入

依赖注入常用于以下场景:

  • 共享业务逻辑(复用相同的代码逻辑)

  • 共享数据库连接

  • 实现安全、验证、角色权限

  • 等……

上述场景均可以使用依赖注入,将代码重复最小化。

创建依赖项

依赖项就是一个函数,且可以使用与路径操作函数相同的参数,依赖项函数的形式和结构与路径操作函数一样。因此,可以把依赖项当作没有「装饰器」(即,没有 @app.get("/some-path") )的路径操作函数。

from typing import Unionimport uvicorn
from fastapi import FastAPI, Dependsapp = FastAPI()# 依赖的组件函数
async def common_parameters(q: Union[str, None] = None,skip: int = 0,limit: int = 100,
):return {"skip": skip, "limit": limit, "q": q}@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 commonsif __name__ == '__main__':uvicorn.run(app)

实现过程:

1、导入 Depends

from fastapi import Depends

2、定义依赖的组件函数

# 依赖的组件函数
async def common_parameters(q: Union[str, None] = None,skip: int = 0,limit: int = 100,
):return {"skip": skip, "limit": limit, "q": q}

3、声明依赖项

声明依赖项需要使用 Depends 和一个新的参数:

async def read_items(commons: dict = Depends(common_parameters)):

其他与「依赖注入」概念相同的术语为:

  • 资源(Resource)

  • 提供方(Provider)

  • 服务(Service)

  • 可注入(Injectable)

  • 组件(Component)

依赖注入系统如此简洁的特性,让 FastAPI 可以与下列系统兼容:

  • 关系型数据库

  • NoSQL 数据库

  • 外部支持库

  • 外部 API

  • 认证和鉴权系统

  • API 使用监控系统

  • 响应数据注入系统

  • 等等……

类作为依赖项

依赖项时一个可调用的对象,Python 中的 "可调用对象" 是指任何 Python 可以像函数一样 "调用" 的对象。Python 类也是 可调用对象。因此,在 FastAPI 中,你可以使用一个 Python 类作为一个依赖项。

实际上 FastAPI 检查的是它是一个 "可调用对象"(函数,类或其他任何类型)以及定义的参数。

import uvicorn
from fastapi import FastAPI, Dependsapp = FastAPI()fake_items_db = [{"item_name": "Foo"}, {"item_name": "Bar"}, {"item_name": "Baz"}]class CommonQueryParams:def __init__(self, q: str | None = None, skip: int = 0, limit: int = 100):self.q = qself.skip = skipself.limit = limit# FastAPI 调用 CommonQueryParams 类。这将创建该类的一个 "实例",该实例将作为参数 commons 被传递给你的函数。
@app.get("/items/")
async def read_items(commons: CommonQueryParams = Depends(CommonQueryParams)):response = {}if commons.q:response.update({"q": commons.q})items = fake_items_db[commons.skip: commons.skip + commons.limit]response.update({"items": items})return responseif __name__ == '__main__':uvicorn.run(app, host="127.0.0.1", port=8000)

FastAPI 为这些情况提供了一个快捷方式,在这些情况下,依赖项 明确地 是一个类,FastAPI 将 "调用" 它来创建类本身的一个实例。

快捷写法

commons: CommonQueryParams = Depends()

分层依赖注入

假设是用户管理模块,创建如下的目录结构以及python文件:

schemas/user_schema.py

from pydantic import BaseModel, Field
from datetime import datetimeclass User(BaseModel):id: int | None = Field(description="主键ID")username: str | None = Field(description="用户名")age: int | None = Field(description="年龄")is_vip: int | None = Field(description="是否会员 0-不是,1-是")create_time: datetime = Field(description="创建时间")

dao/user_dao.py

from datetime import datetime
from user.schemas.user_schema import Userclass UserDAO:"""数据层"""def __init__(self):passdef get_user_by_username(self, username)-> User:"""根据用户名查询用户信息:param username::return:"""user = User(id=1, username="alice", age=25, is_vip=0, create_time=datetime.now())return user

service/user_service.py

from fastapi import Dependsfrom user.dao.user_dao import UserDAO
from user.schemas.user_schema import Userclass UserService:"""业务逻辑处理层"""def __init__(self, user_dao: UserDAO = Depends()):self.user_dao = user_daodef find_by_username(self, username: str)-> User:"""根据用户名查询用户信息:param username::return:"""return self.user_dao.get_user_by_username(username)

routers/user_routers.py

from fastapi import APIRouter, Dependsfrom commons.result import Result
from user.exceptions.user_exception import UserNotFoundException
from user.service.user_serivce import UserServiceusers = APIRouter()@users.get(path="/find/{username}", summary="根据用户名查询用户", response_model=Result)
async def find_user_by_username(username: str, user_service: UserService = Depends()):user = user_service.find_by_username(username)# 用户不存在if user is None:raise UserNotFoundExceptionresult = Result()result.data = userreturn result

commoms/result.py

from typing import Anyfrom pydantic import BaseModel, Fieldclass Result(BaseModel):code: int = Field(description="响应状态码", default=200)message: str = Field(description="响应结果信息", default="成功")data: Any = Field(description="响应结果数据", default=None)

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

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

相关文章

接口幂等性原理与方案总结

文章目录 接口幂等概念典型场景核心解决方案一锁二判三更新 方案选型对比 接口幂等概念 定义:无论调用接口多少次,对系统的影响与单次调用一样 范畴:在后端开发中,通常更关注写接口的幂等,因为写接口才会对系统数据造…

【已解决】windows gitbash 出现CondaError: Run ‘conda init‘ before ‘conda activate‘

在 Git Bash 中执行: source /c/Users/你的用户名/miniconda3/etc/profile.d/conda.sh # 注意填入你自己的路径 conda init bash关闭并重新打开 Git Bash 终端。测试激活环境: conda activate your_env_name注意事项 要把上述命令中的 你的用户名 替…

软件包管理系统的架构与生态机制

文章目录 前言一、总结二、如何上传自己的软件包 前言 在日常软件开发中,我们经常使用诸如apt install, pip install, npm install之类的命令,但有一个问题是,这些下载命令是从哪里下载的这些软件包,以及我们是否能上传自己的代码…

Java线程池管理最佳实践(设计模式)

引言 在多线程编程中,线程池是一种非常重要的资源管理工具。合理使用线程池可以显著提高系统性能,避免频繁创建和销毁线程带来的开销。今天,我将为大家深入分析一个实用的ThreadPoolManager实现,它来自com.kingdee.eas.util包&am…

4.8.2 利用Spark SQL计算总分与平均分

在本次实战中,我们的目标是利用Spark SQL计算学生的总分与平均分。首先,我们准备了包含学生成绩的数据文件,并将其上传至HDFS。接着,通过Spark的交互式编程环境,我们读取了成绩文件并将其转换为结构化的DataFrame。然后…

HTML 文件路径完全指南:相对路径、绝对路径解析与引用技巧

一、为什么必须学会文件路径?—— 网页引用资源的 “地址规则” 在 HTML 中,引用图片、CSS、JS 等外部文件时,必须通过文件路径告诉浏览器资源的位置。路径错误会导致资源无法加载(页面出现 broken image 图标或样式丢失&#xf…

keepalived两台设备同时出现VIP问题

目录 问题背景: 日志分析如下: 原因和解决方案总结: 问题背景: keepalived-master和keepalived-slave同时出现了VIP,出现了非对称路由和双主现象 日志分析如下: master能够接受到来自slave的通告消息…

【开源解析】基于PyQt5+Folium的谷歌地图应用开发:从入门到实战

🌐【开源解析】基于PyQt5Folium的谷歌地图应用开发:从入门到实战 🌈 个人主页:创客白泽 - CSDN博客 🔥 系列专栏:🐍《Python开源项目实战》 💡 热爱不止于代码,热情源自每…

篇章五 数据结构——链表(一)

目录 1.ArrayList的缺陷 2. 链表 2.1 链表的概念及结构 2.2 链表结构 1. 单向或者双向 2.带头或者不带头 3.循环或者非循环 2.3 链表的实现 1.完整代码 2.图解 3.显示方法 4.链表大小 5. 链表是否存在 key 值 6.头插法 7.尾插法 8.中间插入 9.删除key值节点 10.…

数据库相关面试

数据库相关面试 Mysql MySQL中的事务隔离级别及其特点 参考:事务的隔离级别:可重复读 未提交读(Read Uncommitted):允许脏读,也就是可能读取到其他会话中未提交事务修改的数据 已提交读(Read Committed):只能读取到…

基于Scrapy的天猫商品数据爬取与分析实战(含API签名破解与可视化)

基于Scrapy的天猫商品数据爬取与分析实战(含API签名破解与可视化) 本文以华为Mate 60 Pro为例,详细介绍如何使用Scrapy框架爬取天猫商品数据,涵盖API签名破解、反爬应对、数据存储及可视化全流程,适合爬虫进阶学习者实…

【C++进阶篇】哈希表的模拟实现(赋源码)

这里写目录标题 前言一. 开放地址法实现哈希表1.1 闭散列结构定义1.2 构造函数1.3 插入(线性探测)1.3.1 传统写法1.3.2 现代写法 1.4 查找1.5 删除 二. 链地址法实现哈希表(哈希桶)2.1 开散列结构定义2.2 构造函数2.3 插入2.4 查找…

07-后端Web实战(部门管理)

5. 修改部门 对于任何业务的修改功能来说,一般都会分为两步进行:查询回显、修改数据。 5.1 查询回显 5.1.1 需求 当我们点击 "编辑" 的时候,需要根据ID查询部门数据,然后用于页面回显展示。 5.1.2 接口描述 参照参照…

深度解析项目集方向或目标根本性转变的应对策略 —— 项目集管理实战指南

在复杂多变的商业环境中,项目集管理面临着重重挑战,而项目集方向或目标的根本性转变无疑是其中最具冲击力的问题之一。本文将深度剖析这一难题,为项目集管理从业者提供实用、新颖且富有价值的应对策略,助力大家在项目集管理的复杂…

JAVA面试复习知识点

面试中遇到的题目,记录复习(持续更新) Java基础 1.String的最大长度 https://www.cnblogs.com/wupeixuan/p/12187756.html 2.集合 Collection接口的实现: List接口:ArraryList、LinkedList、Vector Set接口&#xff1a…

【烧脑算法】定长滑动窗口:算法题中的“窗口”智慧

目录 引言 定长滑动窗口习题剖析 3439. 重新安排会议得到最多空余时间 I 2134. 最少交换次数来组合所有的 1 II 1297. 子串的最大出现次数 2653. 滑动子数组的美丽值 567. 字符串的排列 438. 找到字符串中所有字母异位词 30. 串联所有单词的子串 220. 存在重复元素 II…

JWT安全:接收无签名令牌.【签名算法设置为none绕过验证】

JWT安全:假密钥【签名随便写实现越权绕过.】 JSON Web 令牌 (JWT)是一种在系统之间发送加密签名 JSON 数据的标准化格式。理论上,它们可以包含任何类型的数据,但最常用于在身份验证、会话处理和访问控制机制中发送有关用户的信息(“声明”)。…

XGBoost与SHAP深度解析:从算法原理到实战价值

在机器学习领域,XGBoost以其卓越的性能长期占据Kaggle竞赛和工业界的主流地位,而SHAP(SHapley Additive exPlanations)则成为模型可解释性的标杆工具。本文将深度解析两者的技术内核,并通过实战案例揭示其结合应用的实…

Java SE Cloneable接口和深/浅拷贝

Java为我们提供了各种各样功能的接口,Clonable接口就是其中之一。 它通常配合Object类的 clone方法使用。这个方法可以为我们创建一个对象的拷贝,即复制一个对象。在进入本文的主要内容之前,先来对访问限定符 protected进行一个解剖。 1.再…

Python学习(3) ----- Python的函数定义及其使用

Python 中函数是组织好的、可重复使用的代码块,用于实现单一或相关联的功能。下面是函数定义和使用的完整说明: 📌 一、函数定义语法 def 函数名(参数1, 参数2默认值, *args, **kwargs):"""函数说明文档"""函…