Spaces:
Configuration error
Configuration error
| """FastAPI application entrypoint (API-01..09). | |
| Run with: `uvicorn app.main:app --host 0.0.0.0 --port $APP_PORT` | |
| The model + SHAP explainer are loaded exactly once during the lifespan | |
| startup hook (EXPL-04) and stored on `app.state.model_bundle` -- every | |
| request reuses the same in-memory objects, never reloading per-request. | |
| """ | |
| from __future__ import annotations | |
| from contextlib import asynccontextmanager | |
| from fastapi import FastAPI | |
| from fastapi.middleware.cors import CORSMiddleware | |
| from fastapi.staticfiles import StaticFiles | |
| from app.auth import seed_officer_if_missing | |
| from app.config import settings | |
| from app.db.session import session_scope | |
| from app.routers import auth, client, health, officer, pages, predict | |
| from app.scoring import load_model_bundle | |
| DESCRIPTION = """ | |
| Score banking transactions for fraud risk in real time. | |
| Every prediction returns a probability, a low/medium/high risk tier, and | |
| the top SHAP features driving that specific score -- not just a black-box | |
| number. Predictions and alerts are persisted to MySQL. | |
| Two role-scoped surfaces sit on top of the same scoring pipeline: banking | |
| officers manage clients and review the fraud alert queue (`/officer/*`), | |
| clients submit and review their own transactions (`/client/*`). See | |
| **/guide** for a plain-language walkthrough of the scoring pipeline. | |
| """ | |
| async def lifespan(app: FastAPI): | |
| app.state.model_bundle = load_model_bundle(settings.MODEL_PATH) | |
| with session_scope() as db: | |
| seed_officer_if_missing(db) | |
| yield | |
| app = FastAPI( | |
| title="Banking Fraud Detection API", | |
| description=DESCRIPTION, | |
| version="1.0.0", | |
| lifespan=lifespan, | |
| ) | |
| app.add_middleware( | |
| CORSMiddleware, | |
| allow_origins=settings.ALLOWED_ORIGINS, | |
| allow_credentials=True, | |
| allow_methods=["*"], | |
| allow_headers=["*"], | |
| ) | |
| app.mount("/static", StaticFiles(directory="app/static"), name="static") | |
| app.mount("/reports", StaticFiles(directory="reports"), name="reports") | |
| app.include_router(health.router) | |
| app.include_router(auth.router) | |
| app.include_router(predict.router) | |
| app.include_router(officer.router) | |
| app.include_router(client.router) | |
| app.include_router(pages.router) | |