pythonfastapistarlettefastapi-middleware

How to add a shutdown event in FastAPI using lifespan in middleware?


FastAPI profiler code

        if server_app is not None:
            server_app.add_event_handler("shutdown", self.get_profiler_result)

I think Starlette is not allowing both lifespan and shutdown events. Code link

        if on_startup or on_shutdown:
            warnings.warn(
                "The on_startup and on_shutdown parameters are deprecated, and they "
                "will be removed on version 1.0. Use the lifespan parameter instead. "
                "See more about it on https://www.starlette.io/lifespan/.",
                DeprecationWarning,
            )
            if lifespan:
                warnings.warn(
                    "The `lifespan` parameter cannot be used with `on_startup` or "
                    "`on_shutdown`. Both `on_startup` and `on_shutdown` will be "
                    "ignored."
                )

I am using lifespan to manage my DB and that cannot be removed. Can you suggest a way ?

I tried to check in the __call__ function whether the scope is "lifespan" and send event is lifespan.shutdown acc. to link but did not get that event.

My code:

app = FastAPI(
    lifespan=lifespan,
)

app.add_middleware(PyInstrumentProfilerMiddleware, 
                   profiler_output_type="html", 
                   server_app=app,
                   open_in_browser=True)


Solution

  • I used the code from the below link to manually call the shutdown events

    https://github.com/fastapi/fastapi/discussions/11872#discussioncomment-10134866

    from contextlib import asynccontextmanager
    from fastapi import FastAPI
    
    @asynccontextmanager
    async def lifespan(app: FastAPI):
        yield
        for on_shutdown in  app.router.on_shutdown:
            await on_shutdown()
    
    app = FastAPI(lifespan=lifespan)
    
    async def get_profiler_result():
        print("On shutdown has been called")
    
    app.add_event_handler("shutdown", get_profiler_result)
    

    Caveat: This is just a hack. also see