init
This commit is contained in:
80
new-planet-backend/app/services/storage_service.py
Normal file
80
new-planet-backend/app/services/storage_service.py
Normal 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()
|
||||
|
||||
Reference in New Issue
Block a user