#!/bin/bash # Universal Deployment Script for Multi-Lingual Catalog Translator # Works on macOS, Linux, Windows (with WSL), and cloud platforms set -e # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # Configuration PROJECT_NAME="multilingual-catalog-translator" DEFAULT_PORT=8501 BACKEND_PORT=8001 # Function to print colored output print_status() { echo -e "${BLUE}[INFO]${NC} $1" } print_success() { echo -e "${GREEN}[SUCCESS]${NC} $1" } print_warning() { echo -e "${YELLOW}[WARNING]${NC} $1" } print_error() { echo -e "${RED}[ERROR]${NC} $1" } # Function to detect operating system detect_os() { if [[ "$OSTYPE" == "linux-gnu"* ]]; then echo "linux" elif [[ "$OSTYPE" == "darwin"* ]]; then echo "macos" elif [[ "$OSTYPE" == "cygwin" ]] || [[ "$OSTYPE" == "msys" ]] || [[ "$OSTYPE" == "win32" ]]; then echo "windows" else echo "unknown" fi } # Function to check if command exists command_exists() { command -v "$1" >/dev/null 2>&1 } # Function to install dependencies based on OS install_dependencies() { local os=$(detect_os) print_status "Installing dependencies for $os..." case $os in "linux") if command_exists apt-get; then sudo apt-get update sudo apt-get install -y python3 python3-pip python3-venv curl elif command_exists yum; then sudo yum install -y python3 python3-pip curl elif command_exists pacman; then sudo pacman -S python python-pip curl fi ;; "macos") if command_exists brew; then brew install python3 else print_warning "Homebrew not found. Please install Python 3 manually." fi ;; "windows") print_warning "Please ensure Python 3 is installed on Windows." ;; esac } # Function to check Python installation check_python() { if command_exists python3; then PYTHON_CMD="python3" elif command_exists python; then PYTHON_CMD="python" else print_error "Python not found. Installing..." install_dependencies return 1 fi print_success "Python found: $PYTHON_CMD" } # Function to create virtual environment setup_venv() { print_status "Setting up virtual environment..." if [ ! -d "venv" ]; then $PYTHON_CMD -m venv venv print_success "Virtual environment created" else print_status "Virtual environment already exists" fi # Activate virtual environment if [[ "$OSTYPE" == "msys" ]] || [[ "$OSTYPE" == "win32" ]]; then source venv/Scripts/activate else source venv/bin/activate fi print_success "Virtual environment activated" } # Function to install Python packages install_packages() { print_status "Installing Python packages..." # Upgrade pip pip install --upgrade pip # Install requirements if [ -f "requirements.txt" ]; then pip install -r requirements.txt else print_error "requirements.txt not found" exit 1 fi print_success "Python packages installed" } # Function to check Docker installation check_docker() { if command_exists docker; then print_success "Docker found" return 0 else print_warning "Docker not found" return 1 fi } # Function to deploy with Docker deploy_docker() { print_status "Deploying with Docker..." # Check if docker-compose exists if command_exists docker-compose; then COMPOSE_CMD="docker-compose" elif command_exists docker && docker compose version >/dev/null 2>&1; then COMPOSE_CMD="docker compose" else print_error "Docker Compose not found" exit 1 fi # Stop existing containers $COMPOSE_CMD down # Build and start containers $COMPOSE_CMD up --build -d print_success "Docker deployment completed" print_status "Frontend available at: http://localhost:8501" print_status "Backend API available at: http://localhost:8001" } # Function to deploy standalone (without Docker) deploy_standalone() { print_status "Deploying standalone application..." # Setup virtual environment setup_venv # Install packages install_packages # Start the application print_status "Starting application..." # Check if we should run full-stack or standalone if [ -d "backend" ] && [ -f "backend/main.py" ]; then print_status "Starting backend server..." cd backend $PYTHON_CMD -m uvicorn main:app --host 0.0.0.0 --port $BACKEND_PORT & BACKEND_PID=$! cd .. # Wait a moment for backend to start sleep 3 print_status "Starting frontend..." cd frontend export API_BASE_URL="http://localhost:$BACKEND_PORT" streamlit run app.py --server.port $DEFAULT_PORT --server.address 0.0.0.0 & FRONTEND_PID=$! cd .. print_success "Full-stack deployment completed" print_status "Frontend: http://localhost:$DEFAULT_PORT" print_status "Backend API: http://localhost:$BACKEND_PORT" # Save PIDs for cleanup echo "$BACKEND_PID" > .backend_pid echo "$FRONTEND_PID" > .frontend_pid else # Run standalone version streamlit run app.py --server.port $DEFAULT_PORT --server.address 0.0.0.0 & APP_PID=$! echo "$APP_PID" > .app_pid print_success "Standalone deployment completed" print_status "Application: http://localhost:$DEFAULT_PORT" fi } # Function to deploy to Hugging Face Spaces deploy_hf_spaces() { print_status "Preparing for Hugging Face Spaces deployment..." # Check if git is available if ! command_exists git; then print_error "Git not found. Please install git." exit 1 fi # Create Hugging Face Spaces configuration cat > README.md << 'EOF' --- title: Multi-Lingual Product Catalog Translator emoji: 🌐 colorFrom: blue colorTo: green sdk: streamlit sdk_version: 1.28.0 app_file: app.py pinned: false license: mit --- # Multi-Lingual Product Catalog Translator AI-powered translation service for e-commerce product catalogs using IndicTrans2 by AI4Bharat. ## Features - Support for 15+ Indian languages - Real-time translation - Product catalog optimization - Neural machine translation ## Usage Simply upload your product catalog and select target languages for translation. EOF print_success "Hugging Face Spaces configuration created" print_status "To deploy to HF Spaces:" print_status "1. Create a new Space at https://huggingface.co/spaces" print_status "2. Clone your space repository" print_status "3. Copy all files to the space repository" print_status "4. Push to deploy" } # Function to deploy to cloud platforms deploy_cloud() { local platform=$1 case $platform in "railway") print_status "Preparing for Railway deployment..." # Create railway.json if it doesn't exist if [ ! -f "railway.json" ]; then cat > railway.json << 'EOF' { "$schema": "https://railway.app/railway.schema.json", "build": { "builder": "DOCKERFILE", "dockerfilePath": "Dockerfile.standalone" }, "deploy": { "startCommand": "streamlit run app.py --server.port $PORT --server.address 0.0.0.0", "healthcheckPath": "/_stcore/health", "healthcheckTimeout": 100, "restartPolicyType": "ON_FAILURE", "restartPolicyMaxRetries": 10 } } EOF fi print_success "Railway configuration created" ;; "render") print_status "Preparing for Render deployment..." # Create render.yaml if it doesn't exist if [ ! -f "render.yaml" ]; then cat > render.yaml << 'EOF' services: - type: web name: multilingual-translator env: docker dockerfilePath: ./Dockerfile.standalone plan: starter healthCheckPath: /_stcore/health envVars: - key: PORT value: 8501 EOF fi print_success "Render configuration created" ;; "heroku") print_status "Preparing for Heroku deployment..." # Create Procfile if it doesn't exist if [ ! -f "Procfile" ]; then echo "web: streamlit run app.py --server.port \$PORT --server.address 0.0.0.0" > Procfile fi print_success "Heroku configuration created" ;; esac } # Function to show deployment status show_status() { print_status "Checking deployment status..." # Check if services are running if [ -f ".app_pid" ]; then local pid=$(cat .app_pid) if ps -p $pid > /dev/null; then print_success "Standalone app is running (PID: $pid)" else print_warning "Standalone app is not running" fi fi if [ -f ".backend_pid" ]; then local backend_pid=$(cat .backend_pid) if ps -p $backend_pid > /dev/null; then print_success "Backend is running (PID: $backend_pid)" else print_warning "Backend is not running" fi fi if [ -f ".frontend_pid" ]; then local frontend_pid=$(cat .frontend_pid) if ps -p $frontend_pid > /dev/null; then print_success "Frontend is running (PID: $frontend_pid)" else print_warning "Frontend is not running" fi fi # Check Docker containers if command_exists docker; then local containers=$(docker ps --filter "name=${PROJECT_NAME}" --format "table {{.Names}}\t{{.Status}}") if [ ! -z "$containers" ]; then print_status "Docker containers:" echo "$containers" fi fi } # Function to stop services stop_services() { print_status "Stopping services..." # Stop standalone app if [ -f ".app_pid" ]; then local pid=$(cat .app_pid) if ps -p $pid > /dev/null; then kill $pid print_success "Stopped standalone app" fi rm -f .app_pid fi # Stop backend if [ -f ".backend_pid" ]; then local backend_pid=$(cat .backend_pid) if ps -p $backend_pid > /dev/null; then kill $backend_pid print_success "Stopped backend" fi rm -f .backend_pid fi # Stop frontend if [ -f ".frontend_pid" ]; then local frontend_pid=$(cat .frontend_pid) if ps -p $frontend_pid > /dev/null; then kill $frontend_pid print_success "Stopped frontend" fi rm -f .frontend_pid fi # Stop Docker containers if command_exists docker; then if command_exists docker-compose; then docker-compose down elif docker compose version >/dev/null 2>&1; then docker compose down fi fi print_success "All services stopped" } # Function to show help show_help() { echo "Multi-Lingual Catalog Translator - Universal Deployment Script" echo "" echo "Usage: ./deploy.sh [COMMAND] [OPTIONS]" echo "" echo "Commands:" echo " start Start the application (default)" echo " docker Deploy using Docker" echo " standalone Deploy without Docker" echo " hf-spaces Prepare for Hugging Face Spaces" echo " cloud PLATFORM Prepare for cloud deployment (railway|render|heroku)" echo " status Show deployment status" echo " stop Stop all services" echo " help Show this help message" echo "" echo "Examples:" echo " ./deploy.sh # Quick start (auto-detect best method)" echo " ./deploy.sh docker # Deploy with Docker" echo " ./deploy.sh standalone # Deploy without Docker" echo " ./deploy.sh cloud railway # Prepare for Railway deployment" echo " ./deploy.sh hf-spaces # Prepare for HF Spaces" echo " ./deploy.sh status # Check status" echo " ./deploy.sh stop # Stop all services" } # Main execution main() { echo "========================================" echo " Multi-Lingual Catalog Translator" echo " Universal Deployment Pipeline" echo "========================================" echo "" local command=${1:-"start"} case $command in "start") print_status "Starting automatic deployment..." check_python if check_docker; then deploy_docker else deploy_standalone fi ;; "docker") if check_docker; then deploy_docker else print_error "Docker not available. Use 'standalone' deployment." exit 1 fi ;; "standalone") check_python deploy_standalone ;; "hf-spaces") deploy_hf_spaces ;; "cloud") if [ -z "$2" ]; then print_error "Please specify cloud platform: railway, render, or heroku" exit 1 fi deploy_cloud "$2" ;; "status") show_status ;; "stop") stop_services ;; "help"|"-h"|"--help") show_help ;; *) print_error "Unknown command: $command" show_help exit 1 ;; esac } # Run main function with all arguments main "$@"