Python Web 开发:使用 FastAPI 进行依赖注入与异常处理

Python Web 开发:使用 FastAPI 进行依赖注入与异常处理

目录

  1. 🛠️ 依赖注入与 FastAPI 高级特性
  2. ⚠️ 自定义异常类的实现与应用
  3. 🚨 使用 HTTPException 处理常见错误
  4. 🌍 全局异常处理器的设计与实现
  5. ⚙️ 异常处理与 API 响应的整合

1. 🛠️ 依赖注入与 FastAPI 高级特性

FastAPI 提供了非常强大的依赖注入机制,可以帮助开发者简化代码结构,使得应用更加清晰、可维护和易于扩展。依赖注入是一种设计模式,它使得组件之间的依赖关系得以解耦,尤其适用于大型应用程序。在 FastAPI 中,依赖注入不仅可以注入数据库连接、配置文件、服务类等,还能够注入复杂的业务逻辑处理层。

依赖注入的基础

在 FastAPI 中,依赖注入机制是通过 Depends 类来实现的。开发者只需要将需要依赖的组件作为参数传递给函数,FastAPI 会自动解析并将依赖项注入函数中。这种方式使得代码的模块化程度大大提高,也让代码更加简洁和可测试。

from fastapi import FastAPI, Dependsapp = FastAPI()# 定义一个简单的依赖项
def get_db():db = "数据库连接"return db# 依赖注入到路径操作函数中
@app.get("/items/")
async def read_items(db: str = Depends(get_db)):return {"message": f"使用的数据库是:{db}"}

在上面的例子中,get_db() 函数返回一个“数据库连接”字符串,并通过 Depends(get_db) 注入到 read_items() 路由函数的参数中。FastAPI 会自动识别并调用 get_db(),将返回值传递给 db 参数。

依赖注入的优势

依赖注入提供了许多好处,尤其是在项目的可维护性和可扩展性方面。以下是几种常见的优势:

  1. 解耦和模块化:各个模块之间的依赖关系通过注入来管理,而不是硬编码在代码中,降低了模块间的耦合度。
  2. 代码清晰度:通过明确声明依赖项,代码变得更加清晰,易于理解和维护。
  3. 更容易进行单元测试:由于各个部分的依赖被解耦,因此可以通过模拟 (Mock) 或替换依赖项来更容易地进行单元测试。
  4. 复用性:开发者可以更容易地复用依赖项,无需重复创建新的实例或进行配置。
动态依赖注入

FastAPI 还支持动态依赖注入,这使得开发者可以根据不同的情况动态地决定依赖项。例如,可以根据用户角色注入不同的数据库连接、配置或服务。

from fastapi import FastAPI, Depends, HTTPException
from typing import Optionalapp = FastAPI()# 模拟根据不同角色返回不同数据库连接
def get_db(role: Optional[str] = None):if role == "admin":return "管理员数据库连接"elif role == "user":return "普通用户数据库连接"else:raise HTTPException(status_code=400, detail="无效角色")@app.get("/items/")
async def read_items(db: str = Depends(get_db)):return {"message": f"当前使用的数据库连接是:{db}"}

这种动态注入方式在复杂的系统中非常有用,能够根据业务逻辑需要选择不同的依赖项。

2. ⚠️ 自定义异常类的实现与应用

在 Web 开发中,处理错误和异常是至关重要的一部分。FastAPI 提供了许多内建的异常处理机制,但对于一些特定业务场景,开发者往往需要自定义异常类。自定义异常类能够让我们更好地管理错误代码、错误消息,并且使 API 的错误信息更加语义化。

自定义异常类的实现

自定义异常类通常是通过继承 Exception 类来创建,并根据业务需要添加错误代码、消息或更多详细信息。以下是一个简单的自定义异常类实现的例子:

class ItemNotFoundError(Exception):def __init__(self, item_id: int):self.item_id = item_idself.message = f"项目 {item_id} 未找到"super().__init__(self.message)

在上述代码中,ItemNotFoundError 是一个自定义的异常类,继承了 Exception。该异常类具有一个初始化方法,用于接收 item_id 参数并构造错误信息。

使用自定义异常

在 FastAPI 中,异常可以通过 HTTPException 或通过自定义的异常类抛出。通过 Depends 注入依赖项,我们可以在路由函数中触发自定义异常。例如:

from fastapi import FastAPI, HTTPException, Dependsapp = FastAPI()# 假设这是数据库查询操作
def get_item(item_id: int):if item_id != 123:raise ItemNotFoundError(item_id)return {"item_id": item_id, "name": "商品名称"}@app.get("/items/{item_id}")
async def read_item(item_id: int, item: dict = Depends(get_item)):return item

在上面的代码中,get_item 函数尝试查找指定 item_id 的项目,如果没有找到该项目,抛出 ItemNotFoundError 异常。FastAPI 会自动捕捉到这个异常并返回合适的错误信息。

异常类的扩展

自定义异常类不仅仅可以添加错误信息,还可以增加 HTTP 状态码、错误码等,以便更好地进行错误分类和处理。例如:

class ItemNotFoundError(HTTPException):def __init__(self, item_id: int):self.item_id = item_idself.status_code = 404self.detail = f"项目 {item_id} 未找到"super().__init__(status_code=self.status_code, detail=self.detail)

这种做法使得自定义的异常类可以直接作为 HTTPException 使用,FastAPI 会自动将其作为 HTTP 响应返回。

3. 🚨 使用 HTTPException 处理常见错误

FastAPI 内置了许多常用的 HTTP 错误状态码和异常处理类,其中 HTTPException 是最常用的异常类。它允许开发者通过设置状态码、错误信息等来抛出 HTTP 错误,进而在 API 响应中提供友好的错误提示。

使用 HTTPException

HTTPException 是一个简单的异常类,可以用来返回 HTTP 错误。它接受 status_codedetail 两个参数,分别表示 HTTP 状态码和错误信息。以下是一个简单的示例:

from fastapi import FastAPI, HTTPExceptionapp = FastAPI()@app.get("/items/{item_id}")
async def read_item(item_id: int):if item_id != 123:raise HTTPException(status_code=404, detail="项目未找到")return {"item_id": item_id, "name": "商品名称"}

在上面的代码中,当 item_id 不为 123 时,FastAPI 会抛出 HTTPException,返回 404 状态码并显示错误信息“项目未找到”。

错误处理与自定义响应

在实际开发中,错误的处理往往需要根据业务场景进行定制化,比如添加更多的错误细节信息或返回不同格式的响应。例如,除了返回标准的 JSON 错误响应外,还可以添加额外的字段,帮助前端更好地理解错误。

from fastapi import FastAPI, HTTPException
from fastapi.responses import JSONResponse@app.exception_handler(HTTPException)
async def custom_http_exception_handler(request, exc: HTTPException):return JSONResponse(status_code=exc.status_code,content={"error": exc.detail,"request_url": str(request.url),},)

在上面的代码中,我们定义了一个全局异常处理器,它会在遇到 HTTPException 异常时,返回自定义的 JSON 响应格式,并附加请求的 URL 作为调试信息。

4. 🌍 全局异常处理器的设计与实现

FastAPI 允许开发者通过全局异常处理器来捕获和处理应用中的所有异常。通过这种方式,开发者可以集中管理所有错误响应逻辑,而不需要在每个路由中单独处理异常。这使得应用的异常管理变得更加统一和高效。

定义全局异常处理器

FastAPI 通过 @app.exception_handler 装饰器提供了全局异常处理的功能。开发者可以为不同类型的

异常定义专门的处理函数,下面是一个处理所有未捕获异常的例子:

from fastapi import FastAPI, HTTPException
from fastapi.responses import JSONResponseapp = FastAPI()@app.exception_handler(Exception)
async def global_exception_handler(request, exc: Exception):return JSONResponse(status_code=500,content={"message": "服务器发生了未知错误","detail": str(exc),},)

在上面的代码中,我们定义了一个全局异常处理器,它会捕获所有未处理的异常,并返回一个统一的 500 错误响应。响应中包含了错误的详细信息以及“服务器发生了未知错误”的提示。

捕获特定异常

除了捕获所有异常,开发者还可以为特定的异常类型定义专门的处理函数。例如,当捕获 HTTPException 时,我们希望返回更加详细的错误信息和建议。如下所示:

@app.exception_handler(HTTPException)
async def custom_http_exception_handler(request, exc: HTTPException):return JSONResponse(status_code=exc.status_code,content={"error": exc.detail,"advice": "请检查请求参数或尝试稍后重试。",},)

这种做法能够让错误响应更加用户友好,并提供一些建议,帮助客户端更容易地解决问题。

5. ⚙️ 异常处理与 API 响应的整合

在实际的 API 开发中,错误处理不仅仅是返回一个错误状态码和消息那么简单。开发者往往需要将错误处理与 API 响应的整体设计相结合,以确保前端能够准确地解析和显示错误信息。FastAPI 提供了一些灵活的机制,能够帮助开发者实现这一点。

设计一致的错误响应格式

为了让前端更加方便地处理错误信息,通常需要设计一种统一的错误响应格式。这可以通过全局异常处理器和自定义异常类来实现。

from fastapi import FastAPI, HTTPException
from fastapi.responses import JSONResponseapp = FastAPI()@app.exception_handler(HTTPException)
async def custom_http_exception_handler(request, exc: HTTPException):return JSONResponse(status_code=exc.status_code,content={"status": "error","error_code": exc.status_code,"message": exc.detail,},)

这种格式化的错误响应使得前端可以快速定位错误信息,并根据 error_code 进行相应的处理。

错误日志记录

除了返回错误信息外,错误日志记录也是异常处理中重要的一部分。通过将错误信息记录到日志中,开发者可以追踪应用的异常并分析问题根源。FastAPI 可以与 Python 标准库的 logging 模块集成,以便记录错误日志。

import logging
from fastapi import FastAPI, HTTPException
from fastapi.responses import JSONResponse# 配置日志记录
logging.basicConfig(level=logging.ERROR)
logger = logging.getLogger(__name__)app = FastAPI()@app.exception_handler(HTTPException)
async def custom_http_exception_handler(request, exc: HTTPException):logger.error(f"发生错误: {exc.detail}, URL: {request.url}")return JSONResponse(status_code=exc.status_code,content={"status": "error","error_code": exc.status_code,"message": exc.detail,},)

通过记录日志,开发者可以在后台查看详细的错误信息和请求 URL,从而更容易定位问题并进行修复。

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

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

相关文章

LabVIEW气缸摩擦力测试系统

基于LabVIEW的气缸摩擦力测试系统实现了气缸在不同工作状态下摩擦力的快速、准确测试。系统由硬件平台和软件两大部分组成,具有高自动化、精确测量和用户友好等特点,可广泛应用于精密机械和自动化领域。 ​ 项目背景: 气缸作为舵机关键部件…

CentOS7.X 安装RustDesk自建服务器实现远程桌面控制

参照文章CentOS安装RustDesk自建服务器中间总有几个位置出错,经实践做个记录防止遗忘 一 环境&工具准备 1.1 阿里云轻量服务器、Centos7系统、目前最高1.1.11版本rustdesk-server-linux-amd64.zip 1.2 阿里云轻量服务器–安全组–开放端口:TCP(21…

工具篇:IDEA VFS 损害启动报错 com.intellij.util.io.CorruptedException 处理

文章目录 前言一、 idea 的 VFS是什么?二、解决方式:2.1 退出Idea 然后重新打开:2.2 手动清除Idea 缓存,让Idea 重新建立缓存:2.2.1 打开 Invalidate Caches / Restart 对话框:2.2.2 勾选要清除的缓存: 总结…

2.linux中调度kettle

一.准备转换,等会在linux中用 1.添加excel输入组件,并添加对应的文件 2.添加列拆分为多行组件 3.添加文本文件输出组件 4.保存转换 二.linux安装java 1.把jdk-8u144-linux-x64.tar.gz上传到linux的/lx目录下 2. 解压jdk包,然后配置环境变量…

第四节、电机定角度转动【51单片机-TB6600驱动器-步进电机教程】

摘要:本节介绍用电机转动角度计算步骤,从而控制步进电机转角 一、 计算过程 1.1 驱动器接收一个脉冲后,步进电机转动一步,根据驱动器设置的细分值 计算一个脉冲对应电机转动的角度step_x s t e p x s t e p X … … ① step_{x…

如何终身使用 100% 免费的服务器

作为开发人员,我们需要在云服务上运行和托管后端。有许多 BaaS(后端即服务)可用,但它们有一些限制。 如果我说我已经免费使用基于 Linux 的服务器超过 4-5 年了,那会怎样?是的,你没听错。我正在使用这台安装了 Ubuntu 20、24 GB RAM、4 个 CPU 和 200 GB 存储空间的 Lin…

【计算机组成原理】期末复习题库

5.主存储器和CPU之间增加cache的目的是 。 A.解决CPU和主存之间的速度匹配问题 B.扩大主存储器的容量 C.扩大CPU中通用寄存器的数量 D.既扩大主存容量又扩大CPU中通用寄存器的数量 在计算机系统中,CPU的速…

SAP中Smartforms 翻译越南语

点击打印预览 打印预览中确实是越南语 转出成PDF 成了乱码 SPAD中查询LP01其实是简体中文 换成LP02试试 显示看上去正常的 SPAD中的LP02 SU3可以设置自己的默认打印参数 查查Smartforms中的字体样式 是宋体,看上去不用为了越南文刻意改字体样式成TIMES 看这篇文章…

26.删除有序数组中的重复项 python

删除有序数组中的重复项 题目题目描述示例 1:示例 2:提示:题目链接 题解解题思路python实现代码解释提交结果 题目 题目描述 给你一个 非严格递增排列 的数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现…

R语言 | 峰峦图 / 山脊图

目的:为展示不同数据分布的差异。 1. ggplot2 实现 # 准备数据 datmtcars[, c("mpg", "cyl")] colnames(dat)c("value", "type") head(dat) # value type #Mazda RX4 21.0 6 #Mazda RX4 Wag …

四川创新志成健康管理有限公司

四川创新志成健康管理有限公司 成都市青羊区广富路168号 公司简介 四川创新志成健康管理有限公司成立于2021年,公司专注体外诊断领域,致力为医学实验室、生产厂家、 经销商提供专业的学术、技术增值服务,涵盖免疫、生化、输血等检测领域&a…

系统级 I/O

Unix I/O **了解 Unix I/O 将帮助你理解其他的系统概念。**I/O 是系统操作不可或缺的一部分。我们经常遇到 I/O 和其他系统概念之间的循环依赖。例如,I/O 在进程的创建和执行中扮演着关键的角色。反过来,进程创建又在不同进程间的文件共享中扮演着关键角…

Elasticsearch:使用阿里 infererence API 及 semantic text 进行向量搜索

在之前的文章 “Elasticsearch 开放推理 API 新增阿里云 AI 搜索支持”,它详细描述了如何使用 Elastic inference API 来针对阿里的密集向量模型,稀疏向量模型, 重新排名及 completion 进行展示。在那篇文章里,它使用了很多的英文…

基于公网的无线全双工内部通话系统在演出行业可以用吗?

文旅名城再出发,更待“烟花”绽繁花 2024年4月将开业的扬州首个大型沉浸式剧场-《运河密城》 以运河为原点 追随河的记忆 从春秋时代的吴王夫差 到贯通南北的大运河成形 穿梭时空 探索扬州的前世今生 「运河第一锹」古运河旁 有一处新地标正在悄然兴起 如…

POSTGRESQL跟ORACLE语法区别和相同之处

跟ORACLE语法区别之处 1. Update和delete语法区别 Pg 和MySQL Update和delete的时候表名不能加别名 2. 插入数字类型不一样 ORACLE 对number类型的数据可以用’’ 字符串标记插入,但是PG不行,必须要进行正确的数据类型 3. SEQ使用不同 ORACEL的SEQ…

C++编程物联网:舵机VS步进电机

舵机和步进电机都是常见的电机类型,它们在自动化和机器人控制中有着不同的应用场景。两者的主要区别在于控制方式、运动精度、适用范围等方面。下面详细介绍它们的作用、应用场景和主要区别。 1. 舵机(Servo Motor) 工作原理 舵机是一种具有反馈控制的电动机,通常由电动…

鸿翼参与撰写档案数据管理与长期保存策略基于数字中国战略的研究

​编者按:近日,由中国财富出版社有限公司出版的《档案数据管理与长期保存策略——基于数字中国战略的研究》正式发行,上海鸿翼软件技术股份有限公司董事长兼CEO龙凌云作为核心作者参与主要编写工作。 本书是在国家档案局立项科研项目“数字档…

机器学习中的图匹配问题—基础学习

机器学习中的图匹配问题 结合导师所给的方向,能否将实例之间的点匹配问题转换为点到实例之间的匹配问题来进行求解呢?这里结合师姐推荐的讲座首先对图匹配的这个方向来进行简单的了解和接触。 图匹配问题概述 图匹配就是:不仅考虑点之间的配…

2024.11.29——[HCTF 2018]WarmUp 1

拿到题&#xff0c;发现是一张图&#xff0c;查看源代码发现了被注释掉的提示 <!-- source.php--> step 1 在url传参看看这个文件&#xff0c;发现了这道题的源码 step 2 开始审计代码&#xff0c;分析关键函数 //mb_strpos($haystack,$needle,$offset,$encoding):int|…

gRPC 快速入门 — SpringBoot 实现(1)

目录 一、什么是 RPC 框架 &#xff1f; 二、什么是 gRPC 框架 &#xff1f; 三、传统 RPC 与 gRPC 对比 四、gRPC 的优势和适用场景 五、gRPC 在分布式系统中应用场景 六、什么是 Protocol Buffers&#xff08;ProtoBuf&#xff09;&#xff1f; 特点 使用场景 简单的…