Cachy / start.py
Vatxzz's picture
feat: update backend, UI, and pipeline features
4537cd6
Raw
History Blame Contribute Delete
3.37 kB
#!/usr/bin/env python3
"""Orchestration script to start both Cachy FastAPI backend and Flutter web frontend.
Starts the FastAPI backend using uvicorn from the virtual environment and launches
the Flutter web frontend on Chrome.
"""
import shutil
import subprocess
import sys
import time
from pathlib import Path
from typing import List, Optional
def find_executable(name: str) -> Optional[str]:
"""Find the path to an executable in PATH.
Args:
name: The name of the executable to search for.
Returns:
The path string if found, otherwise None.
"""
return shutil.which(name)
def run_app() -> int:
"""Start the Cachy backend and Flutter frontend subprocesses.
Returns:
Exit code (0 for clean shutdown, non-zero for error).
"""
root_dir: Path = Path(__file__).resolve().parent
backend_dir: Path = root_dir / "backend"
frontend_dir: Path = root_dir / "app"
venv_uvicorn: Path = backend_dir / ".venv" / "bin" / "uvicorn"
uvicorn_bin = str(venv_uvicorn)
if not venv_uvicorn.exists():
fallback = find_executable("uvicorn")
if fallback is None:
print(f"Error: uvicorn not found in virtualenv or PATH.")
return 1
uvicorn_bin = fallback
flutter_bin: Optional[str] = find_executable("flutter")
if flutter_bin is None:
print("Error: 'flutter' executable not found in PATH.")
return 1
backend_cmd: List[str] = [
uvicorn_bin,
"app.main:app",
"--reload",
# Bind all interfaces so a phone on the same WiFi can reach the API after
# LAN discovery (not just localhost). Local-testing only.
"--host",
"0.0.0.0",
"--port",
"8000",
]
frontend_cmd: List[str] = [
flutter_bin,
"run",
"-d",
"chrome",
"--dart-define=CACHY_API_BASE=http://localhost:8000",
]
print("Starting Cachy Backend (port 8000)...")
backend_proc: Optional[subprocess.Popen] = None
frontend_proc: Optional[subprocess.Popen] = None
try:
backend_proc = subprocess.Popen(backend_cmd, cwd=backend_dir)
except Exception as e:
print(f"Failed to start backend subprocess: {e}")
return 1
time.sleep(2)
print("Starting Cachy Flutter Frontend on Chrome...")
try:
frontend_proc = subprocess.Popen(frontend_cmd, cwd=frontend_dir)
except Exception as e:
print(f"Failed to start frontend subprocess: {e}")
if backend_proc.poll() is None:
backend_proc.terminate()
return 1
try:
frontend_proc.wait()
except KeyboardInterrupt:
print("\nReceived keyboard interrupt. Shutting down servers...")
except Exception as e:
print(f"Unexpected error during execution: {e}")
finally:
if frontend_proc and frontend_proc.poll() is None:
frontend_proc.terminate()
if backend_proc and backend_proc.poll() is None:
backend_proc.terminate()
try:
backend_proc.wait(timeout=5)
except subprocess.TimeoutExpired as e:
print(f"Backend did not terminate gracefully, killing process: {e}")
backend_proc.kill()
print("Cachy shutdown complete.")
return 0
if __name__ == "__main__":
sys.exit(run_app())