from contextlib import asynccontextmanager from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware from fastapi.middleware.gzip import GZipMiddleware from .config import settings from .core.errors import install_exception_handlers from .core.logging import setup_logging from .db.engine import init_db from .routers import analyze, feedback, health, history, stats @asynccontextmanager async def lifespan(app: FastAPI): setup_logging() init_db() app.state.whisper = None app.state.clf = None try: from .ml.whisper import load_whisper app.state.whisper = load_whisper(settings) except Exception: app.state.whisper = None try: from .ml.classifier import load_classifier app.state.clf = load_classifier(settings.clf_path) except Exception: app.state.clf = None yield app.state.whisper = None app.state.clf = None app = FastAPI( title="AP27510301 Fraud Detector API", version=settings.app_version, description=( "Anti-fraud detection API for Kazakhstan. " "Analyzes Russian and Kazakh text and audio for signs of social engineering." ), lifespan=lifespan, docs_url="/docs", redoc_url="/redoc", ) # Compress JSON / text responses >1 KB. History pages and audio analyses # with feature evidence routinely fit this, this is essentially free # bandwidth savings for the mobile client over cellular networks. app.add_middleware(GZipMiddleware, minimum_size=1024, compresslevel=5) app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_methods=["*"], allow_headers=["X-Device-Id", "Content-Type", "Accept-Language"], ) install_exception_handlers(app) app.include_router(health.router, prefix="/v1") app.include_router(analyze.router, prefix="/v1") app.include_router(history.router, prefix="/v1") app.include_router(feedback.router, prefix="/v1") app.include_router(stats.router, prefix="/v1") app.include_router(health.router)