mirror of https://github.com/tiangolo/fastapi.git
fix: resolve merge with master — lifespan app vs router
- Default lifespan: use app.router for _DefaultLifespan (router has _startup/_shutdown; FastAPI app does not). - Wrapper: when app is FastAPI, set fastapi_app from app and pass app.router to _run_lifespan_dependencies so lifespan deps are collected. - Test: use only Request.receive() (Starlette Request has no .send). Made-with: Cursor
This commit is contained in:
parent
df44ff0d9e
commit
53ebb9b46a
|
|
@ -49,6 +49,11 @@ def _wrap_lifespan_with_dependency_cache(original: Any) -> Any:
|
|||
@asynccontextmanager
|
||||
async def cm() -> Any:
|
||||
fastapi_app = getattr(app, "_fastapi_app", None)
|
||||
if fastapi_app is None and hasattr(app, "router"):
|
||||
router = getattr(app, "router", None)
|
||||
if router is not None and getattr(router, "_fastapi_app", None) is app:
|
||||
fastapi_app = app
|
||||
router_for_deps = getattr(app, "router", app)
|
||||
stack: AsyncExitStack | None = None
|
||||
orig_cm = original(app)
|
||||
try:
|
||||
|
|
@ -56,7 +61,9 @@ def _wrap_lifespan_with_dependency_cache(original: Any) -> Any:
|
|||
stack = AsyncExitStack()
|
||||
await stack.__aenter__()
|
||||
cache: dict[Any, Any] = {}
|
||||
await routing._run_lifespan_dependencies(app, cache, stack)
|
||||
await routing._run_lifespan_dependencies(
|
||||
router_for_deps, cache, stack
|
||||
)
|
||||
setattr(
|
||||
fastapi_app.state,
|
||||
FASTAPI_LIFESPAN_DEPENDENCY_CACHE,
|
||||
|
|
@ -1020,7 +1027,7 @@ class FastAPI(Starlette):
|
|||
_inner_lifespan = (
|
||||
lifespan
|
||||
if lifespan is not None
|
||||
else (lambda app: routing._DefaultLifespan(app))
|
||||
else (lambda app: routing._DefaultLifespan(app.router))
|
||||
)
|
||||
_lifespan = _wrap_lifespan_with_dependency_cache(_inner_lifespan)
|
||||
self.router: routing.APIRouter = routing.APIRouter(
|
||||
|
|
|
|||
|
|
@ -122,10 +122,9 @@ def test_collect_lifespan_dependants_route_level_scope() -> None:
|
|||
|
||||
|
||||
def test_lifespan_dependency_synthetic_request_receive_send() -> None:
|
||||
"""Lifespan dep that uses Request.receive/send covers noop_receive and noop_send during startup."""
|
||||
"""Lifespan dep that uses Request.receive covers noop_receive during startup."""
|
||||
async def lifespan_dep(request: Request) -> str:
|
||||
await request.receive()
|
||||
await request.send({"type": "http.response.body"})
|
||||
return "ok"
|
||||
|
||||
app = FastAPI()
|
||||
|
|
|
|||
Loading…
Reference in New Issue