122 lines
3.3 KiB
Python
122 lines
3.3 KiB
Python
|
|
"""MinIO 文件存储服务"""
|
|||
|
|
|
|||
|
|
import io
|
|||
|
|
from minio import Minio
|
|||
|
|
from minio.error import S3Error
|
|||
|
|
from app.core.config import settings
|
|||
|
|
from app.utils.logger import logger
|
|||
|
|
|
|||
|
|
|
|||
|
|
class MinioService:
|
|||
|
|
"""MinIO 文件存储服务"""
|
|||
|
|
|
|||
|
|
def __init__(self):
|
|||
|
|
self.client = Minio(
|
|||
|
|
settings.minio_endpoint,
|
|||
|
|
access_key=settings.minio_access_key,
|
|||
|
|
secret_key=settings.minio_secret_key,
|
|||
|
|
secure=settings.minio_secure,
|
|||
|
|
)
|
|||
|
|
self.bucket = settings.minio_bucket
|
|||
|
|
self._ensure_bucket()
|
|||
|
|
|
|||
|
|
def _ensure_bucket(self):
|
|||
|
|
"""确保存储桶存在"""
|
|||
|
|
try:
|
|||
|
|
if not self.client.bucket_exists(self.bucket):
|
|||
|
|
self.client.make_bucket(self.bucket)
|
|||
|
|
logger.info(f"Created MinIO bucket: {self.bucket}")
|
|||
|
|
except S3Error as e:
|
|||
|
|
logger.error(f"MinIO bucket check failed: {e}")
|
|||
|
|
|
|||
|
|
def upload_file(
|
|||
|
|
self,
|
|||
|
|
object_name: str,
|
|||
|
|
file_data: bytes,
|
|||
|
|
content_type: str = "application/octet-stream",
|
|||
|
|
) -> str:
|
|||
|
|
"""
|
|||
|
|
上传文件到 MinIO
|
|||
|
|
|
|||
|
|
Args:
|
|||
|
|
object_name: 对象名称(文件路径)
|
|||
|
|
file_data: 文件二进制数据
|
|||
|
|
content_type: 文件类型
|
|||
|
|
|
|||
|
|
Returns:
|
|||
|
|
文件的 MinIO URL
|
|||
|
|
"""
|
|||
|
|
try:
|
|||
|
|
data_stream = io.BytesIO(file_data)
|
|||
|
|
self.client.put_object(
|
|||
|
|
self.bucket,
|
|||
|
|
object_name,
|
|||
|
|
data_stream,
|
|||
|
|
length=len(file_data),
|
|||
|
|
content_type=content_type,
|
|||
|
|
)
|
|||
|
|
url = f"{settings.minio_endpoint}/{self.bucket}/{object_name}"
|
|||
|
|
logger.info(f"Uploaded file to MinIO: {object_name}")
|
|||
|
|
return url
|
|||
|
|
except S3Error as e:
|
|||
|
|
logger.error(f"MinIO upload failed: {e}")
|
|||
|
|
raise
|
|||
|
|
|
|||
|
|
def get_file(self, object_name: str) -> bytes:
|
|||
|
|
"""
|
|||
|
|
从 MinIO 获取文件
|
|||
|
|
|
|||
|
|
Args:
|
|||
|
|
object_name: 对象名称
|
|||
|
|
|
|||
|
|
Returns:
|
|||
|
|
文件二进制数据
|
|||
|
|
"""
|
|||
|
|
try:
|
|||
|
|
response = self.client.get_object(self.bucket, object_name)
|
|||
|
|
data = response.read()
|
|||
|
|
response.close()
|
|||
|
|
response.release_conn()
|
|||
|
|
return data
|
|||
|
|
except S3Error as e:
|
|||
|
|
logger.error(f"MinIO get file failed: {e}")
|
|||
|
|
raise
|
|||
|
|
|
|||
|
|
def delete_file(self, object_name: str) -> bool:
|
|||
|
|
"""
|
|||
|
|
删除 MinIO 中的文件
|
|||
|
|
|
|||
|
|
Args:
|
|||
|
|
object_name: 对象名称
|
|||
|
|
|
|||
|
|
Returns:
|
|||
|
|
是否成功删除
|
|||
|
|
"""
|
|||
|
|
try:
|
|||
|
|
self.client.remove_object(self.bucket, object_name)
|
|||
|
|
logger.info(f"Deleted file from MinIO: {object_name}")
|
|||
|
|
return True
|
|||
|
|
except S3Error as e:
|
|||
|
|
logger.error(f"MinIO delete failed: {e}")
|
|||
|
|
return False
|
|||
|
|
|
|||
|
|
def list_files(self, prefix: str = "") -> list[str]:
|
|||
|
|
"""
|
|||
|
|
列出 MinIO 中的文件
|
|||
|
|
|
|||
|
|
Args:
|
|||
|
|
prefix: 文件前缀过滤
|
|||
|
|
|
|||
|
|
Returns:
|
|||
|
|
文件名列表
|
|||
|
|
"""
|
|||
|
|
try:
|
|||
|
|
objects = self.client.list_objects(self.bucket, prefix=prefix)
|
|||
|
|
return [obj.object_name for obj in objects]
|
|||
|
|
except S3Error as e:
|
|||
|
|
logger.error(f"MinIO list files failed: {e}")
|
|||
|
|
return []
|
|||
|
|
|
|||
|
|
|
|||
|
|
# 单例
|
|||
|
|
minio_service = MinioService()
|