Что такое lifespan событие? Как управлять жизненным циклом приложения?
Подробный ответ
Зачем нужен lifespan
Некоторые ресурсы не нужно создавать для каждого HTTP-запроса: пул соединений с базой, HTTP-клиент, подключение к брокеру или загруженная модель. Lifespan позволяет открыть их при запуске приложения и освободить при graceful shutdown.
Пример с asynccontextmanager
from contextlib import asynccontextmanager
from fastapi import FastAPI
import httpx
@asynccontextmanager
async def lifespan(app: FastAPI):
app.state.http_client = httpx.AsyncClient(timeout=10)
yield
await app.state.http_client.aclose()
app = FastAPI(lifespan=lifespan)Код до yield выполняется при старте приложения, а код после yield — при его завершении. Общий ресурс можно сохранить в app.state или передавать через dependency.
Доступ к ресурсу в endpoint
from fastapi import Request
@app.get('/external-data')
async def get_external_data(request: Request):
client = request.app.state.http_client
response = await client.get('https://example.com/data')
return response.json()Что не стоит делать
Не нужно выполнять в lifespan тяжёлые миграции базы, долгие синхронные задачи или работу, которую должны выполнять отдельные job-процессы. При нескольких workers lifespan запускается в каждом процессе, поэтому ресурсы и инициализация должны быть безопасны для многократного запуска.
Как ответить на собеседовании
Lifespan управляет ресурсами на уровне жизненного цикла FastAPI-приложения: до yield я инициализирую общий ресурс, после yield корректно его закрываю. Это подходит для HTTP-клиентов, connection pools и загружаемых моделей, а не для тяжёлых фоновых работ.
Оцени свой прогресс