Spaces:
Sleeping
Sleeping
File size: 4,260 Bytes
71c85a4 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 | """
FASTAPI + GRADIO SERVING APPLICATION - Production-Ready ML Model Serving
========================================================================
This application provides a complete serving solution for the PaySim model
with both programmatic API access and a user-friendly web interface.
Architecture:
- FastAPI: High-performance REST API with automatic OpenAPI documentation
- Gradio: User-friendly web UI for manual testing and demonstrations
- Pydantic: Data validation and automatic API documentation
"""
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from typing import Literal
import gradio as gr
from src.app.inference import predict
app = FastAPI(
title="PaySim Prediction API",
description="ML API for predicting Transaction Fraud",
version="1.0.0"
)
@app.get("/health")
def health_check():
"""
Health check endpoint for monitoring and load balancer health checks.
"""
return {"status": "ok"}
class TransactionData(BaseModel):
"""
This is the schema for PaySim prediction
This schema defines the exact features required for prediction
Here goes only the columns that are consumed not even the engineered ones"""
step: int #Represents a unit of time in the real world, with 1 step equating to 1 hour.
#The total simulation spans 744 steps, equivalent to 30 days
type:str #Transaction type
amount:float #The transaction amount
oldbalanceOrg: float #Sender balance before transaction
newbalanceOrig: float #Sender new balance after transactions
oldbalanceDest: float #receiver old balance
newbalanceDest: float #receiver new balance
@app.post("/predict")
def predict_endpoint(data: TransactionData):
try:
return predict(data.model_dump()) # model_dump() -> plain dict
except ValueError as e:
raise HTTPException(status_code=400, detail=str(e))
# ---------------GRADIO--------------------
def gradio_interface(step,type,amount,oldbalanceOrg,
newbalanceOrig,oldbalanceDest,newbalanceDest):
""""This function:
1. Takes individual form inputs from Gradio UI
2. Constructs the data dictionary matching the API schema
3. Calls the same inference pipeline used by the API
4. Returns user-friendly prediction string"""
#construct data dictionary matching the schema
data = {
"step":int(step),
"type":type,
"amount":float(amount),
"oldbalanceOrg":float(oldbalanceOrg),
"newbalanceOrig":float(newbalanceOrig),
"oldbalanceDest": float(oldbalanceDest),
"newbalanceDest":float(newbalanceDest),
}
#Call same inference pipeline as API endpoint
result = predict(data)
prob = result["fraud_probability"]
label = "Fraud" if result["is_fraud"] else "Not Fraud"
return f"{label} — fraud probability: {prob * 100:.2f}%"
# === GRADIO UI CONFIGURATION ===
demo = gr.Interface(
fn = gradio_interface,
inputs=[
gr.Number(label="Step", value=0, minimum=0, maximum=743),
gr.Dropdown(["CASH_OUT", "TRANSFER"], label="Transaction Type", value="TRANSFER"),
gr.Number(label="Amount (EU)", value=0, minimum=0),
gr.Number(label="Sender's Old Balance"),
gr.Number(label="Sender's New Balance"),
gr.Number(label="Receiver's Old Balance"),
gr.Number(label="Receiver's New Balance"),
],
outputs=gr.Textbox(label= "Fraud Prediction",lines=1),
title= "Pay Sim transaction Fraud Prediction",
description="""
Predict if the transaction is a fraud or not using Machine Learning
Fill in the transaction's details below to get a prediction. The
model is using a simple MLP on historical data.""",
flagging_mode="never", # no writable flagged/ dir needed (HF runs non-root)
theme = gr.themes.Soft()
)
app = gr.mount_gradio_app(
app,
demo,
path="/" # Gradio UI is the landing page; API still at /predict and /docs
)
|