from fastapi import FastAPI, APIRouter from fastapi.middleware.cors import CORSMiddleware from contextlib import asynccontextmanager from src.apis.routes.user_route import router as router_user from src.apis.routes.chat_route import router as router_chat from src.apis.routes.lesson_route import router as router_lesson from src.apis.routes.evaluation_route import router as router_evaluation from src.apis.routes.pronunciation_route import router as router_pronunciation from src.apis.routes.speaking_route import router as router_speaking, preload_whisper_model from src.apis.routes.ipa_route import router as router_ipa from loguru import logger import time api_router = APIRouter(prefix="/api") api_router.include_router(router_user) api_router.include_router(router_chat) api_router.include_router(router_lesson) api_router.include_router(router_evaluation) api_router.include_router(router_pronunciation) api_router.include_router(router_speaking) api_router.include_router(router_ipa) @asynccontextmanager async def lifespan(app: FastAPI): """ FastAPI lifespan context manager for startup and shutdown events Preloads Whisper model during startup for faster first inference """ # Startup logger.info("🚀 Starting English Tutor API...") startup_start = time.time() try: # Preload Whisper model during startup logger.info("📦 Preloading Whisper model for pronunciation assessment...") success = preload_whisper_model(whisper_model="base.en") if success: logger.info("✅ Whisper model preloaded successfully!") logger.info("🎯 First pronunciation assessment will be much faster!") else: logger.warning("⚠️ Failed to preload Whisper model, will load on first request") except Exception as e: logger.error(f"❌ Error during Whisper preloading: {e}") logger.warning("⚠️ Continuing without preload, model will load on first request") startup_time = time.time() - startup_start logger.info(f"🎯 English Tutor API startup completed in {startup_time:.2f}s") logger.info("🌟 API is ready to serve pronunciation assessments!") yield # Application runs here # Shutdown logger.info("🛑 Shutting down English Tutor API...") def create_app(): app = FastAPI( docs_url="/", title="English Tutor API with Optimized Whisper", description="Pronunciation assessment API with preloaded Whisper for faster inference", version="2.1.0", lifespan=lifespan # Enable preloading during startup ) app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) # Add health check endpoint for monitoring Whisper status @app.get("/health") async def health_check(): """Health check endpoint that also verifies Whisper is loaded""" try: from src.apis.routes.speaking_route import global_assessor whisper_loaded = global_assessor is not None model_name = global_assessor.asr.whisper_model_name if whisper_loaded else None return { "status": "healthy", "whisper_preloaded": whisper_loaded, "whisper_model": model_name, "api_version": "2.1.0", "message": "English Tutor API is running" + (" with preloaded Whisper!" if whisper_loaded else "") } except Exception as e: return { "status": "healthy", "whisper_preloaded": False, "error": str(e), "api_version": "2.1.0" } return app