diegobeyl/backtesting
2
1#!/bin/bash2 3# Backtesting App V2 - Launcher Script para macOS/Linux4# Inicia API y Streamlit con un solo comando5 6# Configuración de colores para output7RED='\033[0;31m'8GREEN='\033[0;32m'9YELLOW='\033[1;33m'10NC='\033[0m' # No Color11 12# Flag para control de navegador13NO_BROWSER=false14 15# Procesar argumentos16while [[ "$#" -gt 0 ]]; do17 case $1 in18 --no-browser) NO_BROWSER=true ;;19 *) echo "Argumento desconocido: $1"; exit 1 ;;20 esac21 shift22done23 24PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"25 26echo ""27echo "========================================"28echo " BACKTESTING APP V2 - LAUNCHER"29echo "========================================"30echo ""31 32# Verificar que estamos en el directorio correcto33if [ ! -f "$PROJECT_ROOT/.env" ]; then34 echo -e "${RED}ERROR: Archivo .env no encontrado${NC}"35 echo -e "${YELLOW} Ejecuta primero: ./setup.sh${NC}"36 echo ""37 exit 138fi39 40# Verificar entorno virtual41if [ ! -f "$PROJECT_ROOT/venv/bin/python" ]; then42 echo -e "${RED}ERROR: Entorno virtual no encontrado${NC}"43 echo -e "${YELLOW} Ejecuta primero: ./setup.sh${NC}"44 echo ""45 exit 146fi47 48echo -e "${GREEN}OK - Verificaciones pasadas${NC}"49echo ""50 51# Crear directorios necesarios52mkdir -p "$PROJECT_ROOT/logs" "$PROJECT_ROOT/cache"53 54# Activar entorno virtual55source "$PROJECT_ROOT/venv/bin/activate"56 57# Función para limpiar procesos al salir58cleanup() {59 echo ""60 echo -e "${YELLOW}Deteniendo servicios...${NC}"61 62 if [ ! -z "$API_PID" ] && kill -0 $API_PID 2>/dev/null; then63 echo " Deteniendo API (PID: $API_PID)..."64 kill $API_PID 2>/dev/null65 fi66 67 if [ ! -z "$STREAMLIT_PID" ] && kill -0 $STREAMLIT_PID 2>/dev/null; then68 echo " Deteniendo Streamlit (PID: $STREAMLIT_PID)..."69 kill $STREAMLIT_PID 2>/dev/null70 fi71 72 # Esperar a que los procesos terminen73 sleep 274 75 # Forzar terminación si aún están activos76 if [ ! -z "$API_PID" ] && kill -0 $API_PID 2>/dev/null; then77 kill -9 $API_PID 2>/dev/null78 fi79 80 if [ ! -z "$STREAMLIT_PID" ] && kill -0 $STREAMLIT_PID 2>/dev/null; then81 kill -9 $STREAMLIT_PID 2>/dev/null82 fi83 84 echo ""85 echo -e "${GREEN}Servicios detenidos correctamente${NC}"86 echo ""87 exit 088}89 90# Registrar función de limpieza para Ctrl+C y salida91trap cleanup SIGINT SIGTERM EXIT92 93# Matar procesos previos si existen94echo -e "${YELLOW}Verificando procesos existentes...${NC}"95 96# Buscar y matar TODOS los procesos uvicorn y streamlit97pkill -9 -f "uvicorn" 2>/dev/null || true98pkill -9 -f "streamlit" 2>/dev/null || true99sleep 2100 101# Limpiar logs anteriores para evitar confusión102> logs/api.log 2>/dev/null || true103> logs/streamlit.log 2>/dev/null || true104 105echo -e "${GREEN}Procesos previos terminados, logs limpiados${NC}"106 107echo ""108echo "========================================"109echo " Iniciando API Backend (FastAPI)"110echo "========================================"111echo ""112 113# Iniciar API en segundo plano (sin --reload para evitar múltiples workers)114cd "$PROJECT_ROOT"115python -m uvicorn api.main:app --host 0.0.0.0 --port 8000 > /dev/null 2>&1 &116API_PID=$!117 118echo -e "${GREEN}API iniciada (PID: $API_PID)${NC}"119echo " URL: http://localhost:8000"120echo " Docs: http://localhost:8000/docs"121echo " Logs: logs/api.log"122echo ""123 124# Esperar a que la API esté lista125echo "Esperando a que la API esté lista..."126for i in {1..30}; do127 if curl -s http://localhost:8000/health > /dev/null 2>&1; then128 echo -e "${GREEN}API lista!${NC}"129 break130 fi131 if [ $i -eq 30 ]; then132 echo -e "${RED}ERROR: La API no respondió a tiempo${NC}"133 exit 1134 fi135 sleep 1136 echo -n "."137done138echo ""139 140echo ""141echo "========================================"142echo " Iniciando Frontend (Streamlit)"143echo "========================================"144echo ""145 146# Configurar Streamlit para no abrir navegador automáticamente si se especifica147if [ "$NO_BROWSER" = true ]; then148 export STREAMLIT_BROWSER_GATHER_USAGE_STATS=false149 BROWSER_FLAG="--server.headless=true"150else151 BROWSER_FLAG=""152fi153 154# Iniciar Streamlit en segundo plano155streamlit run backtesting_app/app.py \156 --server.port=8501 \157 --server.address=0.0.0.0 \158 $BROWSER_FLAG \159 > logs/streamlit.log 2>&1 &160STREAMLIT_PID=$!161 162echo -e "${GREEN}Streamlit iniciado (PID: $STREAMLIT_PID)${NC}"163echo " URL: http://localhost:8501"164echo " Logs: logs/streamlit.log"165echo ""166 167# Esperar a que Streamlit esté listo168echo "Esperando a que Streamlit esté listo..."169for i in {1..30}; do170 if curl -s http://localhost:8501/_stcore/health > /dev/null 2>&1; then171 echo -e "${GREEN}Streamlit listo!${NC}"172 break173 fi174 sleep 1175 echo -n "."176done177echo ""178 179echo ""180echo "========================================"181echo " APLICACIÓN INICIADA"182echo "========================================"183echo ""184echo -e "${GREEN}Servicios corriendo:${NC}"185echo " API Backend: http://localhost:8000"186echo " API Docs: http://localhost:8000/docs"187echo " Frontend: http://localhost:8501"188echo ""189echo -e "${YELLOW}Presiona Ctrl+C para detener todos los servicios${NC}"190echo ""191 192# Abrir navegador si no se especificó --no-browser193if [ "$NO_BROWSER" = false ]; then194 sleep 2195 open http://localhost:8501 2>/dev/null || true196fi197 198# Mantener el script corriendo sin mostrar logs (más limpio)199echo "========================================"200echo " APLICACIÓN EJECUTÁNDOSE"201echo "========================================"202echo ""203echo -e "${GREEN}Los servicios están corriendo en segundo plano.${NC}"204echo -e "${YELLOW}Presiona Ctrl+C para detener todos los servicios${NC}"205echo ""206 207# Mantener el script corriendo208while true; do209 sleep 1210done211 