首页 > 其他分享 >FastAPI: 测试lifespan特性(转)

FastAPI: 测试lifespan特性(转)

时间:2024-04-12 20:11:06浏览次数:28  
标签:resource FastAPI app lifespan yield 测试 async

add by zhj:实践出真知,文章写得真不错,自己测试这些条件

原文:FastAPI: experiment lifespan feature

Init

In FastAPI, one of ways creating a shared resource and living as long as application is up is using lifespan feature in FastAPI.

This lifespan feature can do

  • creating resources before App starts getting requests.
  • cleaning up resources when App is terminating

The feature used to be supported with startup/shutdown, but it has been deprecated.

Why startup/shutdown is deprecated?

In FastAPI, the startup and shutdown are two different functions. As you know, the shutdown function is used to clean up ( OR free up the resources ). To do that, some instances have to be kept in Global area.

The lifespan feature ( new ) tries to simplify ( OR remove ) those unencessity keeping them in Global area by utilizing “contextmanager”.

I’d like to try how it works today.

Start: Base Code

Here is the starting code. It uses “asynccontextmanager” in contextlib.

from contextlib import asynccontextmanager

from fastapi import FastAPI, Request

resource = {}

@asynccontextmanager
async def app_lifespan(app: FastAPI):
    print("init lifespan")
    resource["msg"] = "Hello, it's beautiful day!!"
    yield
    resource.clear()
    print("clean up lifespan")

app = FastAPI(lifespan=app_lifespan)

@app.get("/", include_in_schema=False)
async def root(request: Request):
    resource["msg"]

print("completed app init.")

Loading Application

  • The interesting thing was that the execution of the code wasn’t blocking code. The message “completed app int” is printed before the “init lifespan”.
  • And, one obvious thing was that “clean up lifespan” wasn’t printed when application is loaded. ( coroutine ).

 

Experiment 1: can contextmanager be used?

I got curious if `contextmanager` instead of `asynccontextmanager` can be used for the lifespan function.

So, I tried it. And, I got an error.

( maybe using sync contextmanager for async function didn’t make a sense from the beggining )

The error is from Starlette that FastAPI depends on.

Based on the code, the lifespan has to be wrapped ( or supported ) with async context manager. ( required )

 

Experiment 2: Is app positional argument required for lifespan function?

Here is the base code. I got curious if the app argument is required.

So, I tried after removing the app argument from the app_lifespan function.

@asynccontextmanager
async def app_lifespan(app: FastAPI):
    print("init lifespan")
    resource["msg"] = "Hello, it's beautiful day!!"
    yield
    resource.clear()
    print("clean up lifespan")

And, I got this error. The error came from the same code that I looked into when I tried contextmanager instead asynccontextmanager .

Basically, the Starlette lifespan implementation that FastAPI uses requires

  • asynccontextmanager
  • taking a positional argument
async with self.lifespan_context(app) as maybe_state:

Experiment 3: Does lifespan has to be set to FastAPI?

The `def app_lifespan` is assigned ( or set ) to FastAPI in the base code like below.

app = FastAPI(lifespan=app_lifespan)

What if the `app_lifespan` is not assigned into FastAPI during the initialization, will the lifespan be executed?

Well, based on the code I saw in previous experimentations, I can say that it won’t work. And, the below result confirmed that.

 

Experiment 4: Is `yield` required in lifespan?

What if `yield` is removed? Does it still work?

Is the `yield` required in the lifespan?

@asynccontextmanager
async def app_lifespan(app: FastAPI):
    print("init lifespan")
    resource["msg"] = "Hello, it's beautiful day!!"
    # yield
    resource.clear()
    print("clean up lifespan")

Yes. The `yield` is required. It’s because the lifespan uses async function + asynccontextmanger. It needs `yield`

 

Experiment 5: what if lifespan is implemented as sync function?

What if the lifspan is implemented fully as sync function like below?

 
@contextmanager
def app_lifespan(app: FastAPI):
    print("init lifespan")
    resource["msg"] = "Hello, it's beautiful day!!"
    # yield
    resource.clear()
    print("clean up lifespan")

As seen in the previous experimentations, since the Starlette uses ( or expect ) asynccontextmanger, it doesn’t work.

Summary

Basically, the lifespan feature requires

  • async implemented function
  • yield has to be set in the function
  • asynccontextmanager has to be used
  • async implemented function lifespan has to be set to FastAPI

Here is the final format how FastAPI lifespan has to be implemented.

@asynccontextmanager
async def app_lifespan(app: FastAPI):
    # code to execute when app is loading
    yield
    # code to execute when app is shutting down

app = FastAPI(lifespan=app_lifespan)

 

标签:resource,FastAPI,app,lifespan,yield,测试,async
From: https://www.cnblogs.com/ajianbeyourself/p/18132009

相关文章

  • 四月十一日软件测试学习
      黑盒测试用例设计方法:1、等价类划分:他的具体操作方法,就是把所有可能的输入数据,包括有效输入数据和无效输入数据,给他划分成若干个等价的子集,给他起个名字就叫做等价类,使得每个子集中的典型值在测试中的作用与这一子集中其他值的作用相同。因为咱们输入的数据分为......
  • G2D图像处理硬件调用和测试-基于米尔-全志T113-i开发板
    本篇测评由电子工程世界的优秀测评者“jf_99374259”提供。本文将介绍基于米尔电子MYD-YT113i开发板的G2D图像处理硬件调用和测试。 MYC-YT113i核心板及开发板真正的国产核心板,100%国产物料认证国产T113-i处理器配备2*[email protected],RISC-V外置DDR3接口、支持视频......
  • PAN3029与SX1276接收灵敏度的测试对比
       2023年9月磐启微第二代ChirpIoT™系列芯片PAN3029发布至今已有半年了,不少企业都拿到了PAN3029的测试板。但由于缺乏充分的仪器,或测试方法问题无法准确的获得芯片在不同扩频因子下的灵敏度。因此由行业专家甘泉老师操刀测试PAN3029这款芯片性能后并录制成视频,供行业的企业......
  • 测试环境如何部署?
    测试环境的部署是为了提供一个与生产环境相似的环境,用于进行软件测试。下面是测试环境部署的一般步骤和注意事项 确定测试环境的需求:首先,需要明确测试的范围、目的和需求。了解要测试的软件系统或应用程序的特性、架构和依赖关系,确定所需的硬件资源、软件环境和网络配置等......
  • 一个完整的测试报告包括哪些内容?
    一、概要:一个完整的测试报告应该包括以下内容:标题和概要信息:报告的标题、日期、项目名称、版本信息等概要信息,以及报告编写人员的姓名和联系方式。引言:对测试任务和测试目标的简要介绍,包括测试的范围、目的和重点。测试执行概况:对测试执行情况的概述,包括测试周......
  • linux C++程序测试命令的一种实现
    linuxC++程序测试命令的一种实现前言在程序开发调试过程中,或者已经部署的情况下,我们常常需要执行一些测试命令。在命令行端输入命令,然后程序执行,说起来简单,但是当程序本身有很多终端调试信息输出时,命令输入很不方便。针对上述问题,以下提供一个使用消息队列的命令行测试小工具......
  • 【Go】单元测试
    Go本身提供了一套轻量级的测试框架。符合规则的测试代码会在运行测试时被自动识别并执行。单元测试源文件的命名规则如下:在需要测试的包下面创建以“_test”结尾的go文件,形如[^.]*_test.goGo的单元测试函数分功能测试函数和性能测试函数,分别以Test和Benchmark为函数名前缀并以*t......
  • 3568F-PCIe 5G通信测试手册
     ......
  • 3568F-Linux-RT系统测试手册
     ......
  • 火山引擎 VeDI:剪映产品如何应用A/B测试验证新功能效果
    更多技术交流、求职机会,欢迎关注字节跳动数据平台微信公众号,回复【1】进入官方交流群C端产品的用户体验是决定用户留存率和产品使用率的关键,为了提升用户体验,一些C端产品上线新功能前已经开始引入A/B测试,判断新功能带来的用户反馈。本文介绍剪映APP应用A/B测试验证新功能上线效......