""" Example: How to integrate Whisper preloading in FastAPI app startup This shows how to preload Whisper model during FastAPI startup so the first inference will be much faster. """ from fastapi import FastAPI from contextlib import asynccontextmanager from src.apis.routes.speaking_route import router as speaking_router, preload_whisper_model from loguru import logger import time @asynccontextmanager async def lifespan(app: FastAPI): """ FastAPI lifespan context manager for startup and shutdown events """ # Startup logger.info("🚀 Starting FastAPI application...") startup_start = time.time() # Preload Whisper model during startup logger.info("📦 Preloading Whisper model...") success = preload_whisper_model(whisper_model="base.en") if success: logger.info("✅ Whisper model preloaded successfully!") else: logger.warning("⚠️ Failed to preload Whisper model, will load on first request") startup_time = time.time() - startup_start logger.info(f"🎯 FastAPI startup completed in {startup_time:.2f}s") yield # Application runs here # Shutdown logger.info("🛑 Shutting down FastAPI application...") # Create FastAPI app with lifespan app = FastAPI( title="English Tutor API with Whisper Preloading", description="Pronunciation assessment API with optimized Whisper startup", version="2.0.0", lifespan=lifespan # This enables the startup preloading ) # Include speaking routes app.include_router(speaking_router) @app.get("/") async def root(): return {"message": "English Tutor API with Whisper preloaded!", "status": "ready"} @app.get("/health") async def health_check(): """Health check endpoint that also verifies Whisper is loaded""" from src.apis.routes.speaking_route import global_assessor whisper_loaded = global_assessor is not None return { "status": "healthy", "whisper_preloaded": whisper_loaded, "model": global_assessor.asr.whisper_model_name if whisper_loaded else None } if __name__ == "__main__": import uvicorn # Run with uvicorn uvicorn.run( "example_app_with_preload:app", host="0.0.0.0", port=8000, reload=False, # Set to False for production to avoid reloading and losing preloaded model log_level="info" )