Consider a custom class designed for sending notifications, whose initialization involves establishing a connection to a notification server, a time-consuming process. This class is utilized within a background task in FastAPI to avoid delaying the endpoint response. However, the current approach has limitations:
file1.py: noticlient = NotificationClient() @app.post("/{data}") def send_msg(somemsg: str, background_tasks: BackgroundTasks): result = add_some_tasks(data, background_tasks, noticlient) return result file2.py: def add_some_tasks(data, background_tasks: BackgroundTasks, noticlient): background_tasks.add_task(noticlient.send, param1, param2) result = some_operation return result
The global NotificationClient initialization in file1.py results in multiple redundant initializations every time a request is received, which is inefficient.
Option 1: Utilizing app.state
FastAPI allows you to store arbitrary state using app.state. You can initialize the NotificationClient object and add it to app.state during FastAPI startup or shutdown using a dependency lifecycle function such as lifespan.
from fastapi import FastAPI, Request from contextlib import asynccontextmanager @asynccontextmanager async def lifespan(app: FastAPI): ''' Run at startup Initialise the Client and add it to app.state ''' app.state.n_client = NotificationClient() yield ''' Run on shutdown Close the connection Clear variables and release the resources ''' app.state.n_client.close() app = FastAPI(lifespan=lifespan) @app.get('/') async def main(request: Request): n_client = request.app.state.n_client # ...
Option 2: Utilizing Starlette lifespan
Starlette's lifespan handler allows you to define state objects accessible within endpoints via request.state.
from fastapi import FastAPI, Request from contextlib import asynccontextmanager @asynccontextmanager async def lifespan(app: FastAPI): ''' Run at startup Initialise the Client and add it to request.state ''' n_client = NotificationClient() yield {'n_client': n_client} ''' Run on shutdown Close the connection Clear variables and release the resources ''' n_client.close() app = FastAPI(lifespan=lifespan) @app.get('/') async def main(request: Request): n_client = request.state.n_client # ...
The above is the detailed content of How to Efficiently Initialize and Reuse a Global Object Across FastAPI Endpoints?. For more information, please follow other related articles on the PHP Chinese website!