"""MinIO / S3-compatible object-storage helpers. Provides thin wrappers around boto3 for bucket management, file upload and presigned-URL generation. """ import boto3 from botocore.exceptions import ClientError from app.config import settings # --------------------------------------------------------------------------- # Shared client (module-level singleton) # --------------------------------------------------------------------------- _scheme = "https" if settings.MINIO_SECURE else "http" _client = boto3.client( "s3", endpoint_url=f"{_scheme}://{settings.MINIO_ENDPOINT}", aws_access_key_id=settings.MINIO_ACCESS_KEY, aws_secret_access_key=settings.MINIO_SECRET_KEY, region_name="us-east-1", # MinIO ignores this but boto3 requires it ) # --------------------------------------------------------------------------- # Public helpers # --------------------------------------------------------------------------- def ensure_bucket_exists() -> None: """Create the evidence bucket if it does not already exist.""" try: _client.head_bucket(Bucket=settings.MINIO_BUCKET) except ClientError: _client.create_bucket(Bucket=settings.MINIO_BUCKET) def upload_file(content: bytes, key: str) -> str: """Upload *content* to the evidence bucket under *key*. Returns the key that was written (same as the input). """ _client.put_object( Bucket=settings.MINIO_BUCKET, Key=key, Body=content, ) return key def get_presigned_url(key: str, expiration: int = 3600) -> str: """Return a presigned GET URL for *key* valid for *expiration* seconds.""" return _client.generate_presigned_url( "get_object", Params={"Bucket": settings.MINIO_BUCKET, "Key": key}, ExpiresIn=expiration, )