Update nutrition score retrieval using OFF v2 REST API and title cleaning

This commit is contained in:
sriram
2026-08-10 18:54:27 +05:30
parent 72dd9f8296
commit 370f867355
43 changed files with 2088 additions and 373 deletions

155
run_project.py Normal file
View File

@@ -0,0 +1,155 @@
#!/usr/bin/env python3
"""
Unified Single-Command Project Launcher for Brand Catalog Product LLM & RAG Intelligence Engine.
Usage:
python run_project.py
What this script automates:
1. Checks & launches PostgreSQL via Docker Compose (`docker compose up -d`).
2. Starts FastAPI backend server on http://localhost:8000 (with background auto-seeding).
3. Starts Vite frontend dev server on http://localhost:5173 (or serves static dist).
4. Keeps both servers running concurrently with instant hot-reloading & single Ctrl+C exit.
"""
import os
import sys
import time
import subprocess
import signal
from pathlib import Path
if sys.platform == "win32":
try:
sys.stdout.reconfigure(encoding="utf-8", errors="replace")
sys.stderr.reconfigure(encoding="utf-8", errors="replace")
except Exception:
pass
ROOT_DIR = Path(__file__).resolve().parent
BACKEND_DIR = ROOT_DIR / "backend"
FRONTEND_DIR = ROOT_DIR / "frontend"
VENV_PYTHON = BACKEND_DIR / "venv" / "Scripts" / "python.exe"
if not VENV_PYTHON.exists():
VENV_PYTHON = Path(sys.executable)
def print_banner():
print("\033[96m" + "=" * 70)
print(" 🚀 BRAND CATALOG PRODUCT LLM & RAG INTELLIGENCE ENGINE")
print("=" * 70 + "\033[0m")
import shutil
def start_docker():
print("\n📦 Checking PostgreSQL Docker container...")
compose_file = ROOT_DIR / "docker-compose.yml"
if not compose_file.exists():
compose_file = BACKEND_DIR / "docker-compose.yml"
if compose_file.exists():
try:
res = subprocess.run(["docker", "compose", "-f", str(compose_file), "up", "-d"], capture_output=True, text=True)
if res.returncode == 0:
print("✅ PostgreSQL container is running on port 5432 (pgvector ready).")
else:
print("⚠️ Docker notice:", res.stderr.strip() or "Ensure Docker Desktop is running if using Docker Postgres.")
except Exception as e:
print(f"⚠️ Docker check skipped: {e}")
def start_ollama():
print("\n🦙 Checking Ollama LLM service...")
import urllib.request
try:
req = urllib.request.urlopen("http://localhost:11434/api/tags", timeout=2)
if req.getcode() == 200:
print("✅ Ollama LLM server is running on http://localhost:11434.")
return None
except Exception:
pass
if not shutil.which("ollama"):
print("ℹ️ Ollama CLI not installed/found. Backend will use catalog-grounded fallback responses.")
return None
try:
p = subprocess.Popen(["ollama", "serve"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
print("🚀 Automatically launched Ollama LLM server background process.")
return p
except Exception as e:
print(f"⚠️ Ollama auto-launch note: {e} (App will use catalog grounded fallback).")
return None
def main():
print_banner()
start_docker()
p_ollama = start_ollama()
processes = []
if p_ollama:
processes.append(p_ollama)
try:
# 1. Start Backend FastAPI Uvicorn
print("\n⚡ Starting Backend FastAPI Server (http://localhost:8000)...")
backend_cmd = [
str(VENV_PYTHON), "-m", "uvicorn", "app.main:app",
"--reload", "--host", "0.0.0.0", "--port", "8000"
]
env_backend = os.environ.copy()
env_backend["PYTHONPATH"] = str(BACKEND_DIR)
env_backend["PYTHONIOENCODING"] = "utf-8"
p_backend = subprocess.Popen(
backend_cmd, cwd=str(BACKEND_DIR), env=env_backend
)
processes.append(p_backend)
# 2. Start Frontend Vite Dev Server
print("🎨 Starting Frontend Vite Server (http://localhost:5173)...")
npm_cmd = "npm.cmd" if sys.platform == "win32" else "npm"
p_frontend = subprocess.Popen(
[npm_cmd, "run", "dev"], cwd=str(FRONTEND_DIR), shell=(sys.platform == "win32")
)
processes.append(p_frontend)
print("\n\033[92m" + "=" * 70)
print(" 🎉 APPLICATION IS LIVE AND READY!")
print("=" * 70 + "\033[0m")
print(" 👉 Web App UI: \033[94mhttp://localhost:5173\033[0m")
print(" 👉 Backend API: \033[94mhttp://localhost:8000\033[0m")
print(" 👉 API Docs: \033[94mhttp://localhost:8000/docs\033[0m")
print(" 👉 System Status: \033[94mhttp://localhost:8000/api/system/status\033[0m")
print("=" * 70)
print(" (Press Ctrl+C to stop all servers gracefully)\n")
# Monitor core servers (backend & frontend)
core_processes = [p_backend, p_frontend]
while True:
time.sleep(1)
for p in core_processes:
if p.poll() is not None:
print(f"⚠️ Core process PID {p.pid} exited with code {p.returncode}")
return
except KeyboardInterrupt:
print("\n🛑 Stopping all services...")
finally:
for p in processes:
try:
p.terminate()
p.wait(timeout=3)
except Exception:
try:
p.kill()
except Exception:
pass
print("👋 Goodbye! All processes terminated.")
if __name__ == "__main__":
main()