""" 云屋 - 主程序入口点 实现沉浸式宠物伴侣系统的核心API服务 支持用户认证、聊天交互和实时音频处理 """ from fastapi import FastAPI, HTTPException, Request from fastapi.middleware.cors import CORSMiddleware from fastapi.responses import FileResponse from fastapi.staticfiles import StaticFiles from contextlib import asynccontextmanager import uvicorn import logging from datetime import datetime import os import sys # Add current directory to Python path sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) # Import available routers from api.chat_router import chat_router from api.pet_router import pet_router from api.storage_router import storage_router from api.user_router import user_router from api.background_router import background_router from api.admin_router import admin_router from api.wechat_auth_router import wechat_auth_router from api.sms_auth_router import sms_auth_router from api.cache_router import cache_router from api.scene_editor_router import scene_editor_router from api.ai_governance_router import ai_governance_router from api.live2d_router import live2d_router from api.fullscreen_router import fullscreen_router from api.model_config_router import router as model_config_router from api.voice_chat_router import voice_chat_router from config.settings import settings from models.database import init_db # Configure logging logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) @asynccontextmanager async def lifespan(app: FastAPI): # 启动时初始化数据库表 init_db() # 使用同步版本 yield # 关闭时可以添加清理逻辑 # Initialize FastAPI app app = FastAPI( title="AI Pet Companion API", description="Backend API for the immersive pet companion system", version="3.0.0", lifespan=lifespan ) # Add CORS middleware app.add_middleware( CORSMiddleware, allow_origins=settings.ALLOWED_ORIGINS, allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) # Add static files middleware for uploads uploads_dir = os.path.abspath(os.path.join(os.path.dirname(os.path.abspath(__file__)), "uploads")) if not os.path.exists(uploads_dir): os.makedirs(uploads_dir) print(f"Static files directory: {uploads_dir}") # Mount static files to serve uploads directory from fastapi.staticfiles import StaticFiles app.mount("/uploads", StaticFiles(directory=uploads_dir), name="uploads") # Include all routers with v1 prefix (must be before catch-all route) app.include_router(user_router, prefix="/api/v1") app.include_router(chat_router, prefix="/api/v1") app.include_router(pet_router, prefix="/api/v1") app.include_router(background_router, prefix="/api/v1/background") app.include_router(storage_router, prefix="/api/v1") app.include_router(admin_router, prefix="/api/v1/admin") app.include_router(wechat_auth_router, prefix="/api/v1/auth/wechat") app.include_router(sms_auth_router, prefix="/api/v1/auth/sms") app.include_router(cache_router, prefix="/api/v1/cache") app.include_router(scene_editor_router, prefix="/api/v1/scene-editor") app.include_router(ai_governance_router, prefix="/api/v1/ai-governance") app.include_router(live2d_router, prefix="/api/v1/live2d") app.include_router(fullscreen_router, prefix="/api/v1/fullscreen") app.include_router(model_config_router, prefix="/api/v1/model-config") app.include_router(voice_chat_router, prefix="/api/v1") # Frontend static files configuration (must be after API routes) frontend_dist_dir = os.path.abspath(os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "frontend", "dist")) frontend_assets_dir = os.path.join(frontend_dist_dir, "assets") frontend_index_path = os.path.join(frontend_dist_dir, "index.html") print(f"Frontend dist directory: {frontend_dist_dir}") if os.path.exists(frontend_assets_dir): app.mount("/assets", StaticFiles(directory=frontend_assets_dir), name="assets") if os.path.exists(frontend_index_path): @app.get("/{full_path:path}") async def serve_frontend(request: Request, full_path: str): if os.path.exists(frontend_index_path): return FileResponse(frontend_index_path) return {"error": "Frontend not found"} @app.get("/") async def root(): return {"message": "AI Pet Companion API is running", "version": "3.0.0"} @app.get("/debug/routes") async def debug_routes(): """Debug endpoint to list all registered routes""" routes = [] for route in app.routes: if hasattr(route, 'path') and hasattr(route, 'methods'): routes.append({ "path": route.path, "methods": list(route.methods) }) return {"routes": routes} if __name__ == "__main__": uvicorn.run( "main:app", host=settings.HOST, port=settings.PORT, reload=settings.DEBUG )