Files
deer-flow/backend/app/gateway/common/lifespan.py
T
rayhpeng 39a575617b refactor(gateway): restructure gateway with new dependency injection and services
Reorganize app/gateway/ with:
- common/ - lifespan management
- dependencies/ - FastAPI dependency injection (db, checkpointer, repositories, stream_bridge)
- services/runs/ - run execution services (facade_factory, input adapters, store operations)
- registrar.py - router registration
- router.py - main router setup

Simplify app.py to use the new modular structure.
Remove deprecated utils.py.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-22 11:27:08 +08:00

53 lines
1.4 KiB
Python

from collections.abc import Callable
from contextlib import AbstractAsyncContextManager, AsyncExitStack, asynccontextmanager
from typing import Any
from fastapi import FastAPI
LifespanFunc = Callable[[FastAPI], AbstractAsyncContextManager[dict[str, Any] | None]]
class LifespanManager:
"""FastAPI lifespan manager"""
def __init__(self) -> None:
self._lifespans: list[LifespanFunc] = []
def register(self, func: LifespanFunc) -> LifespanFunc:
"""
Register a lifespan hook.
:param func: lifespan hook
:return:
"""
if func not in self._lifespans:
self._lifespans.append(func)
return func
def build(self) -> LifespanFunc:
"""
Build the combined lifespan hook.
:return:
"""
@asynccontextmanager
async def combined_lifespan(app: FastAPI): # noqa: ANN202
state: dict[str, Any] = {}
async with AsyncExitStack() as exit_stack:
for lifespan_fn in self._lifespans:
result = await exit_stack.enter_async_context(lifespan_fn(app))
if isinstance(result, dict):
state.update(result)
for key, value in state.items():
setattr(app.state, key, value)
yield state or None
return combined_lifespan
# Singleton lifespan_manager instance
lifespan_manager = LifespanManager()