""" MOXIE - Fake Local LLM Orchestrator Main FastAPI Application Entry Point """ import sys from pathlib import Path # Add project root to path sys.path.insert(0, str(Path(__file__).parent)) from contextlib import asynccontextmanager from fastapi import FastAPI, Request from fastapi.responses import HTMLResponse, FileResponse from fastapi.staticfiles import StaticFiles from fastapi.middleware.cors import CORSMiddleware from loguru import logger from config import settings, get_data_dir, get_workflows_dir from api.routes import router as api_router from api.admin import router as admin_router from web.routes import router as web_router from core.orchestrator import Orchestrator from rag.store import RAGStore from auth.models import get_auth_manager # Configure logging logger.remove() logger.add( sys.stderr, format="{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {name}:{function}:{line} - {message}", level="DEBUG" if settings.debug else "INFO" ) @asynccontextmanager async def lifespan(app: FastAPI): """Application lifespan manager.""" logger.info("Starting MOXIE Orchestrator...") # Initialize data directories get_data_dir() get_workflows_dir() # Initialize auth manager auth_manager = get_auth_manager() logger.info("Auth Manager initialized") # Initialize RAG store app.state.rag_store = RAGStore() logger.info("RAG Store initialized") # Initialize orchestrator app.state.orchestrator = Orchestrator(app.state.rag_store) logger.info("Orchestrator initialized") logger.success(f"MOXIE ready on http://{settings.host}:{settings.port}") logger.info(f"Admin UI: http://{settings.host}:{settings.port}/{settings.admin_path}") logger.info(f"Web UI: http://{settings.host}:{settings.port}/") yield # Cleanup logger.info("Shutting down MOXIE...") # Create FastAPI app app = FastAPI( title="MOXIE", description="AI Assistant with multiple backend support", version="1.0.0", lifespan=lifespan, docs_url=None, # Hide docs redoc_url=None, # Hide redoc ) # CORS middleware app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) # Static files for admin UI admin_static_path = Path(__file__).parent / "admin" / "static" if admin_static_path.exists(): app.mount( f"/{settings.admin_path}/static", StaticFiles(directory=str(admin_static_path)), name="admin-static" ) # Static files for web UI web_static_path = Path(__file__).parent / "web" / "static" if web_static_path.exists(): app.mount( "/static", StaticFiles(directory=str(web_static_path)), name="web-static" ) # Include routers app.include_router(web_router, tags=["web"]) # Web UI routes at root app.include_router(api_router, prefix="/v1", tags=["api"]) # OpenAI-compatible API app.include_router(admin_router, prefix=f"/{settings.admin_path}", tags=["admin"]) # Admin panel @app.get("/health") async def health_check(): """Health check endpoint.""" return {"status": "healthy", "service": "moxie"} # Serve favicon @app.get("/favicon.ico") async def favicon(): return {"status": "not found"} if __name__ == "__main__": import uvicorn uvicorn.run( "main:app", host=settings.host, port=settings.port, reload=settings.debug, )