cyril-sabu commited on
Commit
d1660ed
Β·
verified Β·
1 Parent(s): 7f41344

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +97 -82
app.py CHANGED
@@ -1,82 +1,97 @@
1
- import os
2
- import joblib
3
- import pandas as pd
4
- from flask import Flask, request, jsonify
5
- from flask_cors import CORS
6
-
7
- # Initialize the Flask application
8
- app = Flask(__name__)
9
- CORS(app) # Enable Cross-Origin Resource Sharing
10
-
11
- # --- Model Loading ---
12
- # The model is loaded once when the application starts.
13
- try:
14
- # In Hugging Face Spaces, your files are all in the same root directory.
15
- model_path = 'realistic_fraud_model.pkl'
16
- model = joblib.load(model_path)
17
- print("βœ… Model loaded successfully.")
18
- except FileNotFoundError:
19
- print(f"❌ Error: Model file not found at '{model_path}'")
20
- model = None
21
- except Exception as e:
22
- print(f"❌ An error occurred while loading the model: {e}")
23
- model = None
24
- # --- End of Model Loading ---
25
-
26
-
27
- # --- API Endpoints ---
28
-
29
- # Root endpoint to check if the API is running
30
- @app.route('/', methods=['GET'])
31
- def home():
32
- return jsonify({"status": "API is running", "model_loaded": model is not None})
33
-
34
-
35
- # Prediction endpoint
36
- @app.route('/predict', methods=['POST'])
37
- def predict():
38
- """
39
- Receives feature data in JSON format and returns a fraud prediction.
40
- """
41
- if model is None:
42
- return jsonify({"error": "Model is not loaded."}), 500
43
-
44
- try:
45
- # Get data from the POST request
46
- data = request.get_json(force=True)
47
-
48
- # IMPORTANT: You must know the order of features your model expects.
49
- # The input JSON should be an object with a key like "features"
50
- # which is a list of values in the correct order.
51
- # Example: {"features": [0.1, -0.5, 1.2, ...]}
52
- features = data['features']
53
-
54
- # Convert to a Pandas DataFrame for prediction
55
- # The feature names here are placeholders, they don't affect a
56
- # scikit-learn model prediction if the order is correct.
57
- feature_df = pd.DataFrame([features])
58
-
59
- # Make prediction
60
- prediction = model.predict(feature_df)
61
- prediction_proba = model.predict_proba(feature_df)
62
-
63
- # Return the result as JSON
64
- return jsonify({
65
- 'prediction': int(prediction[0]),
66
- 'is_fraud': bool(prediction[0] == 1),
67
- 'prediction_probability': {
68
- 'not_fraud': prediction_proba[0][0],
69
- 'fraud': prediction_proba[0][1]
70
- }
71
- })
72
-
73
- except Exception as e:
74
- return jsonify({"error": f"An error occurred during prediction: {str(e)}"}), 400
75
-
76
- # --- End of API Endpoints ---
77
-
78
-
79
- if __name__ == '__main__':
80
- # The 'port' is set by Hugging Face Spaces, default to 8080 for local testing
81
- port = int(os.environ.get("PORT", 8080))
82
- app.run(host='0.0.0.0', port=port)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import joblib
3
+ import torch
4
+ import torch.nn as nn
5
+ import numpy as np
6
+ from flask import Flask, request, jsonify
7
+ from flask_cors import CORS
8
+
9
+ # --- 1. Define the same PyTorch Model Architecture ---
10
+ # This class must be identical to the one in your training script.
11
+ class FraudClassifier(nn.Module):
12
+ def __init__(self):
13
+ super(FraudClassifier, self).__init__()
14
+ self.layer1 = nn.Linear(2, 16) # 2 input features
15
+ self.layer2 = nn.Linear(16, 8)
16
+ self.layer3 = nn.Linear(8, 1) # 1 output for binary classification
17
+ self.relu = nn.ReLU()
18
+ self.sigmoid = nn.Sigmoid()
19
+
20
+ def forward(self, x):
21
+ x = self.relu(self.layer1(x))
22
+ x = self.relu(self.layer2(x))
23
+ x = self.sigmoid(self.layer3(x))
24
+ return x
25
+
26
+ # --- 2. Initialize Flask App and Load Assets ---
27
+ app = Flask(__name__)
28
+ CORS(app) # Enable Cross-Origin Resource Sharing
29
+
30
+ # The model and scaler are loaded once when the application starts.
31
+ model = None
32
+ scaler = None
33
+
34
+ try:
35
+ # Load the PyTorch model
36
+ model = FraudClassifier()
37
+ # Use map_location=torch.device('cpu') for compatibility if the server doesn't have a GPU
38
+ model.load_state_dict(torch.load("realistic_fraud_model.pth", map_location=torch.device('cpu')))
39
+ model.eval() # Set model to evaluation mode
40
+ print("βœ… PyTorch model loaded successfully.")
41
+
42
+ # Load the scaler
43
+ scaler = joblib.load("scaler.pkl")
44
+ print("βœ… Scaler loaded successfully.")
45
+
46
+ except Exception as e:
47
+ print(f"❌ An error occurred during asset loading: {e}")
48
+
49
+ # --- 3. API Endpoints ---
50
+ @app.route('/', methods=['GET'])
51
+ def home():
52
+ """Root endpoint to check API status."""
53
+ return jsonify({
54
+ "status": "API is running",
55
+ "model_loaded": model is not None,
56
+ "scaler_loaded": scaler is not None
57
+ })
58
+
59
+ @app.route('/predict', methods=['POST'])
60
+ def predict():
61
+ """Receives feature data and returns a fraud prediction."""
62
+ if not model or not scaler:
63
+ return jsonify({"error": "Model or scaler not loaded."}), 500
64
+
65
+ try:
66
+ data = request.get_json(force=True)
67
+ # Expected input: {"features": [value_ether, fee_ether]}
68
+ features = np.array(data['features']).reshape(1, -1)
69
+
70
+ # Apply the same scaling as in training
71
+ scaled_features = scaler.transform(features)
72
+
73
+ # Convert to PyTorch tensor
74
+ features_tensor = torch.tensor(scaled_features, dtype=torch.float32)
75
+
76
+ # Make prediction
77
+ with torch.no_grad(): # Disable gradient calculation for inference
78
+ probability = model(features_tensor)
79
+
80
+ prob_fraud = probability.item() # Get the float value from the tensor
81
+ prediction = 1 if prob_fraud > 0.5 else 0
82
+
83
+ # Return the result
84
+ return jsonify({
85
+ 'prediction': prediction,
86
+ 'is_fraud': bool(prediction == 1),
87
+ 'prediction_probability': {
88
+ 'not_fraud': 1.0 - prob_fraud,
89
+ 'fraud': prob_fraud
90
+ }
91
+ })
92
+ except Exception as e:
93
+ return jsonify({"error": f"An error occurred during prediction: {str(e)}"}), 400
94
+
95
+ if __name__ == '__main__':
96
+ port = int(os.environ.get("PORT", 8080))
97
+ app.run(host='0.0.0.0', port=port)