Spaces:
Building
Building
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 work_mode""" | |
cfg = ConfigProvider.get() | |
log("=" * 60) | |
log(f"π Flare Starting in {cfg.global_config.work_mode.upper()} mode") | |
log("=" * 60) | |
if cfg.global_config.is_cloud_mode(): | |
log("βοΈ Cloud Mode: Using HuggingFace Secrets") | |
log("π Required secrets: JWT_SECRET, FLARE_TOKEN_KEY, SPARK_TOKEN") | |
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="0.1.0", | |
description="LLM-driven intent & API flow engine (bootstrap)", | |
) | |
# 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 | |
# ---------------- Core chat/session routes -------------------------- | |
app.include_router(chat_router, prefix="/api") | |
# ---------------- Admin API routes ---------------------------------- | |
app.include_router(admin_router) | |
# ---------------- Serve Angular UI if exists ------------------------ | |
static_path = Path("static") | |
log(f"π Checking for static directory at: {static_path.absolute()}") | |
log(f"π Static directory exists: {static_path.exists()}") | |
if static_path.exists() and static_path.is_dir(): | |
# List files in static directory | |
files = list(static_path.iterdir()) | |
log(f"π Files in static directory: {[f.name for f in files]}") | |
# Check for index.html | |
index_path = static_path / "index.html" | |
log(f"π index.html exists: {index_path.exists()}") | |
# Mount entire static directory | |
app.mount("/static", StaticFiles(directory="static"), name="static") | |
# Serve static files (Angular assets) - only if assets directory exists | |
assets_path = static_path / "assets" | |
if assets_path.exists() and assets_path.is_dir(): | |
app.mount("/assets", StaticFiles(directory=str(assets_path)), name="assets") | |
# Root path - serve index.html | |
async def serve_root(): | |
index_path = static_path / "index.html" | |
if index_path.exists(): | |
log("π Serving index.html") | |
return FileResponse(str(index_path), media_type="text/html") | |
log("β οΈ index.html not found, returning health check") | |
return {"status": "ok", "sessions": len(session_store._sessions)} # Fallback to health check | |
# Serve JS files with correct MIME type | |
async def serve_js(filename: str): | |
js_path = static_path / f"{filename}.js" | |
if js_path.exists(): | |
return FileResponse(str(js_path), media_type="application/javascript") | |
return {"error": "JS file not found"}, 404 | |
# Serve CSS files with correct MIME type | |
async def serve_css(filename: str): | |
css_path = static_path / f"{filename}.css" | |
if css_path.exists(): | |
return FileResponse(str(css_path), media_type="text/css") | |
return {"error": "CSS file not found"}, 404 | |
# Catch-all route for Angular routing (must be last!) | |
async def serve_angular(full_path: str): | |
# Don't catch API routes | |
if full_path.startswith("api/") or full_path in ["start_session", "chat", "health"]: | |
return {"error": "Not found"}, 404 | |
# Return Angular index.html for all other routes | |
index_path = static_path / "index.html" | |
if index_path.exists(): | |
return FileResponse(str(index_path), media_type="text/html") | |
return {"error": "UI not found"}, 404 | |
else: | |
log("β οΈ Static directory not found") | |
# No UI built, just health endpoint | |
def health_check(): | |
return {"status": "ok", "message": "UI not found. Build Angular app first."} | |
if __name__ == "__main__": | |
log("π Starting Flare backend β¦") | |
uvicorn.run(app, host="0.0.0.0", port=7860) |