from fastapi import FastAPI from fastapi.staticfiles import StaticFiles from fastapi.responses import FileResponse from fastapi.middleware.cors import CORSMiddleware import uvicorn import os from pathlib import Path import mimetypes from utils import log from chat_handler import router as chat_router # ← start_session & chat from admin_routes import router as admin_router, start_cleanup_task from spark_startup import run_in_thread from session import session_store, start_session_cleanup from config_provider import ConfigProvider # ===================== Environment Setup ===================== def setup_environment(): """Setup environment based on deployment""" cfg = ConfigProvider.get() log("=" * 60) log(f"🚀 Flare Starting") log(f"🤖 LLM Provider: {cfg.global_config.llm_provider.name}") log(f"🔊 TTS Provider: {cfg.global_config.tts_provider.name}") log(f"🎤 STT Provider: {cfg.global_config.stt_provider.name}") log("=" * 60) # Check if running in HuggingFace Space if os.environ.get("SPACE_ID"): log("☁️ Running in HuggingFace Space") log("📌 Using environment secrets for API keys") else: log("🏢 Local/On-Premise deployment") if not Path(".env").exists(): log("⚠️ WARNING: .env file not found!") log("📌 Copy .env.example to .env and configure it") # Run setup setup_environment() # Fix MIME types for JavaScript files mimetypes.add_type("application/javascript", ".js") mimetypes.add_type("text/css", ".css") app = FastAPI( title="Flare Orchestration Service", version="0.1.0", description="LLM-driven intent & API flow engine", ) # CORS for development if os.getenv("ENVIRONMENT") == "development": app.add_middleware( CORSMiddleware, allow_origins=["http://localhost:4200"], # Angular dev server allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) log("🔧 CORS enabled for development") run_in_thread() start_cleanup_task() # Activity log cleanup start_session_cleanup() # Session cleanup # ---------------- Core chat/session routes -------------------------- app.include_router(chat_router, prefix="/api") # ---------------- Admin API routes ---------------------------------- app.include_router(admin_router) # ---------------- Serve Angular UI if exists ------------------------ ui_path = Path(__file__).parent / "ui" / "dist" / "flare-ui" if ui_path.exists(): log(f"📁 Serving UI from: {ui_path}") # Serve static files app.mount("/assets", StaticFiles(directory=ui_path / "assets"), name="assets") # Catch-all route for Angular routing @app.get("/{full_path:path}") async def serve_angular(full_path: str): """Serve Angular app for all non-API routes""" # Skip API routes if full_path.startswith("api/"): return {"error": "API endpoint not found"} # Serve index.html for all routes (Angular will handle routing) return FileResponse(ui_path / "index.html") else: log("⚠️ UI not found - only API endpoints available") @app.get("/") def root(): return { "service": "Flare Orchestration Service", "version": "0.1.0", "status": "running", "ui": "not available - build Angular UI first" } if __name__ == "__main__": log("🌐 Starting Flare backend on port 7860...") uvicorn.run(app, host="0.0.0.0", port=7860)