"""FastAPI application factory""" import logging from contextlib import asynccontextmanager from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware from fastapi.websockets import WebSocket from luxx.core.config import config from luxx.core.database import init_db from luxx.api import api_router logger = logging.getLogger(__name__) @asynccontextmanager async def lifespan(app: FastAPI): """Application lifespan manager""" # Import all models to ensure they are registered with Base from luxx.models.user import User, LLMProvider, Project from luxx.models.chat import Conversation, Message from luxx.models.room import ChatRoom, Agent, RoomParticipant init_db() # Create default test user if not exists from luxx.core.database import SessionLocal from luxx.utils.helpers import hash_password db = SessionLocal() try: default_user = db.query(User).filter(User.username == "admin").first() if not default_user: default_user = User( username="admin", password_hash=hash_password("admin"), role="admin" ) db.add(default_user) db.commit() logger.info("Default admin user created: admin / admin") finally: db.close() # Import and register tools from luxx.tools.builtin import crawler, code, data yield def create_app() -> FastAPI: """Create FastAPI application""" app = FastAPI( title="luxx API", description="Intelligent chat backend API with multi-model support, streaming responses, and tool calling", version="1.0.0", lifespan=lifespan ) # Configure CORS app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) # Register routes app.include_router(api_router, prefix="/api") # WebSocket endpoint for chat rooms from luxx.services.room_ws import websocket_handler @app.websocket("/ws/chat-room/{room_id}") async def chat_room_websocket( websocket: WebSocket, room_id: str, participant_id: str = None, participant_type: str = "user", participant_name: str = None ): """ WebSocket endpoint for chat room participation. Query parameters: - participant_id: ID of the user or agent connecting - participant_type: "user" or "agent" (default: "user") - participant_name: Display name for the participant Example: - User: ws://host/ws/chat-room/{room_id}?participant_id=123&participant_type=user&participant_name=John - Agent: ws://host/ws/chat-room/{room_id}?participant_id=agent-1&participant_type=agent&participant_name=Assistant """ await websocket_handler(websocket, room_id) # Health check @app.get("/health") async def health_check(): return {"status": "healthy", "service": "luxx"} @app.get("/") async def root(): return { "service": "luxx API", "version": "1.0.0", "docs": "/docs" } return app # Create application instance app = create_app()