|
4 | 4 | from dataclasses import dataclass |
5 | 5 | from datetime import datetime |
6 | 6 | from functools import cached_property |
7 | | -from typing import Any, Final, Literal |
| 7 | +from typing import Any, AsyncContextManager, Final, Literal |
8 | 8 |
|
9 | 9 | import aiodocker |
10 | 10 | import aiohttp |
@@ -287,44 +287,56 @@ async def pull_image( |
287 | 287 | ) |
288 | 288 |
|
289 | 289 |
|
290 | | -@asynccontextmanager |
291 | | -async def lifespan_remote_docker_client(app: FastAPI) -> AsyncIterator[None]: |
292 | | - """Ensures `setup` and `teardown` for the docker client. |
| 290 | +def get_lifespan_remote_docker_client( |
| 291 | + docker_api_proxy_settings_property_name: str, |
| 292 | +) -> Callable[[FastAPI], AsyncContextManager[None]]: |
| 293 | + """Ensures `setup` and `teardown` for the remote docker client. |
293 | 294 |
|
294 | | - NOTE: the `DockerApiProxysettings` must be placed as `DOCKER_API_PROXY` |
295 | | - on the Application's Settings object |
| 295 | + Arguments: |
| 296 | + docker_api_proxy_settings_property_name -- if the name is `PROP_NAME` |
| 297 | + then it should be accessible as `app.state.settings.PROP_NAME` |
| 298 | +
|
| 299 | + Returns: |
| 300 | + docker client lifespan manager |
296 | 301 | """ |
297 | | - settings: DockerApiProxysettings = app.state.settings.DOCKER_API_PROXY |
298 | | - |
299 | | - session: ClientSession | None = None |
300 | | - if settings.DOCKER_API_PROXY_USER and settings.DOCKER_API_PROXY_PASSWORD: |
301 | | - session = ClientSession( |
302 | | - auth=aiohttp.BasicAuth( |
303 | | - login=settings.DOCKER_API_PROXY_USER, |
304 | | - password=settings.DOCKER_API_PROXY_PASSWORD.get_secret_value(), |
305 | | - ) |
| 302 | + |
| 303 | + @asynccontextmanager |
| 304 | + async def _(app: FastAPI) -> AsyncIterator[None]: |
| 305 | + settings: DockerApiProxysettings = getattr( |
| 306 | + app.state.settings, docker_api_proxy_settings_property_name |
306 | 307 | ) |
307 | 308 |
|
308 | | - async with AsyncExitStack() as exit_stack: |
| 309 | + session: ClientSession | None = None |
309 | 310 | if settings.DOCKER_API_PROXY_USER and settings.DOCKER_API_PROXY_PASSWORD: |
310 | | - await exit_stack.enter_async_context( |
311 | | - ClientSession( |
312 | | - auth=aiohttp.BasicAuth( |
313 | | - login=settings.DOCKER_API_PROXY_USER, |
314 | | - password=settings.DOCKER_API_PROXY_PASSWORD.get_secret_value(), |
| 311 | + session = ClientSession( |
| 312 | + auth=aiohttp.BasicAuth( |
| 313 | + login=settings.DOCKER_API_PROXY_USER, |
| 314 | + password=settings.DOCKER_API_PROXY_PASSWORD.get_secret_value(), |
| 315 | + ) |
| 316 | + ) |
| 317 | + |
| 318 | + async with AsyncExitStack() as exit_stack: |
| 319 | + if settings.DOCKER_API_PROXY_USER and settings.DOCKER_API_PROXY_PASSWORD: |
| 320 | + await exit_stack.enter_async_context( |
| 321 | + ClientSession( |
| 322 | + auth=aiohttp.BasicAuth( |
| 323 | + login=settings.DOCKER_API_PROXY_USER, |
| 324 | + password=settings.DOCKER_API_PROXY_PASSWORD.get_secret_value(), |
| 325 | + ) |
315 | 326 | ) |
316 | 327 | ) |
| 328 | + |
| 329 | + client = await exit_stack.enter_async_context( |
| 330 | + aiodocker.Docker(url=settings.base_url, session=session) |
317 | 331 | ) |
318 | 332 |
|
319 | | - client = await exit_stack.enter_async_context( |
320 | | - aiodocker.Docker(url=settings.base_url, session=session) |
321 | | - ) |
| 333 | + app.state.remote_docker_client = client |
322 | 334 |
|
323 | | - app.state.remote_docker_client = client |
| 335 | + yield |
324 | 336 |
|
325 | | - yield |
| 337 | + return _ |
326 | 338 |
|
327 | 339 |
|
328 | 340 | def get_remote_docker_client(app: FastAPI) -> aiodocker.Docker: |
329 | | - client: aiodocker.Docker = app.state.remote_docker_client |
330 | | - return client |
| 341 | + assert isinstance(app.state.remote_docker_client, aiodocker.Docker) # nosec |
| 342 | + return app.state.remote_docker_client |
0 commit comments