from contextlib import asynccontextmanager import aiobotocore.session from app.config import get_settings from app.storage.backend import StorageBackend class S3StorageBackend(StorageBackend): def __init__(self) -> None: self._settings = get_settings() self._session = aiobotocore.session.get_session() @asynccontextmanager async def _client(self): s = self._settings async with self._session.create_client( "s3", region_name=s.s3_region, endpoint_url=s.s3_endpoint_url or None, aws_access_key_id=s.s3_access_key_id, aws_secret_access_key=s.s3_secret_access_key, ) as client: yield client async def put(self, key: str, data: bytes, content_type: str) -> None: async with self._client() as client: await client.put_object( Bucket=self._settings.s3_bucket_name, Key=key, Body=data, ContentType=content_type, ) async def get(self, key: str) -> bytes: async with self._client() as client: response = await client.get_object(Bucket=self._settings.s3_bucket_name, Key=key) return await response["Body"].read() async def delete(self, key: str) -> None: async with self._client() as client: await client.delete_object(Bucket=self._settings.s3_bucket_name, Key=key)