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
)