Text Extraction Done, UI Fixes Done, Extracted Template Layout Saved in DB
This commit is contained in:
285
run_docengine.sh
Executable file
285
run_docengine.sh
Executable file
@@ -0,0 +1,285 @@
|
||||
#!/usr/bin/env bash
|
||||
# =============================================================================
|
||||
# DocEngine — Backend Startup Script
|
||||
# =============================================================================
|
||||
# Usage:
|
||||
# ./run_docengine.sh Run the API server (default)
|
||||
# ./run_docengine.sh server Run the API server only
|
||||
# ./run_docengine.sh worker Run the Celery worker only
|
||||
# ./run_docengine.sh all Run both API server and Celery worker
|
||||
# ./run_docengine.sh setup Install deps + run migrations only
|
||||
# ./run_docengine.sh migrate Run Alembic migrations only
|
||||
# =============================================================================
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# ── Paths ────────────────────────────────────────────────────────────────────
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_DIR="${SCRIPT_DIR}/docengine"
|
||||
VENV_DIR="${PROJECT_DIR}/.venv"
|
||||
PID_DIR="${PROJECT_DIR}/.pids"
|
||||
|
||||
# ── Colors ───────────────────────────────────────────────────────────────────
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
CYAN='\033[0;36m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
log() { echo -e "${GREEN}[DocEngine]${NC} $*"; }
|
||||
warn() { echo -e "${YELLOW}[DocEngine]${NC} $*"; }
|
||||
err() { echo -e "${RED}[DocEngine]${NC} $*" >&2; }
|
||||
|
||||
# ── Pre-flight checks ───────────────────────────────────────────────────────
|
||||
check_python() {
|
||||
if command -v python3 &>/dev/null; then
|
||||
PYTHON=python3
|
||||
elif command -v python &>/dev/null; then
|
||||
PYTHON=python
|
||||
else
|
||||
err "Python 3 is not installed. Please install Python 3.12+."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
local version
|
||||
version=$($PYTHON -c 'import sys; print(f"{sys.version_info.major}.{sys.version_info.minor}")')
|
||||
log "Using Python ${version} (${PYTHON})"
|
||||
}
|
||||
|
||||
check_redis() {
|
||||
if command -v redis-cli &>/dev/null; then
|
||||
if redis-cli ping &>/dev/null; then
|
||||
log "Redis is running ✓"
|
||||
else
|
||||
warn "Redis is installed but not running. Celery worker will fail without Redis."
|
||||
warn "Start Redis with: brew services start redis (or) redis-server --daemonize yes"
|
||||
fi
|
||||
else
|
||||
warn "redis-cli not found. Celery worker requires Redis."
|
||||
fi
|
||||
}
|
||||
|
||||
# ── Virtual Environment ─────────────────────────────────────────────────────
|
||||
ensure_venv() {
|
||||
local created=false
|
||||
if [ ! -d "${VENV_DIR}" ]; then
|
||||
log "Creating virtual environment at ${VENV_DIR}..."
|
||||
$PYTHON -m venv "${VENV_DIR}"
|
||||
log "Virtual environment created ✓"
|
||||
created=true
|
||||
fi
|
||||
# shellcheck disable=SC1091
|
||||
source "${VENV_DIR}/bin/activate"
|
||||
log "Virtual environment activated ✓"
|
||||
|
||||
# Auto-install dependencies if this is a fresh venv or if uvicorn is missing
|
||||
if [ "${created}" = true ] || ! python -c "import uvicorn" &>/dev/null; then
|
||||
log "Dependencies missing. Auto-installing dependencies..."
|
||||
install_deps
|
||||
fi
|
||||
}
|
||||
|
||||
# ── Dependencies ─────────────────────────────────────────────────────────────
|
||||
install_deps() {
|
||||
log "Installing Python dependencies..."
|
||||
pip install --upgrade pip --quiet
|
||||
pip install -r "${PROJECT_DIR}/requirements.txt" --quiet
|
||||
log "Dependencies installed ✓"
|
||||
}
|
||||
|
||||
# ── Storage Directories ─────────────────────────────────────────────────────
|
||||
ensure_storage() {
|
||||
local dirs=("documents" "templates" "images" "temp" "rendered")
|
||||
for dir in "${dirs[@]}"; do
|
||||
mkdir -p "${PROJECT_DIR}/storage/${dir}"
|
||||
done
|
||||
log "Storage directories ready ✓"
|
||||
}
|
||||
|
||||
# ── Database Migrations ─────────────────────────────────────────────────────
|
||||
run_migrations() {
|
||||
log "Running Alembic database migrations..."
|
||||
cd "${PROJECT_DIR}"
|
||||
if alembic upgrade head 2>/dev/null; then
|
||||
log "Migrations applied ✓"
|
||||
else
|
||||
warn "Alembic migrations failed or no migrations to apply."
|
||||
warn "If this is a fresh database, ensure PostgreSQL is reachable at the configured host."
|
||||
fi
|
||||
}
|
||||
|
||||
# ── PID Management ───────────────────────────────────────────────────────────
|
||||
mkdir_pids() {
|
||||
mkdir -p "${PID_DIR}"
|
||||
}
|
||||
|
||||
save_pid() {
|
||||
echo "$2" > "${PID_DIR}/$1.pid"
|
||||
}
|
||||
|
||||
remove_pid() {
|
||||
rm -f "${PID_DIR}/$1.pid"
|
||||
}
|
||||
|
||||
read_pid() {
|
||||
local pidfile="${PID_DIR}/$1.pid"
|
||||
if [ -f "${pidfile}" ]; then
|
||||
cat "${pidfile}"
|
||||
fi
|
||||
}
|
||||
|
||||
is_running() {
|
||||
local pid
|
||||
pid=$(read_pid "$1")
|
||||
if [ -n "${pid}" ] && kill -0 "${pid}" 2>/dev/null; then
|
||||
return 0
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
# ── Cleanup on exit ─────────────────────────────────────────────────────────
|
||||
cleanup() {
|
||||
log "Shutting down..."
|
||||
local server_pid worker_pid
|
||||
server_pid=$(read_pid "server")
|
||||
worker_pid=$(read_pid "worker")
|
||||
|
||||
if [ -n "${server_pid}" ] && kill -0 "${server_pid}" 2>/dev/null; then
|
||||
log "Stopping API server (PID ${server_pid})..."
|
||||
kill "${server_pid}" 2>/dev/null || true
|
||||
remove_pid "server"
|
||||
fi
|
||||
|
||||
if [ -n "${worker_pid}" ] && kill -0 "${worker_pid}" 2>/dev/null; then
|
||||
log "Stopping Celery worker (PID ${worker_pid})..."
|
||||
kill "${worker_pid}" 2>/dev/null || true
|
||||
remove_pid "worker"
|
||||
fi
|
||||
|
||||
log "Shutdown complete."
|
||||
}
|
||||
|
||||
# ── Start API Server ────────────────────────────────────────────────────────
|
||||
start_server() {
|
||||
if is_running "server"; then
|
||||
warn "API server is already running (PID $(read_pid 'server'))"
|
||||
return
|
||||
fi
|
||||
|
||||
cd "${PROJECT_DIR}"
|
||||
log "Starting API server on port 7989..."
|
||||
log " Docs: ${CYAN}http://localhost:7989/docs${NC}"
|
||||
log " ReDoc: ${CYAN}http://localhost:7989/redoc${NC}"
|
||||
log " Health: ${CYAN}http://localhost:7989/api/v1/health${NC}"
|
||||
echo ""
|
||||
|
||||
python -m uvicorn app.main:app \
|
||||
--host 0.0.0.0 \
|
||||
--port 7989 \
|
||||
--reload \
|
||||
--log-level info &
|
||||
|
||||
local pid=$!
|
||||
save_pid "server" "${pid}"
|
||||
log "API server started (PID ${pid}) ✓"
|
||||
}
|
||||
|
||||
# ── Start Celery Worker ─────────────────────────────────────────────────────
|
||||
start_worker() {
|
||||
if is_running "worker"; then
|
||||
warn "Celery worker is already running (PID $(read_pid 'worker'))"
|
||||
return
|
||||
fi
|
||||
|
||||
cd "${PROJECT_DIR}"
|
||||
log "Starting Celery worker..."
|
||||
|
||||
celery -A app.workers.celery_app worker \
|
||||
--loglevel=info \
|
||||
--concurrency=4 \
|
||||
--pool=prefork \
|
||||
-Q celery,document_processing \
|
||||
-E &
|
||||
|
||||
local pid=$!
|
||||
save_pid "worker" "${pid}"
|
||||
log "Celery worker started (PID ${pid}) ✓"
|
||||
}
|
||||
|
||||
# ── Setup (no server start) ─────────────────────────────────────────────────
|
||||
do_setup() {
|
||||
check_python
|
||||
ensure_venv
|
||||
install_deps
|
||||
ensure_storage
|
||||
check_redis
|
||||
run_migrations
|
||||
log ""
|
||||
log "Setup complete. Run ${CYAN}./run_docengine.sh${NC} to start the server."
|
||||
}
|
||||
|
||||
# ── Main ─────────────────────────────────────────────────────────────────────
|
||||
main() {
|
||||
local command="${1:-server}"
|
||||
|
||||
case "${command}" in
|
||||
setup)
|
||||
do_setup
|
||||
;;
|
||||
migrate)
|
||||
check_python
|
||||
ensure_venv
|
||||
run_migrations
|
||||
;;
|
||||
server)
|
||||
check_python
|
||||
ensure_venv
|
||||
ensure_storage
|
||||
mkdir_pids
|
||||
trap cleanup EXIT INT TERM
|
||||
start_server
|
||||
wait
|
||||
;;
|
||||
worker)
|
||||
check_python
|
||||
ensure_venv
|
||||
check_redis
|
||||
mkdir_pids
|
||||
trap cleanup EXIT INT TERM
|
||||
start_worker
|
||||
wait
|
||||
;;
|
||||
all)
|
||||
check_python
|
||||
ensure_venv
|
||||
ensure_storage
|
||||
check_redis
|
||||
mkdir_pids
|
||||
trap cleanup EXIT INT TERM
|
||||
start_server
|
||||
start_worker
|
||||
echo ""
|
||||
log "═══════════════════════════════════════════════"
|
||||
log " DocEngine is running"
|
||||
log " API Server : http://localhost:7989"
|
||||
log " Swagger UI : http://localhost:7989/docs"
|
||||
log " Celery : Worker active (4 processes)"
|
||||
log "═══════════════════════════════════════════════"
|
||||
log "Press Ctrl+C to stop all services."
|
||||
echo ""
|
||||
wait
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $0 {server|worker|all|setup|migrate}"
|
||||
echo ""
|
||||
echo " server Start the FastAPI server (default)"
|
||||
echo " worker Start the Celery worker"
|
||||
echo " all Start both server and worker"
|
||||
echo " setup Install dependencies and run migrations"
|
||||
echo " migrate Run database migrations only"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
main "$@"
|
||||
Reference in New Issue
Block a user