33
44import contextlib
55from contextlib import asynccontextmanager , contextmanager
6- from typing import TYPE_CHECKING , AsyncGenerator , Callable , Generator , Sequence , Union , overload
6+ from typing import (
7+ TYPE_CHECKING ,
8+ Any ,
9+ AsyncGenerator ,
10+ Callable ,
11+ Generator ,
12+ Sequence ,
13+ Union ,
14+ overload ,
15+ )
716
817from starlette .applications import Starlette
918from starlette .requests import Request # noqa: TC002
@@ -68,8 +77,33 @@ def init_app(self, app: Starlette) -> None:
6877
6978 app .state .advanced_alchemy = self
7079
80+ original_lifespan = app .router .lifespan_context
81+
82+ @asynccontextmanager
83+ async def wrapped_lifespan (app : Starlette ) -> AsyncGenerator [Any , None ]: # pragma: no cover
84+ async with self .lifespan (app ), original_lifespan (app ) as state :
85+ yield state
86+
87+ app .router .lifespan_context = wrapped_lifespan
88+
89+ @asynccontextmanager
90+ async def lifespan (self , app : Starlette ) -> AsyncGenerator [Any , None ]: # pragma: no cover
91+ """Context manager for lifespan events.
92+
93+ Args:
94+ app: The starlette application.
95+
96+ Yields:
97+ None
98+ """
99+ await self .on_startup ()
100+ try :
101+ yield
102+ finally :
103+ await self .on_shutdown ()
104+
71105 @property
72- def app (self ) -> Starlette :
106+ def app (self ) -> Starlette : # pragma: no cover
73107 """Returns the Starlette application instance.
74108
75109 Raises:
@@ -79,7 +113,7 @@ def app(self) -> Starlette:
79113 Returns:
80114 starlette.applications.Starlette: The Starlette application instance.
81115 """
82- if self ._app is None :
116+ if self ._app is None : # pragma: no cover
83117 msg = "Application not initialized. Did you forget to call init_app?"
84118 raise ImproperConfigurationError (msg )
85119
@@ -119,36 +153,38 @@ def get_config(self, key: str | None = None) -> Union[SQLAlchemyAsyncConfig, SQL
119153 if key == "default" and len (self .config ) == 1 :
120154 key = self .config [0 ].bind_key or "default"
121155 config = self ._mapped_configs .get (key )
122- if config is None :
156+ if config is None : # pragma: no cover
123157 msg = f"Config with key { key } not found"
124158 raise ImproperConfigurationError (msg )
125159 return config
126160
127161 def get_async_config (self , key : str | None = None ) -> SQLAlchemyAsyncConfig :
128162 """Get the async config for the given key."""
129163 config = self .get_config (key )
130- if not isinstance (config , SQLAlchemyAsyncConfig ):
164+ if not isinstance (config , SQLAlchemyAsyncConfig ): # pragma: no cover
131165 msg = "Expected an async config, but got a sync config"
132166 raise ImproperConfigurationError (msg )
133167 return config
134168
135169 def get_sync_config (self , key : str | None = None ) -> SQLAlchemySyncConfig :
136170 """Get the sync config for the given key."""
137171 config = self .get_config (key )
138- if not isinstance (config , SQLAlchemySyncConfig ):
172+ if not isinstance (config , SQLAlchemySyncConfig ): # pragma: no cover
139173 msg = "Expected a sync config, but got an async config"
140174 raise ImproperConfigurationError (msg )
141175 return config
142176
143177 @asynccontextmanager
144- async def with_async_session (self , key : str | None = None ) -> AsyncGenerator [AsyncSession , None ]:
178+ async def with_async_session (
179+ self , key : str | None = None
180+ ) -> AsyncGenerator [AsyncSession , None ]: # pragma: no cover
145181 """Context manager for getting an async session."""
146182 config = self .get_async_config (key )
147183 async with config .get_session () as session :
148184 yield session
149185
150186 @contextmanager
151- def with_sync_session (self , key : str | None = None ) -> Generator [Session , None ]:
187+ def with_sync_session (self , key : str | None = None ) -> Generator [Session , None ]: # pragma: no cover
152188 """Context manager for getting a sync session."""
153189 config = self .get_sync_config (key )
154190 with config .get_session () as session :
@@ -164,7 +200,8 @@ def _get_session_from_request(request: Request, config: SQLAlchemySyncConfig) ->
164200
165201 @staticmethod
166202 def _get_session_from_request (
167- request : Request , config : SQLAlchemyAsyncConfig | SQLAlchemySyncConfig
203+ request : Request ,
204+ config : SQLAlchemyAsyncConfig | SQLAlchemySyncConfig , # pragma: no cover
168205 ) -> Session | AsyncSession : # pragma: no cover
169206 """Get the session for the given key."""
170207 session = getattr (request .state , config .session_key , None )
@@ -173,22 +210,24 @@ def _get_session_from_request(
173210 setattr (request .state , config .session_key , session )
174211 return session
175212
176- def get_session (self , request : Request , key : str | None = None ) -> Session | AsyncSession :
213+ def get_session (self , request : Request , key : str | None = None ) -> Session | AsyncSession : # pragma: no cover
177214 """Get the session for the given key."""
178215 config = self .get_config (key )
179216 return self ._get_session_from_request (request , config )
180217
181- def get_async_session (self , request : Request , key : str | None = None ) -> AsyncSession :
218+ def get_async_session (self , request : Request , key : str | None = None ) -> AsyncSession : # pragma: no cover
182219 """Get the async session for the given key."""
183220 config = self .get_async_config (key )
184221 return self ._get_session_from_request (request , config )
185222
186- def get_sync_session (self , request : Request , key : str | None = None ) -> Session :
223+ def get_sync_session (self , request : Request , key : str | None = None ) -> Session : # pragma: no cover
187224 """Get the sync session for the given key."""
188225 config = self .get_sync_config (key )
189226 return self ._get_session_from_request (request , config )
190227
191- def provide_session (self , key : str | None = None ) -> Callable [[Request ], Session | AsyncSession ]:
228+ def provide_session (
229+ self , key : str | None = None
230+ ) -> Callable [[Request ], Session | AsyncSession ]: # pragma: no cover
192231 """Get the session for the given key."""
193232 config = self .get_config (key )
194233
@@ -197,7 +236,7 @@ def _get_session(request: Request) -> Session | AsyncSession:
197236
198237 return _get_session
199238
200- def provide_async_session (self , key : str | None = None ) -> Callable [[Request ], AsyncSession ]:
239+ def provide_async_session (self , key : str | None = None ) -> Callable [[Request ], AsyncSession ]: # pragma: no cover
201240 """Get the async session for the given key."""
202241 config = self .get_async_config (key )
203242
@@ -206,7 +245,7 @@ def _get_session(request: Request) -> AsyncSession:
206245
207246 return _get_session
208247
209- def provide_sync_session (self , key : str | None = None ) -> Callable [[Request ], Session ]:
248+ def provide_sync_session (self , key : str | None = None ) -> Callable [[Request ], Session ]: # pragma: no cover
210249 """Get the sync session for the given key."""
211250 config = self .get_sync_config (key )
212251
@@ -220,12 +259,12 @@ def get_engine(self, key: str | None = None) -> Engine | AsyncEngine: # pragma:
220259 config = self .get_config (key )
221260 return config .get_engine ()
222261
223- def get_async_engine (self , key : str | None = None ) -> AsyncEngine :
262+ def get_async_engine (self , key : str | None = None ) -> AsyncEngine : # pragma: no cover
224263 """Get the async engine for the given key."""
225264 config = self .get_async_config (key )
226265 return config .get_engine ()
227266
228- def get_sync_engine (self , key : str | None = None ) -> Engine :
267+ def get_sync_engine (self , key : str | None = None ) -> Engine : # pragma: no cover
229268 """Get the sync engine for the given key."""
230269 config = self .get_sync_config (key )
231270 return config .get_engine ()
0 commit comments