This commit is contained in:
2025-12-13 14:39:50 +03:00
commit b666cdcb95
79 changed files with 3081 additions and 0 deletions

View File

@@ -0,0 +1,80 @@
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()