Skip to content

Commit

Permalink
feat(storage): make S3 URL expiration customizable (#345)
Browse files Browse the repository at this point in the history
* feat(storage): make S3 URL expiration customizable

* feat(config): make URL expiration an env var

* test(storage): add test cases

* style(test): remove legacy import

* fix(config): fix type casting
  • Loading branch information
frgfm authored Jul 13, 2024
1 parent 5199745 commit 2dcab5b
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 2 deletions.
1 change: 1 addition & 0 deletions src/app/core/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ def sqlachmey_uri(cls, v: str) -> str:
S3_REGION: str = os.environ["S3_REGION"]
S3_ENDPOINT_URL: str = os.environ["S3_ENDPOINT_URL"]
S3_PROXY_URL: str = os.environ.get("S3_PROXY_URL", "")
S3_URL_EXPIRATION: int = int(os.environ.get("S3_URL_EXPIRATION") or 24 * 3600)

# Error monitoring
SENTRY_DSN: Union[str, None] = os.environ.get("SENTRY_DSN")
Expand Down
2 changes: 1 addition & 1 deletion src/app/services/storage.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ async def check_file_existence(self, bucket_key: str) -> bool:
logger.warning(e)
return False

async def get_public_url(self, bucket_key: str, url_expiration: int = 3600) -> str:
async def get_public_url(self, bucket_key: str, url_expiration: int = settings.S3_URL_EXPIRATION) -> str:
"""Generate a temporary public URL for a bucket file"""
if not (await self.check_file_existence(bucket_key)):
raise HTTPException(status_code=404, detail="File cannot be found on the bucket storage")
Expand Down
21 changes: 20 additions & 1 deletion src/tests/services/test_storage.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,24 @@
import io

import pytest
from httpx import AsyncClient

from app.services.storage import S3Bucket, s3_bucket


def test_s3_bucket():
@pytest.mark.asyncio
async def test_s3_bucket(async_client: AsyncClient, mock_img: bytes):
assert isinstance(s3_bucket, S3Bucket)
bucket_key = "logo.png"
url_expiration = 1
# Check the file does not exist
assert not (await s3_bucket.check_file_existence(bucket_key))
assert await s3_bucket.upload_file(bucket_key, io.BytesIO(mock_img))
assert await s3_bucket.check_file_existence(bucket_key)
assert isinstance(await s3_bucket.get_file_metadata(bucket_key), dict)
# Get the public URL
file_url = await s3_bucket.get_public_url(bucket_key, url_expiration)
assert file_url.startswith("http://")
# Check the file is deleted
await s3_bucket.delete_file(bucket_key)
assert not (await s3_bucket.check_file_existence(bucket_key))

0 comments on commit 2dcab5b

Please sign in to comment.