Files
call-review-platform/services/ingest-service/app/infrastructure/s3.py
2025-12-06 18:25:08 +05:00

67 lines
2.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import aioboto3
import asyncio
import logging
import os
import aiohttp
from app.config import settings
logger = logging.getLogger(__name__)
async def download_and_upload_stream(url: str, key_name: str) -> bool:
"""
Скачивает аудиофайл по URL потоками и передаёт в upload_file_to_s3 для загрузки.
"""
try:
logger.info(f"[INFO] Начало скачивания {url}")
async with aiohttp.ClientSession() as http_session:
async with http_session.get(url) as resp:
resp.raise_for_status()
# читаем файл по частям и собираем в bytes
chunks = []
while True:
chunk = await resp.content.read(1024 * 1024) # 1 МБ
if not chunk:
break
chunks.append(chunk)
file_bytes = b"".join(chunks)
logger.info(f"[INFO] Скачивание {url} завершено, размер {len(file_bytes)} байт")
# передаём в функцию загрузки с retry
success = await upload_file_to_s3(file_bytes, key_name)
return success
except Exception as e:
logger.error(f"[FAILED] Не удалось скачать или загрузить {url}: {e}")
return False
async def upload_file_to_s3(file_bytes: bytes, key_name: str) -> bool:
"""
Асинхронно загружает файл в S3 с ретраями.
Возвращает True при успехе, False при ошибке.
"""
session = aioboto3.Session()
for attempt in range(1, settings.MAX_RETRIES + 1):
try:
logger.info(f"Попытка {attempt} загрузки {key_name} в S3")
#logger.info(f"Параметры S3: {S3_ENDPOINT_URL}, {S3_BUCKET_NAME}, {AWS_REGION}")
async with session.client(
"s3",
endpoint_url=settings.S3_ENDPOINT_URL,
aws_access_key_id=settings.AWS_ACCESS_KEY_ID,
aws_secret_access_key=settings.AWS_SECRET_ACCESS_KEY,
region_name=settings.AWS_REGION
) as s3:
await s3.put_object(Bucket=settings.S3_BUCKET_NAME, Key=key_name, Body=file_bytes)
logger.info(f"[OK] Файл {key_name} загружен в S3!")
return True
except Exception as e:
logger.exception(f"[ERROR] Попытка {attempt} для {key_name} не удалась: {e}")
if attempt < settings.MAX_RETRIES:
await asyncio.sleep(settings.RETRY_DELAY)
else:
logger.error(f"[FAILED] Файл {key_name} не удалось загрузить после {settings.MAX_RETRIES} попыток")
return False