File size: 6,379 Bytes
dbced4f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#!/usr/bin/env bash
# start.sh β€” Start the SegVision stack locally
# Run from: video-seg-app/ directory
# Usage: bash start.sh

set -e
CYAN='\033[0;36m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; RED='\033[0;31m'; NC='\033[0m'

PROJECT_DIR="$(cd "$(dirname "$0")" && pwd)"
BACKEND_DIR="$PROJECT_DIR/backend"
FRONTEND_DIR="$PROJECT_DIR/frontend"
PIDS=()

# ── Detect Python / pip (Anaconda preferred) ────────────────────────────────
PYTHON=""
UVICORN=""
CELERY=""
for candidate in /opt/anaconda3/bin/python3 /opt/homebrew/bin/python3 python3 python; do
    if command -v "$candidate" &>/dev/null 2>&1; then
        PYTHON=$(command -v "$candidate")
        break
    fi
done
for candidate in /opt/anaconda3/bin/uvicorn /opt/homebrew/bin/uvicorn "$HOME/Library/Python/3.9/bin/uvicorn" uvicorn; do
    if [ -x "$candidate" ]; then UVICORN="$candidate"; break; fi
done
for candidate in /opt/anaconda3/bin/celery /opt/homebrew/bin/celery "$HOME/Library/Python/3.9/bin/celery" celery; do
    if [ -x "$candidate" ]; then CELERY="$candidate"; break; fi
done

echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo -e "${CYAN}  SegVision β€” AI Video Segmentation${NC}"
echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo ""
echo -e "  Python : ${GREEN}$PYTHON${NC}"
echo -e "  Uvicorn: ${GREEN}${UVICORN:-NOT FOUND}${NC}"
echo -e "  Celery : ${GREEN}${CELERY:-NOT FOUND}${NC}"
echo ""

if [ -z "$UVICORN" ]; then
    echo -e "${RED}[ERROR]${NC} uvicorn not found. Run:"
    echo -e "  /opt/anaconda3/bin/pip install fastapi 'uvicorn[standard]' 'celery[redis]' redis python-multipart opencv-python-headless"
    exit 1
fi

cleanup() {
    echo -e "\n${YELLOW}Shutting down all services …${NC}"
    for pid in "${PIDS[@]}"; do kill "$pid" 2>/dev/null || true; done
    # Also clean up any stray processes
    pkill -f "celery -A tasks" 2>/dev/null || true
    pkill -f "uvicorn main:app" 2>/dev/null || true
    exit 0
}
trap cleanup SIGINT SIGTERM

# ── Kill any stale processes from previous runs ───────────────────────────────
echo -e "${YELLOW}Stopping any existing services …${NC}"
pkill -f "celery -A tasks" 2>/dev/null && echo "  Stopped old Celery worker" || true
pkill -f "uvicorn main:app" 2>/dev/null && echo "  Stopped old Uvicorn server" || true
sleep 1

# ── 1. Redis ─────────────────────────────────────────────────────────────────
echo -e "${GREEN}[1/4]${NC} Checking Redis …"
if redis-cli ping &>/dev/null 2>&1; then
    echo "  βœ“ Redis already running on :6379"
else
    # Try docker (Desktop app path first, then PATH)
    DOCKER_BIN=$(command -v docker 2>/dev/null || ls /Applications/Docker.app/Contents/Resources/bin/docker 2>/dev/null || echo "")
    if [ -n "$DOCKER_BIN" ]; then
        "$DOCKER_BIN" run -d --rm --name seg_redis -p 6379:6379 redis:7-alpine &>/dev/null || \
        "$DOCKER_BIN" start seg_redis &>/dev/null || true
        sleep 2
        echo "  βœ“ Redis started via Docker"
    else
        echo -e "  ${RED}[ERROR]${NC} Redis not found. Start Docker Desktop or run: brew install redis && redis-server"
        exit 1
    fi
fi

# ── 2. Celery Worker ─────────────────────────────────────────────────────────
echo -e "${GREEN}[2/4]${NC} Starting Celery worker (updated code) …"
cd "$BACKEND_DIR"
CELERY_LOG="/tmp/celery_worker.log"
"$CELERY" -A tasks worker --loglevel=info --concurrency=1 > "$CELERY_LOG" 2>&1 &
CELERY_PID=$!
PIDS+=($CELERY_PID)
sleep 2
if kill -0 $CELERY_PID 2>/dev/null; then
    echo "  βœ“ Worker PID=$CELERY_PID (logs: $CELERY_LOG)"
else
    echo -e "  ${RED}[ERROR]${NC} Celery failed to start. Check: tail $CELERY_LOG"
    exit 1
fi

# ── 3. FastAPI Server ─────────────────────────────────────────────────────────
echo -e "${GREEN}[3/4]${NC} Starting FastAPI on :8000 (with hot-reload) …"
"$UVICORN" main:app --host 0.0.0.0 --port 8000 --reload &
FASTAPI_PID=$!
PIDS+=($FASTAPI_PID)
echo "  βœ“ Backend PID=$FASTAPI_PID"
echo "  ⚠️  Note: FastAPI hot-reloads on code save, but Celery does NOT."
echo "     Restart this script after changing inference.py or tasks.py"

# ── 4. Frontend ───────────────────────────────────────────────────────────────
cd "$FRONTEND_DIR"
# Load nvm if available
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
NPM_BIN=$(command -v npm 2>/dev/null || echo "")

if [ -n "$NPM_BIN" ]; then
    echo -e "${GREEN}[4/4]${NC} Starting Next.js on :3000 …"
    [ ! -d "node_modules" ] && "$NPM_BIN" install --silent
    "$NPM_BIN" run dev &
    PIDS+=($!)
    echo "  βœ“ Frontend PID=$!"
    FRONTEND_URL="http://localhost:3000"
else
    echo -e "${YELLOW}[4/4]${NC} npm not found β€” skipping Next.js"
    echo "     Install Node.js: curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash"
    echo "     Then: export NVM_DIR=~/.nvm && . \$NVM_DIR/nvm.sh && nvm install 20"
    FRONTEND_URL="N/A (install Node.js)"
fi

echo ""
echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo -e "  🎬 Frontend : ${GREEN}${FRONTEND_URL}${NC}"
echo -e "  ⚑ Backend  : ${GREEN}http://localhost:8000${NC}"
echo -e "  πŸ“„ API Docs : ${GREEN}http://localhost:8000/docs${NC}"
echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo -e "  Press ${YELLOW}Ctrl+C${NC} to stop all services"
echo ""

wait