feat: add dev command for hot-reload (uvicorn --reload + Vite HMR)

- manage.sh: dev command starts uvicorn --reload on :8503 and Vite dev
  server (auto-port from 5173); kills API on EXIT/INT/TERM trap
- manage.sh: ENV_UI defaults to 'cf' env (overridable via AVOCET_ENV)
- vite.config.ts: add server.proxy to forward /api to :8503 so Vite
  dev server can reach the backend without CORS issues
This commit is contained in:
pyr0ball 2026-04-08 19:43:40 -07:00
parent 09e334359f
commit f17aae3bd2
2 changed files with 48 additions and 1 deletions

View file

@ -19,7 +19,7 @@ LOG_FILE="${LOG_DIR}/label_tool.log"
DEFAULT_PORT=8503 DEFAULT_PORT=8503
CONDA_BASE="${CONDA_BASE:-/devl/miniconda3}" CONDA_BASE="${CONDA_BASE:-/devl/miniconda3}"
ENV_UI="job-seeker" ENV_UI="${AVOCET_ENV:-cf}"
ENV_BM="job-seeker-classifiers" ENV_BM="job-seeker-classifiers"
PYTHON_BM="${CONDA_BASE}/envs/${ENV_BM}/bin/python" PYTHON_BM="${CONDA_BASE}/envs/${ENV_BM}/bin/python"
PYTHON_UI="${CONDA_BASE}/envs/${ENV_UI}/bin/python" PYTHON_UI="${CONDA_BASE}/envs/${ENV_UI}/bin/python"
@ -91,6 +91,7 @@ usage() {
echo -e " ${GREEN}compare [args]${NC} Shortcut: --compare [args]" echo -e " ${GREEN}compare [args]${NC} Shortcut: --compare [args]"
echo "" echo ""
echo " Dev:" echo " Dev:"
echo -e " ${GREEN}dev${NC} Hot-reload: uvicorn --reload (:8503) + Vite HMR (:5173)"
echo -e " ${GREEN}test${NC} Run pytest suite" echo -e " ${GREEN}test${NC} Run pytest suite"
echo "" echo ""
echo " Port defaults to ${DEFAULT_PORT}; auto-increments if occupied." echo " Port defaults to ${DEFAULT_PORT}; auto-increments if occupied."
@ -165,6 +166,47 @@ case "$CMD" in
exec bash "$0" start exec bash "$0" start
;; ;;
dev)
API_PORT=8503
VITE_PORT=5173
DEV_API_PID_FILE=".avocet-dev-api.pid"
mkdir -p "$LOG_DIR"
DEV_API_LOG="${LOG_DIR}/dev-api.log"
if [[ -f "$DEV_API_PID_FILE" ]] && kill -0 "$(<"$DEV_API_PID_FILE")" 2>/dev/null; then
warn "Dev API already running (PID $(<"$DEV_API_PID_FILE"))"
else
info "Starting uvicorn with --reload on port ${API_PORT}"
nohup "$PYTHON_UI" -m uvicorn app.api:app \
--host 0.0.0.0 --port "$API_PORT" --reload \
>> "$DEV_API_LOG" 2>&1 &
echo $! > "$DEV_API_PID_FILE"
# Wait for API to bind
for _i in $(seq 1 20); do
sleep 0.5
(echo "" >/dev/tcp/127.0.0.1/"$API_PORT") 2>/dev/null && break
if ! kill -0 "$(<"$DEV_API_PID_FILE")" 2>/dev/null; then
rm -f "$DEV_API_PID_FILE"
error "Dev API died during startup. Check ${DEV_API_LOG}"
fi
done
success "API (hot-reload) → http://localhost:${API_PORT}"
fi
# Kill API on exit (Ctrl+C or Vite exits)
_cleanup_dev() {
local pid
pid=$(<"$DEV_API_PID_FILE" 2>/dev/null || true)
[[ -n "$pid" ]] && kill "$pid" 2>/dev/null && rm -f "$DEV_API_PID_FILE"
info "Dev servers stopped."
}
trap _cleanup_dev EXIT INT TERM
info "Starting Vite HMR on port ${VITE_PORT} (proxy /api → :${API_PORT})…"
success "Frontend (HMR) → http://localhost:${VITE_PORT}"
(cd web && npm run dev -- --host 0.0.0.0 --port "$VITE_PORT")
;;
open) open)
URL="http://localhost:8503" URL="http://localhost:8503"
info "Opening ${URL}" info "Opening ${URL}"

View file

@ -4,6 +4,11 @@ import UnoCSS from 'unocss/vite'
export default defineConfig({ export default defineConfig({
plugins: [vue(), UnoCSS()], plugins: [vue(), UnoCSS()],
server: {
proxy: {
'/api': 'http://localhost:8503',
},
},
test: { test: {
environment: 'jsdom', environment: 'jsdom',
globals: true, globals: true,