Files
xiaoxia-saas/apps/api/app/core/storage.py
T
Xiaoxia AI b06201e503
Deploy / Deploy Staging (push) Failing after 6s
Deploy / Deploy Production (push) Has been skipped
Tests / test (push) Failing after 16s
Tests / lint (push) Failing after 16s
fix(phase7): align api runtime wiring for integration
2026-06-17 18:48:08 +08:00

85 lines
2.5 KiB
Python

"""MinIO storage service for file uploads."""
from typing import BinaryIO
import os
from minio import Minio
from minio.error import S3Error
from app.config import get_settings
class MinIOService:
"""MinIO storage service."""
def __init__(self):
settings = get_settings()
self.client = Minio(
settings.MINIO_ENDPOINT,
access_key=settings.MINIO_ACCESS_KEY,
secret_key=settings.MINIO_SECRET_KEY,
secure=settings.MINIO_SECURE,
)
self.bucket_name = settings.MINIO_BUCKET
self.public_url = settings.MINIO_PUBLIC_URL
self._ensure_bucket()
def _ensure_bucket(self):
try:
if not self.client.bucket_exists(self.bucket_name):
self.client.make_bucket(self.bucket_name)
policy = {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {"AWS": "*"},
"Action": ["s3:GetObject"],
"Resource": [f"arn:aws:s3:::{self.bucket_name}/*"],
}
],
}
import json
self.client.set_bucket_policy(self.bucket_name, json.dumps(policy))
except S3Error as error:
print(f"Error ensuring bucket: {error}")
def upload_file(
self,
file: BinaryIO,
storage_key: str,
content_type: str = "application/octet-stream",
) -> str:
try:
file.seek(0, os.SEEK_END)
file_size = file.tell()
file.seek(0)
self.client.put_object(
self.bucket_name,
storage_key,
file,
file_size,
content_type=content_type,
)
return f"{self.public_url}/{self.bucket_name}/{storage_key}"
except S3Error as error:
raise Exception(f"Failed to upload file: {error}")
def get_url(self, storage_key: str) -> str:
return f"{self.public_url}/{self.bucket_name}/{storage_key}"
def delete_file(self, storage_key: str):
try:
self.client.remove_object(self.bucket_name, storage_key)
except S3Error as error:
print(f"Error deleting file: {error}")
_minio_service = None
def get_minio_service() -> MinIOService:
global _minio_service
if _minio_service is None:
_minio_service = MinIOService()
return _minio_service