资源管理新视角:利用 FastAPI Lifespan 事件优化你的应用II

本文说明在 FastAPI 应用程序中使用 lifespan 事件来管理资源的加载和卸载。lifespan 事件允许你在应用启动时执行一些初始化代码,并在应用关闭时执行一些清理代码。这是通过使用异步上下文管理器实现的,具体来说,是通过 asynccontextmanager 装饰器创建一个异步生成器函数。
在这里插入图片描述

# 导入asynccontextmanager用于创建异步上下文管理器
from contextlib import asynccontextmanager
# 导入FastAPI,用于创建和管理Web应用
from fastapi import FastAPI

# 定义一个模拟的机器学习模型函数,它接受一个浮点数x并返回x乘以42的结果
def fake_answer_to_everything_ml_model(x: float):
    return x * 42

# 创建一个空字典,用于存储机器学习模型
ml_models = {}

# 使用asynccontextmanager装饰器定义一个异步上下文管理器函数lifespan
@asynccontextmanager
async def lifespan(app: FastAPI):
    # 在异步上下文管理器中,"进入上下文"时加载机器学习模型
    ml_models["answer_to_everything"] = fake_answer_to_everything_ml_model
    # yield
    yield
    # 在异步上下文管理器中,"退出上下文"时清理机器学习模型,释放资源
    ml_models.clear()

# 创建FastAPI应用实例,并将lifespan函数作为其生命周期管理器
app = FastAPI(lifespan=lifespan)

# 定义一个GET请求路由,用于处理预测请求
@app.get("/predict")
async def predict(x: float):
    # 从ml_models字典中获取模型,并使用它对输入值x进行预测
    result = ml_models["answer_to_everything"](x)
    # 返回预测结果
    return {"result": result}

在这段代码中,lifespan 函数作为异步上下文管理器,负责在FastAPI应用启动时加载机器学习模型,并在应用关闭时清理模型。这样的设计模式确保了应用在运行时能够有效地管理资源。predict 路由函数提供了一个接口,允许用户通过HTTP请求发送数据,并获取模型的预测结果。

代码解释:

  1. 导入必要的库:asynccontextmanager 用于创建异步上下文管理器,FastAPI 是 FastAPI 框架的核心类。

  2. 定义一个模拟的机器学习模型函数 fake_answer_to_everything_ml_model,它接受一个浮点数 x 并返回 x * 42

  3. 创建一个全局字典 ml_models,用于存储机器学习模型。

  4. 使用 @asynccontextmanager 装饰器定义一个异步上下文管理器 lifespan,它接受一个 FastAPI 实例作为参数。

  5. lifespan 函数中,使用 yield 语句之前的代码块来加载模型。在这个例子中,模型加载操作被模拟为将模型函数添加到 ml_models 字典中。

  6. yield 语句之后的代码块用于在应用关闭时执行清理操作,这里它清除了 ml_models 字典。

  7. 创建一个 FastAPI 实例,并将其 lifespan 参数设置为 lifespan 函数。

  8. 定义一个路由处理函数 predict,它使用加载的模型来处理预测请求,并返回结果。

实际作用:

  • 在应用启动时,lifespan 函数中的代码在 yield 之前被执行,模拟加载模型的操作。
  • 应用开始接收请求后,predict 路由可以被调用,使用已加载的模型来处理请求。
  • 当应用关闭时,lifespan 函数中的代码在 yield 之后被执行,进行资源的清理。

在 Python 的异步上下文管理器中,yield 关键字扮演着非常重要的角色。它用于定义上下文管理器的执行流程,特别是在异步上下文管理器(使用 asynccontextmanager 装饰的生成器函数)中。

理解 yield 在异步上下文管理器中的作用:

  1. 定义执行点:在异步上下文管理器中,yield 语句定义了异步生成器在执行时的暂停和恢复点。当进入上下文时,代码执行到 yield 语句,生成器会暂停,等待外部代码执行。一旦退出上下文,生成器会继续执行 yield 之后的代码。

  2. 上下文的分割yield 将上下文管理器的代码分为两部分:

    • 进入上下文yield 之前的代码,用于设置必要的资源或状态。在异步上下文管理器中,这通常包括资源的初始化和分配。
    • 退出上下文yield 之后的代码,用于清理资源或恢复状态。在异步上下文管理器中,这通常包括资源的释放和清理。

示例解释:

在你提供的代码中:

@asynccontextmanager
async def lifespan(app: FastAPI):
    # Load the ML model
    ml_models["answer_to_everything"] = fake_answer_to_everything_ml_model
    yield
    # Clean up the ML models and release the resources
    ml_models.clear()
  • 进入上下文:在 yield 之前的部分,ml_models 字典被用来存储一个模拟的机器学习模型。这模拟了在应用启动时加载模型的过程。
  • 退出上下文yield 之后的代码在上下文管理器退出时执行,这里它清除 ml_models 字典,模拟了在应用关闭时卸载模型和释放资源的过程。

异步上下文管理器的使用:

当使用 async with 语句块时,进入点是 async with 后面的代码块开始执行的地方,而退出点是该代码块执行完毕的地方。例如:

async with lifespan(app) as manager:
    # 这里可以访问和使用上下文中的资源
    pass

在这个 async with 块中,进入上下文的代码在 lifespan 函数被调用时执行,直到遇到 yieldyield 之后的代码在 async with 块的代码执行完毕后执行。yield 在异步上下文管理器中是一个关键的执行控制点,它定义了资源的生命周期,确保资源在使用前后都能得到妥善的处理。

简单的两个 Demo:

当然,以下是上述两个示例代码:

Demo 1:数据库连接

# 导入必要的库
from contextlib import asynccontextmanager
from fastapi import FastAPI
import asyncpg

# 定义数据库连接的URL
DATABASE_URL = "postgres://user:password@localhost/dbname"

# 使用asynccontextmanager装饰器定义一个异步上下文管理器
@asynccontextmanager
async def lifespan(app: FastAPI):
    # 异步连接数据库
    connection = await asyncpg.connect(DATABASE_URL)
    # 将数据库连接存储在app.state中,以便在应用中其他地方使用
    app.state.db = connection
    yield
    # 在上下文结束时关闭数据库连接
    await app.state.db.close()

# 创建FastAPI应用实例,并传入lifespan函数
app = FastAPI(lifespan=lifespan)

# 定义一个路由,用于获取数据库中的数据
@app.get("/get_data")
async def get_data():
    # 从app.state中获取数据库连接
    db = app.state.db
    # 执行SQL查询并返回结果
    return {"data": await db.fetch("SELECT * FROM my_table")}

Demo 2:启动时加载配置文件

# 导入必要的库
from contextlib import asynccontextmanager
from fastapi import FastAPI

# 创建一个空字典,用于存储配置信息
config = {}

# 使用asynccontextmanager装饰器定义一个异步上下文管理器
@asynccontextmanager
async def lifespan(app: FastAPI):
    # 模拟加载配置文件,这里只是简单地将一个配置项设置为一个值
    config['setting'] = 'some_value'
    # 将配置信息存储在app.state中,以便在应用中其他地方使用
    app.state.config = config
    yield
    # 在上下文结束时清理配置信息(如果有必要的话)
    config.clear()

# 创建FastAPI应用实例,并传入lifespan函数
app = FastAPI(lifespan=lifespan)

# 定义一个路由,用于获取当前的配置信息
@app.get("/get_config")
async def get_config():
    # 从app.state中返回配置信息
    return app.state.config

在这两个示例中,lifespan 函数作为一个异步上下文管理器,负责在应用启动时初始化资源(如数据库连接或配置信息),并在应用关闭时进行清理。这样的模式有助于确保资源被正确管理,防止资源泄露。

在这两个 Demo 中,第一个演示了如何在应用启动时建立数据库连接,并在应用关闭时关闭连接。第二个演示了如何在应用启动时加载配置,并在应用关闭时进行清理。这些操作都是在 lifespan 事件中管理的。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

什么是职场?职场的本质又是什么呢?

最近,经常看到很多职场相关的,比如职场必备技能、职场人际关系、职场晋升等等,这些都是职场的一些方面,但是却少有人来深入剖析什么是职场,职场的本质又是什么,今天我们就来一起来聊一聊,到底职…

音视频入门基础:AAC专题(5)——FFmpeg源码中,判断某文件是否为AAC裸流文件的实现

一、引言 通过FFmpeg命令: ./ffmpeg -i XXX.aac 可以判断出某个文件是否为AAC裸流文件: 所以FFmpeg是怎样判断出某个文件是否为AAC裸流文件呢?它内部其实是通过adts_aac_probe函数来判断的。从《FFmpeg源码:av_probe_input_for…

性能测试的复习3-jmeter的断言、参数化、提取器

一、断言、参数化、提取器 需求: 提取查天气获取城市名请求的响应结果:城市对查天气获取城市名的响应结果进行响应断言和json断言对查天气获取城市名添加用户参数 1、步骤 查看天气获取城市名 json提取器(对响应结果提取、另一个接口请求…

也许你该了解下,DeepSeek Coder这个国产目前最牛逼的编码大模型,或许你真的用得上

你是不是也有这样的困惑:代码写不出来、调不通、效率低下,明明花了几个小时,结果却一无所获?别担心,不光是你,我也曾经有过同样的苦恼。但今天我要和你聊的,是一个能够改变这种局面的新工具——DeepSeek Coder。这个工具有多厉害?它能帮你解决闭源代码难以获取的问题,…

复杂情感识别系统

复杂情感识别系统(CERS)是一种先进的技术平台,旨在通过分析情感的组合、相互关系及其动态变化来解读和识别复杂的情感状态。这种系统通常采用以下技术和方法: 机器学习与深度学习: 通过训练算法识别和解释大量情感数据…

Blender/3ds Max/C4D哪个软件好?

在3D建模和动画制作领域,Blender、3ds Max和Cinema 4D(C4D)都是备受赞誉的软件。每个软件都有其独特的优势和特点,选择哪个软件取决于用户的具体需求和个人偏好。今天,成都渲染101云渲染就来分析一些这三款软件的情况&…

Linux服务器配合Xshell+Tensorboard实现深度学习训练过程可视化

问题背景: 在深度学习领域,监控模型的训练过程是非常重要的。TensorBoard 是 TensorFlow 提供的一个可视化工具,可以帮助我们直观地理解模型的训练和验证过程。我们一般在 Windows 系统只需要在自己的浏览器输入localhost:6006就可以观察训练…

Java的发展史与前景

🌈个人主页:Yui_ 🌈Linux专栏:Linux 🌈C语言笔记专栏:C语言笔记 🌈数据结构专栏:数据结构 🌈C专栏:C 文章目录 0. Java语言的发展史1.概述1.1 什么是Java1.2 …

java项目之基于工程教育认证的计算机课程管理平台(源码+论文)

项目简介 基于工程教育认证的计算机课程管理平台的主要管理员可以管理教师,可以对教师信息修改删除以及查询操作;可以对通知公告信息进行添加,修改,删除以及查询操作;可以对学生信息进行添加,修改&#xf…

Oracle绑定变量窥视与自适应游标共享

一.Oracle的绑定变量窥视与自适应游标共享 创建test表,列status存在2个值,有数据倾斜,在列status create table test as select rownum id,DBMS_RANDOM.STRING(A,12) name,DECODE(MOD(ROWNUM,500),0,Inactive,Active) status from all_obj…

Rust Windows下编译 静态链接VCRuntime140.dll

Rust 编译出来的exe默认动态链接VC运行库,分发电脑上需要安装有Microsoft Visual C Redistributable for Visual Studio 2015运行库。 编译时能静态链接进去,就省去客户端未安装运行库的问题。方法如下: 只需在当前根目录下新建.cargo\config.toml&#…

【西电电装实习】6. 手装无人机的蓝牙断连debug

文章目录 前言零、闪灯状态零零、翻滚角,俯仰角,偏航角一、问题描述二、现象解释三、解决方案参考文献 前言 在 西电无人机电装实习 时遇到的问题使用蓝牙芯片 CH582F。沁恒的蓝牙芯片CH582F是一款集成了BLE(Bluetooth Low Energy&#xff0…

windows安装docker、elasticsearch、kibana、cerebro、logstash

文章目录 1. 安装docker1.1. 两大要点1.1.1. 安装启用hyper-v电脑不存在hyper-v的情况 1.1.2. 下载安装docker 2. 在docker里面安装elasticSearch,kibana,cerebro3. 安装logstash-将数据导入到elasticSearch3.1 安装logstash3.1.1 注意事项3.1.1.1. 等了…

[数据集][目标检测]高铁受电弓检测数据集VOC+YOLO格式1245张2类别

数据集格式:Pascal VOC格式YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数):1245 标注数量(xml文件个数):1245 标注数量(txt文件个数):1245 标注…

OrionX vGPU 研发测试场景下最佳实践之Jupyter模式

在上周的文章中,我们讲述了OrionX vGPU研发测试场景下最佳实践之SSH模式,今天,让我们走进 Jupyter模式下的最佳实践。 • Jupyter模式:Jupyter是最近几年算法人员使用比较多的一种工具,很多企业已经将其改造集成开发工…

MongoDB根据字段内容长度查询语句

db.getCollection("qlzx_penalties_business_raw").find({$expr: {$lt: [{ $strLenCP: "$punish_name" }, 5]},"punish_name_type" : "机构", "source_data" : /中国/,})解释: 1-"source_data" : /中…

召回02 Swing 召回通道

为了避免小圈子重合却误判物品相似度很高:降低小圈子对相似度的影响。

Element-ui el-table 全局表格排序

实现效果如下&#xff1a; 一、当页数据排序 如果只想要当前页面排序&#xff0c;只会涉及到前端&#xff0c;只需在<el-table-column>标签上添加 :sortable"true"即可 二、自定义排序 如果想要全局排序&#xff0c;需要自定义排序函数&#xff0c;请求后台排…

Unity Timeline

数据存储 TimeLine和Animation一样也是资源&#xff0c;以.playable的格式存储&#xff0c;可以通过Playable Director进行加载播放。 Playable具有以下优势&#xff1a; 结构简单&#xff1b; 运行时创建、添加和删除&#xff1b; 更加灵活&#xff0c;可以直接控制动画的各种…

计算机网络 ---- 计算机网络的体系结构【计算机网络的分层结构】

一、以快递网络来引入分层思想 1.1 “分层” 的设计思想【将庞大而复杂的问题&#xff0c;转化为若干较小的局部问题】 从我们最熟悉的快递网络出发&#xff0c;在你家附近会有一个快递终点站A&#xff0c;在其他的城市&#xff0c;也会有这种快递终点站&#xff0c;比如说快递…