Spaces:
Paused
Paused
| """ | |
| Flare β Main Application (Refactored) | |
| ===================================== | |
| """ | |
| 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 websocket_handler import websocket_endpoint | |
| 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 llm_startup import run_in_thread # Changed from spark_startup | |
| from session import session_store, start_session_cleanup | |
| from config_provider import ConfigProvider | |
| # ===================== Environment Setup ===================== | |
| def setup_environment(): | |
| """Setup environment based on deployment mode""" | |
| 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) | |
| if cfg.global_config.is_cloud_mode(): | |
| log("βοΈ Cloud Mode: Using HuggingFace Secrets") | |
| log("π Required secrets: JWT_SECRET, FLARE_TOKEN_KEY") | |
| # Check for provider-specific tokens | |
| llm_config = cfg.global_config.get_provider_config("llm", cfg.global_config.llm_provider.name) | |
| if llm_config and llm_config.requires_repo_info: | |
| log("π LLM requires SPARK_TOKEN for repository operations") | |
| else: | |
| log("π’ On-Premise Mode: Using .env file") | |
| 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="2.0.0", | |
| description="LLM-driven intent & API flow engine with multi-provider support", | |
| ) | |
| # 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 LLM startup notifier if needed | |
| start_cleanup_task() # Activity log cleanup | |
| start_session_cleanup() # Session cleanup | |
| # ---------------- Health probe (HF Spaces watchdog) ----------------- | |
| def health_check(): | |
| return {"status": "ok", "version": "2.0.0"} | |
| # ---------------- Core chat/session routes -------------------------- | |
| app.include_router(chat_router, prefix="/api") | |
| # ---------------- Admin API routes ---------------------------------- | |
| app.include_router(admin_router) | |
| # ---------------- WebSocket route for real-time STT ------------------ | |
| async def conversation_websocket(websocket: WebSocket, session_id: str): | |
| await websocket_endpoint(websocket, session_id) | |
| # ---------------- Serve Angular UI if exists ------------------------ | |
| static_dir = Path(__file__).parent / "static" | |
| if static_dir.exists(): | |
| log("π¨ Serving Angular UI from /static directory") | |
| # Mount static files with custom handler for Angular routing | |
| async def serve_angular(path: str): | |
| # API routes should not be handled here | |
| if path.startswith("api/"): | |
| return {"error": "Not found"}, 404 | |
| # Try to serve the exact file first | |
| file_path = static_dir / path | |
| if file_path.is_file(): | |
| return FileResponse(file_path) | |
| # For Angular routes, always serve index.html | |
| index_path = static_dir / "index.html" | |
| if index_path.exists(): | |
| return FileResponse(index_path) | |
| return {"error": "Not found"}, 404 | |
| # Mount static files for assets | |
| app.mount("/", StaticFiles(directory=str(static_dir), html=True), name="static") | |
| else: | |
| log("β οΈ No UI found. Run 'cd flare-ui && npm run build' to build the UI.") | |
| if __name__ == "__main__": | |
| log("π Starting Flare backend on port 7860...") | |
| uvicorn.run(app, host="0.0.0.0", port=7860) |