81 lines
2.6 KiB
Python
81 lines
2.6 KiB
Python
import uuid
|
|
from typing import Optional, BinaryIO
|
|
from botocore.exceptions import ClientError
|
|
import boto3
|
|
from app.core.config import settings
|
|
|
|
|
|
class StorageService:
|
|
def __init__(self):
|
|
self.client = None
|
|
self._initialize_client()
|
|
|
|
def _initialize_client(self):
|
|
"""Инициализация S3/MinIO клиента"""
|
|
self.client = boto3.client(
|
|
"s3",
|
|
endpoint_url=f"{'https' if settings.STORAGE_USE_SSL else 'http'}://{settings.STORAGE_ENDPOINT}",
|
|
aws_access_key_id=settings.STORAGE_ACCESS_KEY,
|
|
aws_secret_access_key=settings.STORAGE_SECRET_KEY,
|
|
region_name=settings.STORAGE_REGION,
|
|
use_ssl=settings.STORAGE_USE_SSL,
|
|
verify=False # Для MinIO в dev
|
|
)
|
|
|
|
async def upload_file(
|
|
self,
|
|
file_obj: BinaryIO,
|
|
filename: str,
|
|
content_type: str = "image/jpeg"
|
|
) -> str:
|
|
"""Загрузить файл в хранилище"""
|
|
file_key = f"{uuid.uuid4()}_{filename}"
|
|
|
|
try:
|
|
self.client.upload_fileobj(
|
|
file_obj,
|
|
settings.STORAGE_BUCKET,
|
|
file_key,
|
|
ExtraArgs={"ContentType": content_type}
|
|
)
|
|
|
|
# Формируем URL
|
|
url = f"{'https' if settings.STORAGE_USE_SSL else 'http'}://{settings.STORAGE_ENDPOINT}/{settings.STORAGE_BUCKET}/{file_key}"
|
|
return url
|
|
except ClientError as e:
|
|
raise Exception(f"Failed to upload file: {str(e)}")
|
|
|
|
async def delete_file(self, file_key: str) -> bool:
|
|
"""Удалить файл из хранилища"""
|
|
try:
|
|
# Извлекаем ключ из URL если передан полный URL
|
|
if "/" in file_key:
|
|
file_key = file_key.split("/")[-1]
|
|
|
|
self.client.delete_object(
|
|
Bucket=settings.STORAGE_BUCKET,
|
|
Key=file_key
|
|
)
|
|
return True
|
|
except ClientError:
|
|
return False
|
|
|
|
async def get_file_url(self, file_key: str) -> Optional[str]:
|
|
"""Получить URL файла"""
|
|
try:
|
|
if "/" in file_key:
|
|
file_key = file_key.split("/")[-1]
|
|
|
|
url = self.client.generate_presigned_url(
|
|
"get_object",
|
|
Params={"Bucket": settings.STORAGE_BUCKET, "Key": file_key},
|
|
ExpiresIn=3600
|
|
)
|
|
return url
|
|
except ClientError:
|
|
return None
|
|
|
|
|
|
storage_service = StorageService()
|
|
|