61 lines
1.9 KiB
Python
61 lines
1.9 KiB
Python
"""MinIO / S3 presigned URL helper.
|
|
|
|
We use boto3 because MinIO speaks the S3 protocol and boto3 is the de-facto
|
|
client. Generating presigned multipart upload URLs lets the browser upload
|
|
files >100MB directly to MinIO without going through the FastAPI process,
|
|
which avoids body-size limits and streaming-into-RAM issues.
|
|
"""
|
|
|
|
import boto3
|
|
from botocore.client import Config
|
|
from ..config import settings
|
|
|
|
|
|
def s3_client():
|
|
return boto3.client(
|
|
"s3",
|
|
endpoint_url=("https" if settings.minio_secure else "http")
|
|
+ "://"
|
|
+ settings.minio_endpoint,
|
|
aws_access_key_id=settings.minio_access_key,
|
|
aws_secret_access_key=settings.minio_secret_key,
|
|
region_name=settings.minio_region,
|
|
config=Config(signature_version="s3v4", s3={"addressing_style": "path"}),
|
|
)
|
|
|
|
|
|
def ensure_bucket() -> None:
|
|
client = s3_client()
|
|
try:
|
|
client.head_bucket(Bucket=settings.minio_bucket)
|
|
except Exception:
|
|
client.create_bucket(Bucket=settings.minio_bucket)
|
|
|
|
|
|
def presign_put(object_key: str, content_type: str, expires: int = 3600) -> str:
|
|
"""Single-PUT presigned URL — for files small enough not to need multipart.
|
|
|
|
For multipart (files >100MB), the frontend should use the AWS SDK's
|
|
@aws-sdk/lib-storage Upload helper, which can sign each part itself once
|
|
we hand it the credentials. For MVP we keep things simple with single-PUT
|
|
+ a 500 MB cap.
|
|
"""
|
|
return s3_client().generate_presigned_url(
|
|
"put_object",
|
|
Params={
|
|
"Bucket": settings.minio_bucket,
|
|
"Key": object_key,
|
|
"ContentType": content_type,
|
|
},
|
|
ExpiresIn=expires,
|
|
HttpMethod="PUT",
|
|
)
|
|
|
|
|
|
def presign_get(object_key: str, expires: int = 3600) -> str:
|
|
return s3_client().generate_presigned_url(
|
|
"get_object",
|
|
Params={"Bucket": settings.minio_bucket, "Key": object_key},
|
|
ExpiresIn=expires,
|
|
)
|