File tree Expand file tree Collapse file tree 2 files changed +66
-0
lines changed Expand file tree Collapse file tree 2 files changed +66
-0
lines changed Original file line number Diff line number Diff line change 1+ from collections .abc import AsyncGenerator , Callable
2+ from contextlib import AsyncExitStack , asynccontextmanager
3+ from typing import AsyncContextManager , TypeAlias
4+
5+ from fastapi import FastAPI
6+
7+ LifespanContextManager : TypeAlias = Callable [[FastAPI ], AsyncContextManager [None ]]
8+
9+
10+ def combine_lfiespan_context_managers (
11+ * context_managers : LifespanContextManager ,
12+ ) -> LifespanContextManager :
13+ """the first entry has its `setup` called first and its `teardown` called last
14+ With `setup` and `teardown` referring to the code before and after the `yield`
15+ """
16+
17+ @asynccontextmanager
18+ async def _ (app : FastAPI ) -> AsyncGenerator [None , None ]:
19+ async with AsyncExitStack () as stack :
20+ for context_manager in context_managers :
21+ await stack .enter_async_context (context_manager (app ))
22+ yield
23+
24+ return _
Original file line number Diff line number Diff line change 1+ from collections .abc import AsyncIterator
2+ from contextlib import asynccontextmanager
3+
4+ import pytest
5+ from asgi_lifespan import LifespanManager
6+ from fastapi import FastAPI
7+ from servicelib .fastapi .lifespan_utils import combine_lfiespan_context_managers
8+
9+
10+ async def test_multiple_lifespan_managers (capsys : pytest .CaptureFixture ):
11+ @asynccontextmanager
12+ async def database_lifespan (_ : FastAPI ) -> AsyncIterator [None ]:
13+ print ("setup DB" )
14+ yield
15+ print ("shutdown DB" )
16+
17+ @asynccontextmanager
18+ async def cache_lifespan (_ : FastAPI ) -> AsyncIterator [None ]:
19+ print ("setup CACHE" )
20+ yield
21+ print ("shutdown CACHE" )
22+
23+ app = FastAPI (
24+ lifespan = combine_lfiespan_context_managers (database_lifespan , cache_lifespan )
25+ )
26+
27+ capsys .readouterr ()
28+
29+ async with LifespanManager (app ):
30+ messages = capsys .readouterr ().out
31+
32+ assert "setup DB" in messages
33+ assert "setup CACHE" in messages
34+ assert "shutdown DB" not in messages
35+ assert "shutdown CACHE" not in messages
36+
37+ messages = capsys .readouterr ().out
38+
39+ assert "setup DB" not in messages
40+ assert "setup CACHE" not in messages
41+ assert "shutdown DB" in messages
42+ assert "shutdown CACHE" in messages
You can’t perform that action at this time.
0 commit comments