test/moxie/main.py
Z User 1f9535d683 Add complete MOXIE web UI with authentication and user management
- New web UI with OpenWebUI-like interface using Tailwind CSS
- SQLite-based authentication with session management
- User registration, login, and profile pages
- Chat interface with conversation history
- Streaming responses with visible thinking phase
- File attachments support
- User document uploads in profile
- Rate limiting (5 requests/day for free users)
- Admin panel user management with promote/demote/delete
- Custom color theme matching balloon logo design
- Compatible with Nuitka build system
2026-03-24 05:15:50 +00:00

131 lines
3.5 KiB
Python
Executable File

"""
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="<green>{time:YYYY-MM-DD HH:mm:ss}</green> | <level>{level: <8}</level> | <cyan>{name}</cyan>:<cyan>{function}</cyan>:<cyan>{line}</cyan> - <level>{message}</level>",
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,
)