Automated Action 92e4d992b2 Implement complete AI video dubbing backend with FastAPI
Features:
- JWT authentication with user registration and login
- Video upload to Amazon S3 with file validation (200MB limit)
- Audio transcription using OpenAI Whisper API
- Text translation using GPT-4 API
- Voice cloning and audio synthesis using ElevenLabs API
- Video processing with ffmpeg for audio replacement
- Complete SQLite database with proper models and migrations
- Background task processing for long-running operations
- Health endpoint and comprehensive API documentation

Tech stack:
- FastAPI with SQLAlchemy ORM
- SQLite database with Alembic migrations
- Amazon S3 for file storage
- OpenAI APIs for transcription and translation
- ElevenLabs API for voice cloning
- ffmpeg for video processing
- JWT authentication with bcrypt password hashing
2025-06-24 17:56:12 +00:00

61 lines
1.9 KiB
Python

import os
import boto3
from botocore.exceptions import ClientError
from typing import Optional
import logging
logger = logging.getLogger(__name__)
AWS_ACCESS_KEY_ID = os.getenv("AWS_ACCESS_KEY_ID")
AWS_SECRET_ACCESS_KEY = os.getenv("AWS_SECRET_ACCESS_KEY")
AWS_REGION = os.getenv("AWS_REGION", "us-east-1")
S3_BUCKET_NAME = os.getenv("S3_BUCKET_NAME")
if not all([AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, S3_BUCKET_NAME]):
logger.warning("AWS credentials or S3 bucket name not configured")
s3_client = boto3.client(
's3',
aws_access_key_id=AWS_ACCESS_KEY_ID,
aws_secret_access_key=AWS_SECRET_ACCESS_KEY,
region_name=AWS_REGION
) if AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY else None
async def upload_file_to_s3(file_content: bytes, file_name: str, content_type: str) -> Optional[str]:
if not s3_client or not S3_BUCKET_NAME:
logger.error("S3 client not configured properly")
return None
try:
s3_client.put_object(
Bucket=S3_BUCKET_NAME,
Key=file_name,
Body=file_content,
ContentType=content_type
)
s3_url = f"https://{S3_BUCKET_NAME}.s3.{AWS_REGION}.amazonaws.com/{file_name}"
return s3_url
except ClientError as e:
logger.error(f"Error uploading file to S3: {e}")
return None
async def download_file_from_s3(file_name: str) -> Optional[bytes]:
if not s3_client or not S3_BUCKET_NAME:
logger.error("S3 client not configured properly")
return None
try:
response = s3_client.get_object(Bucket=S3_BUCKET_NAME, Key=file_name)
return response['Body'].read()
except ClientError as e:
logger.error(f"Error downloading file from S3: {e}")
return None
def get_s3_file_url(file_name: str) -> str:
return f"https://{S3_BUCKET_NAME}.s3.{AWS_REGION}.amazonaws.com/{file_name}"