Spaces:
Sleeping
Sleeping
| 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) | |
| 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 | |
| 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 | |