88from fastapi import FastAPI
99from pydantic import TypeAdapter
1010from servicelib .logging_utils import log_context
11- from tenacity import wait_exponential
11+ from tenacity import retry , wait_random_exponential
1212from tenacity .asyncio import AsyncRetrying
1313from tenacity .before_sleep import before_sleep_log
1414from tenacity .wait import wait_fixed
1515from types_aiobotocore_s3 .literals import BucketLocationConstraintType
1616
1717from ..constants import RETRY_WAIT_SECS
18- from ..core .settings import get_application_settings
18+ from ..core .settings import ApplicationSettings , get_application_settings
1919from ..exceptions .errors import ConfigurationError
2020
2121_logger = logging .getLogger (__name__ )
2222
2323
24+ @retry (
25+ wait = wait_random_exponential (),
26+ before_sleep = before_sleep_log (_logger , logging .WARNING ),
27+ reraise = True ,
28+ )
29+ async def _ensure_s3_bucket (
30+ client : SimcoreS3API , settings : ApplicationSettings
31+ ) -> None :
32+ with log_context (_logger , logging .DEBUG , msg = "setup.s3_bucket.cleanup_ctx" ):
33+ assert settings .STORAGE_S3 # nosec
34+ if await client .bucket_exists (bucket = settings .STORAGE_S3 .S3_BUCKET_NAME ):
35+ _logger .info (
36+ "S3 bucket %s exists already, skipping creation" ,
37+ settings .STORAGE_S3 .S3_BUCKET_NAME ,
38+ )
39+ return
40+ await client .create_bucket (
41+ bucket = settings .STORAGE_S3 .S3_BUCKET_NAME ,
42+ region = TypeAdapter (
43+ BucketLocationConstraintType | Literal ["us-east-1" ]
44+ ).validate_python (settings .STORAGE_S3 .S3_REGION ),
45+ )
46+
47+
2448def setup_s3 (app : FastAPI ) -> None :
2549 async def _on_startup () -> None :
2650 app .state .s3_client = None
@@ -45,29 +69,7 @@ async def _on_startup() -> None:
4569 assert client # nosec
4670 app .state .s3_client = client
4771
48- async for attempt in AsyncRetrying (
49- wait = wait_exponential (min = 1 ), # 1, 2, 4, 8, ...
50- before_sleep = before_sleep_log (_logger , logging .WARNING ),
51- reraise = True ,
52- ):
53- assert settings .STORAGE_S3 # nosec
54- with attempt , log_context (
55- _logger , logging .DEBUG , msg = "setup.s3_bucket.cleanup_ctx"
56- ):
57- if await client .bucket_exists (
58- bucket = settings .STORAGE_S3 .S3_BUCKET_NAME
59- ):
60- _logger .info (
61- "S3 bucket %s exists already, skipping creation" ,
62- settings .STORAGE_S3 .S3_BUCKET_NAME ,
63- )
64- break
65- await client .create_bucket (
66- bucket = settings .STORAGE_S3 .S3_BUCKET_NAME ,
67- region = TypeAdapter (
68- BucketLocationConstraintType | Literal ["us-east-1" ]
69- ).validate_python (settings .STORAGE_S3 .S3_REGION ),
70- )
72+ await _ensure_s3_bucket (client , settings )
7173
7274 async def _on_shutdown () -> None :
7375 if app .state .s3_client :
0 commit comments