#!/bin/bash # πŸš€ Script de Deployment Completo para Transformer Web Interface # Autor: AI Assistant # VersiΓ³n: 1.0 set -e # Salir en caso de error # Colores para output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # ConfiguraciΓ³n por defecto PROJECT_NAME="transformer-sentiment" WEB_PORT=8080 API_PORT=8000 PYTHON_ENV="venv" BROWSER_OPEN=true KILL_EXISTING=true # Funciones de utilidad log_info() { echo -e "${BLUE}[INFO]${NC} $1" } log_success() { echo -e "${GREEN}[SUCCESS]${NC} $1" } log_warning() { echo -e "${YELLOW}[WARNING]${NC} $1" } log_error() { echo -e "${RED}[ERROR]${NC} $1" } print_banner() { echo -e "${BLUE}" echo "╔══════════════════════════════════════════════════════════════════╗" echo "β•‘ πŸ€– TRANSFORMER WEB DEPLOYMENT 🌐 β•‘" echo "β•‘ β•‘" echo "β•‘ Desplegando interfaz web completa para anΓ‘lisis de sentimientos β•‘" echo "β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•" echo -e "${NC}" } show_help() { echo "Uso: $0 [OPCIONES]" echo "" echo "Opciones:" echo " -w, --web-port PORT Puerto para la interfaz web (default: 8080)" echo " -a, --api-port PORT Puerto para la API (default: 8000)" echo " -e, --env ENV_NAME Nombre del entorno virtual (default: venv)" echo " --no-browser No abrir browser automΓ‘ticamente" echo " --no-kill No matar procesos existentes" echo " --api-only Solo iniciar API" echo " --web-only Solo iniciar interfaz web" echo " --full Deployment completo (API + Web + Tests)" echo " --docker Usar Docker para deployment" echo " --production ConfiguraciΓ³n de producciΓ³n" echo " -h, --help Mostrar esta ayuda" echo "" echo "Ejemplos:" echo " $0 # Deployment estΓ‘ndar" echo " $0 --full # Deployment completo con tests" echo " $0 --web-only -w 3000 # Solo web en puerto 3000" echo " $0 --production # Deployment de producciΓ³n" } check_dependencies() { log_info "Verificando dependencias..." # Python if ! command -v python3 &> /dev/null; then log_error "Python3 no estΓ‘ instalado" exit 1 fi # pip if ! command -v pip3 &> /dev/null; then log_error "pip3 no estΓ‘ instalado" exit 1 fi log_success "Dependencias bΓ‘sicas verificadas" } check_ports() { log_info "Verificando disponibilidad de puertos..." if lsof -Pi :$WEB_PORT -sTCP:LISTEN -t >/dev/null 2>&1; then if [ "$KILL_EXISTING" = true ]; then log_warning "Puerto $WEB_PORT ocupado. Matando proceso..." lsof -ti:$WEB_PORT | xargs kill -9 2>/dev/null || true else log_error "Puerto $WEB_PORT ya estΓ‘ en uso" exit 1 fi fi if lsof -Pi :$API_PORT -sTCP:LISTEN -t >/dev/null 2>&1; then if [ "$KILL_EXISTING" = true ]; then log_warning "Puerto $API_PORT ocupado. Matando proceso..." lsof -ti:$API_PORT | xargs kill -9 2>/dev/null || true else log_error "Puerto $API_PORT ya estΓ‘ en uso" exit 1 fi fi log_success "Puertos disponibles" } setup_environment() { log_info "Configurando entorno Python..." # Activar entorno virtual si existe if [ -d "$PYTHON_ENV" ]; then source $PYTHON_ENV/bin/activate log_success "Entorno virtual activado: $PYTHON_ENV" else log_warning "Entorno virtual no encontrado: $PYTHON_ENV" log_info "Creando nuevo entorno virtual..." python3 -m venv $PYTHON_ENV source $PYTHON_ENV/bin/activate log_success "Nuevo entorno virtual creado y activado" fi # Instalar/actualizar dependencias if [ -f "requirements.txt" ]; then log_info "Instalando dependencias..." pip install -r requirements.txt log_success "Dependencias instaladas" else log_warning "requirements.txt no encontrado" fi } start_api() { log_info "Iniciando API en puerto $API_PORT..." # Verificar que el mΓ³dulo API existe if [ ! -f "src/api.py" ]; then log_error "API no encontrada en src/api.py" return 1 fi # Iniciar API en background nohup python -m src.api --host 127.0.0.1 --port $API_PORT > api.log 2>&1 & API_PID=$! echo $API_PID > api.pid # Esperar a que la API estΓ© lista log_info "Esperando a que la API estΓ© lista..." for i in {1..30}; do if curl -s http://127.0.0.1:$API_PORT/health > /dev/null 2>&1; then log_success "API iniciada correctamente (PID: $API_PID)" return 0 fi sleep 1 done log_error "La API no pudo iniciarse en 30 segundos" return 1 } start_web() { log_info "Iniciando interfaz web en puerto $WEB_PORT..." # Verificar que los archivos web existen if [ ! -f "web/index.html" ]; then log_error "Interfaz web no encontrada en web/index.html" return 1 fi # Hacer ejecutable el servidor si no lo es if [ -f "serve_web.py" ]; then chmod +x serve_web.py # Iniciar servidor web personalizado if [ "$BROWSER_OPEN" = true ]; then nohup python serve_web.py --port $WEB_PORT > web.log 2>&1 & else nohup python serve_web.py --port $WEB_PORT --no-browser > web.log 2>&1 & fi else # Usar servidor HTTP bΓ‘sico de Python cd web if [ "$BROWSER_OPEN" = true ]; then nohup python -m http.server $WEB_PORT > ../web.log 2>&1 & open http://localhost:$WEB_PORT 2>/dev/null || true else nohup python -m http.server $WEB_PORT > ../web.log 2>&1 & fi cd .. fi WEB_PID=$! echo $WEB_PID > web.pid # Verificar que el servidor web estΓ‘ funcionando sleep 2 if curl -s http://localhost:$WEB_PORT > /dev/null 2>&1; then log_success "Interfaz web iniciada correctamente (PID: $WEB_PID)" return 0 else log_error "La interfaz web no pudo iniciarse" return 1 fi } run_tests() { log_info "Ejecutando tests del proyecto..." # Tests de API if [ -d "tests" ]; then python -m pytest tests/ -v else log_warning "Directorio de tests no encontrado" fi # Test de health check if curl -s http://127.0.0.1:$API_PORT/health | grep -q "healthy"; then log_success "API health check: βœ… PASS" else log_error "API health check: ❌ FAIL" fi # Test de interfaz web if curl -s http://localhost:$WEB_PORT | grep -q "Transformer"; then log_success "Web interface check: βœ… PASS" else log_error "Web interface check: ❌ FAIL" fi } show_status() { echo "" echo -e "${GREEN}╔══════════════════════════════════════════════════════════════════╗${NC}" echo -e "${GREEN}β•‘ πŸŽ‰ DEPLOYMENT COMPLETADO πŸŽ‰ β•‘${NC}" echo -e "${GREEN}β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•${NC}" echo "" echo -e "${BLUE}πŸ“Š Estado de servicios:${NC}" # Verificar API if curl -s http://127.0.0.1:$API_PORT/health > /dev/null 2>&1; then echo -e " 🟒 API: ${GREEN}RUNNING${NC} en http://127.0.0.1:$API_PORT" echo -e " πŸ“š Docs: http://127.0.0.1:$API_PORT/docs" else echo -e " πŸ”΄ API: ${RED}DOWN${NC}" fi # Verificar Web if curl -s http://localhost:$WEB_PORT > /dev/null 2>&1; then echo -e " 🟒 Web: ${GREEN}RUNNING${NC} en http://localhost:$WEB_PORT" else echo -e " πŸ”΄ Web: ${RED}DOWN${NC}" fi echo "" echo -e "${BLUE}πŸ”§ Comandos ΓΊtiles:${NC}" echo -e " ${YELLOW}Ver logs API:${NC} tail -f api.log" echo -e " ${YELLOW}Ver logs Web:${NC} tail -f web.log" echo -e " ${YELLOW}Parar servicios:${NC} $0 --stop" echo -e " ${YELLOW}Reiniciar:${NC} $0 --restart" echo "" if [ "$BROWSER_OPEN" = true ]; then echo -e "${GREEN}🌐 Abriendo navegador...${NC}" if command -v open &> /dev/null; then open http://localhost:$WEB_PORT elif command -v xdg-open &> /dev/null; then xdg-open http://localhost:$WEB_PORT fi fi } stop_services() { log_info "Deteniendo servicios..." # Parar API if [ -f "api.pid" ]; then API_PID=$(cat api.pid) kill $API_PID 2>/dev/null || true rm api.pid log_success "API detenida" fi # Parar Web if [ -f "web.pid" ]; then WEB_PID=$(cat web.pid) kill $WEB_PID 2>/dev/null || true rm web.pid log_success "Interfaz web detenida" fi # Limpiar puertos por si acaso lsof -ti:$API_PORT | xargs kill -9 2>/dev/null || true lsof -ti:$WEB_PORT | xargs kill -9 2>/dev/null || true } create_production_config() { log_info "Creando configuraciΓ³n de producciΓ³n..." # Nginx config cat > nginx.conf << EOF server { listen 80; server_name localhost; # Interfaz web location / { root $(pwd)/web; index index.html; try_files \$uri \$uri/ /index.html; } # API proxy location /api/ { proxy_pass http://127.0.0.1:$API_PORT/; proxy_set_header Host \$host; proxy_set_header X-Real-IP \$remote_addr; proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; } } EOF # Docker compose para producciΓ³n cat > docker-compose.prod.yml << EOF version: '3.8' services: api: build: . ports: - "$API_PORT:$API_PORT" environment: - ENV=production restart: unless-stopped web: image: nginx:alpine ports: - "80:80" volumes: - ./web:/usr/share/nginx/html - ./nginx.conf:/etc/nginx/conf.d/default.conf depends_on: - api restart: unless-stopped EOF log_success "ConfiguraciΓ³n de producciΓ³n creada" } docker_deployment() { log_info "Iniciando deployment con Docker..." if ! command -v docker &> /dev/null; then log_error "Docker no estΓ‘ instalado" exit 1 fi # Build imagen docker build -t $PROJECT_NAME . # Run con docker-compose if [ -f "docker-compose.yml" ]; then docker-compose up -d log_success "Servicios iniciados con Docker" else log_error "docker-compose.yml no encontrado" exit 1 fi } # Procesar argumentos while [[ $# -gt 0 ]]; do case $1 in -w|--web-port) WEB_PORT="$2" shift 2 ;; -a|--api-port) API_PORT="$2" shift 2 ;; -e|--env) PYTHON_ENV="$2" shift 2 ;; --no-browser) BROWSER_OPEN=false shift ;; --no-kill) KILL_EXISTING=false shift ;; --api-only) MODE="api-only" shift ;; --web-only) MODE="web-only" shift ;; --full) MODE="full" shift ;; --docker) MODE="docker" shift ;; --production) MODE="production" shift ;; --stop) stop_services exit 0 ;; --restart) stop_services sleep 2 # Continuar con el deployment normal shift ;; -h|--help) show_help exit 0 ;; *) log_error "OpciΓ³n desconocida: $1" show_help exit 1 ;; esac done # Banner de inicio print_banner # Verificaciones iniciales check_dependencies check_ports # Deployment segΓΊn modo case ${MODE:-"standard"} in "api-only") setup_environment start_api ;; "web-only") start_web ;; "docker") docker_deployment ;; "production") create_production_config setup_environment start_api start_web ;; "full") setup_environment start_api start_web run_tests ;; *) setup_environment start_api start_web ;; esac # Mostrar estado final show_status # Cleanup en exit trap 'log_info "Limpiando..."; stop_services' EXIT # Mantener script corriendo log_info "Presiona Ctrl+C para detener todos los servicios..." while true; do sleep 10 # Verificar que los servicios siguen corriendo if [ "${MODE:-"standard"}" != "web-only" ]; then if ! curl -s http://127.0.0.1:$API_PORT/health > /dev/null 2>&1; then log_error "API caΓ­da. Reiniciando..." start_api fi fi if [ "${MODE:-"standard"}" != "api-only" ]; then if ! curl -s http://localhost:$WEB_PORT > /dev/null 2>&1; then log_error "Interfaz web caΓ­da. Reiniciando..." start_web fi fi done