Spaces:
Paused
Paused
import logging.config | |
import time | |
from contextlib import asynccontextmanager | |
import psutil | |
from fastapi import Depends, FastAPI, Request | |
from fastapi.responses import JSONResponse | |
import mappingservice.dependencies as deps | |
from mappingservice.constants import AVAILABLE_LANGUAGES, MODEL_NAMES | |
from mappingservice.dependencies import get_api_key, get_settings | |
from mappingservice.ms.model_loader import ModelLoader | |
from mappingservice.routers import admin, room | |
from mappingservice.utils import log_memory_usage, predict_language | |
logging.config.fileConfig("logging.conf", disable_existing_loggers=False) | |
logger = logging.getLogger(__name__) | |
async def lifespan(application: FastAPI): | |
# Load the ML models | |
settings = get_settings() | |
initial_memory = psutil.Process().memory_info().rss | |
start_time = time.time() | |
ml_model = ModelLoader(settings, MODEL_NAMES) | |
for k in MODEL_NAMES: | |
logger.info(f"Loading model: {k}...") | |
for lang in AVAILABLE_LANGUAGES: | |
model_pipeline = ml_model.get_model(k, lang) | |
try: | |
deps.mc[k][lang] = model_pipeline | |
except KeyError: | |
deps.mc[k] = {} | |
deps.mc[k][lang] = model_pipeline | |
elapsed_time = time.time() - start_time | |
num_cores = psutil.cpu_count(logical=True) | |
total_ram = psutil.virtual_memory().total / (1024 ** 3) # Convert to GB | |
final_memory = psutil.Process().memory_info().rss | |
total_memory_used = (final_memory - initial_memory) / (1024 ** 3) # Convert to GB | |
logger.info("*" * 60) # ASCII Art | |
logger.info(f"* Number of Cores: {num_cores}") | |
logger.info(f"* Total RAM: {total_ram:.2f} GB") | |
logger.info( | |
f"* AI Models loaded in {elapsed_time:.2f} seconds, " | |
f"using {total_memory_used:.2f} GB" | |
) | |
logger.info("*" * 60) # ASCII Art | |
yield | |
# Clean up the ML models and release the resources | |
deps.mc.clear() | |
app = FastAPI(root_path="/ml-api", lifespan=lifespan) | |
async def handle_exceptions(request: Request, call_next): | |
try: | |
response = await call_next(request) | |
return response | |
except Exception as e: | |
logging.error(f"Unhandled error: {e}") | |
logging.exception(e) | |
log_memory_usage() | |
return JSONResponse(status_code=500, content={ | |
"message": "Internal Server Error" | |
}) | |
finally: | |
log_memory_usage() | |
async def detect_language(request: Request, call_next): | |
room_description = request.query_params.get("room_description", "") | |
language = "en" | |
if not room_description: | |
try: | |
body = await request.json() | |
room_description = body.get("room_description", "") | |
except ValueError: | |
# If the room description is still empty, continue with the request as | |
# the language detection is not required | |
if not room_description: | |
response = await call_next(request) | |
return response | |
try: | |
language = predict_language(room_description) | |
if language not in AVAILABLE_LANGUAGES: | |
logger.error(f"Unsupported language for room description: {room_description}. Falling back to model prediction.") # noqa: E501 | |
language = deps.mc['lang_detect']['na'].predict(room_description)[0][0]['label'] # noqa: E501 | |
if language not in AVAILABLE_LANGUAGES: | |
logger.error(f"Unsupported language for room description using model prediction: {room_description}. Falling back to English.") # noqa: E501 | |
language = "en" | |
except Exception as e: | |
logger.error(f"Error detecting language: {e}") | |
request.state.predicted_language = language | |
response = await call_next(request) | |
return response | |
app.include_router(room.router, dependencies=[Depends(get_api_key)]) | |
app.include_router(admin.router) | |