Skip to content

Commit e71c113

Browse files
author
Andrei Neagu
committed
added combine_lfiespan_context_managers
1 parent 1837ca2 commit e71c113

File tree

2 files changed

+66
-0
lines changed

2 files changed

+66
-0
lines changed
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
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 _
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
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

0 commit comments

Comments
 (0)