hariharan220 commited on
Commit
3baf523
·
verified ·
1 Parent(s): 3bc76c7

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +74 -0
app.py ADDED
@@ -0,0 +1,74 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import numpy as np
2
+ import tensorflow as tf
3
+ import joblib
4
+ import logging
5
+ from fastapi import FastAPI, HTTPException
6
+ from pydantic import BaseModel
7
+ from typing import List
8
+
9
+ # FastAPI initialization
10
+ app = FastAPI(title="Universal Stock Prediction API")
11
+
12
+ # Request model structure
13
+ class StockPredictionInput(BaseModel):
14
+ stock_symbol: str
15
+ prices: List[List[float]]
16
+
17
+ # Constants
18
+ SEQ_LENGTH = 150
19
+ NUM_FEATURES = 10
20
+
21
+ # Load the trained model
22
+ try:
23
+ model = tf.keras.models.load_model("universal_stock_model_with_fundamentals.h5")
24
+ logging.info("✅ Model loaded successfully.")
25
+ except Exception as e:
26
+ logging.error(f"❌ Failed to load model: {e}")
27
+ raise RuntimeError("Model file not found or corrupted!")
28
+
29
+ @app.get("/")
30
+ def home():
31
+ return {"message": "Welcome to Stock Prediction API"}
32
+
33
+ @app.post("/predict")
34
+ async def predict_stock(data: StockPredictionInput):
35
+ stock = data.stock_symbol.upper()
36
+ logging.info(f"🔍 Processing request for stock: {stock}")
37
+
38
+ try:
39
+ scaler = joblib.load(f"scaler_{stock}.pkl")
40
+ logging.info(f"✅ Scaler loaded for stock: {stock}")
41
+ except Exception:
42
+ logging.warning(f"⚠️ Scaler not found for {stock}. Using identity transform.")
43
+ scaler = None
44
+
45
+ # Convert input to NumPy array and validate shape
46
+ prices_array = np.array(data.prices, dtype=np.float32)
47
+ if prices_array.shape != (SEQ_LENGTH, NUM_FEATURES):
48
+ raise HTTPException(status_code=400, detail=f"Expected input shape ({SEQ_LENGTH}, {NUM_FEATURES}) but got {prices_array.shape}")
49
+
50
+ # Scale first 9 features
51
+ features_to_scale = prices_array[:, :9]
52
+ extra_feature = prices_array[:, 9:]
53
+
54
+ if scaler:
55
+ features_scaled = scaler.transform(features_to_scale)
56
+ else:
57
+ features_scaled = features_to_scale
58
+
59
+ prices_scaled = np.concatenate([features_scaled, extra_feature], axis=1)
60
+ prices_scaled = np.expand_dims(prices_scaled, axis=0)
61
+
62
+ prediction = model.predict(prices_scaled)
63
+ predicted_price = float(prediction[0][0])
64
+
65
+ if scaler:
66
+ try:
67
+ dummy_input = np.zeros((1, 9))
68
+ dummy_input[0, 0] = predicted_price
69
+ inversed_values = scaler.inverse_transform(dummy_input)
70
+ predicted_price = inversed_values[0, 0]
71
+ except Exception as e:
72
+ logging.warning(f"⚠️ Error in inverse transformation: {e}")
73
+
74
+ return {"stock": stock, "predicted_price": round(predicted_price, 2)}