# microservice/utils/minio_client.py import os from minio import Minio from minio.error import S3Error from datetime import timedelta from typing import Optional, BinaryIO import logging logger = logging.getLogger(__name__) class MinIOClient: """Cliente MinIO para FastAPI""" def __init__(self): self.client = None self.bucket_name = None self._initialize() def _initialize(self): """Inicializa el cliente MinIO""" endpoint = os.environ.get('MINIO_ENDPOINT', 'minio:9000') access_key = os.environ.get('MINIO_ACCESS_KEY') secret_key = os.environ.get('MINIO_SECRET_KEY') secure = os.environ.get('MINIO_SECURE', 'false').lower() == 'true' self.bucket_name = os.environ.get('MINIO_BUCKET_NAME', 'efc-microservice-dev') self.client = Minio( endpoint=endpoint, access_key=access_key, secret_key=secret_key, secure=secure ) # Asegurar bucket if not self.client.bucket_exists(self.bucket_name): self.client.make_bucket(self.bucket_name) logger.info(f"Bucket '{self.bucket_name}' creado") def upload_file( self, object_name: str, file_path: str = None, file_data: bytes = None, content_type: str = None ) -> bool: """Sube archivo a MinIO (síncrono para Celery)""" try: if file_path: self.client.fput_object( self.bucket_name, object_name, file_path, content_type=content_type ) elif file_data: import io data_stream = io.BytesIO(file_data) self.client.put_object( self.bucket_name, object_name, data_stream, len(file_data), content_type=content_type ) return True except Exception as e: logger.error(f"Error subiendo archivo: {e}") return False def get_presigned_url(self, object_name: str, expires: int = 3600) -> Optional[str]: """Genera URL firmada""" try: return self.client.presigned_get_object( self.bucket_name, object_name, expires=timedelta(seconds=expires) ) except Exception as e: logger.error(f"Error generando URL: {e}") return None # Singleton minio_client = MinIOClient()