bank-fraud / app /main.py
root
init
942b115
Raw
History Blame Contribute Delete
2.19 kB
"""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.
"""
@asynccontextmanager
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)