Dan Vancea commited on
Commit
3269a5c
·
1 Parent(s): a635c41

Update call_models.py

Browse files
Files changed (1) hide show
  1. call_models.py +61 -0
call_models.py CHANGED
@@ -3,14 +3,75 @@ from datetime import datetime
3
  from flask import Flask, request, jsonify
4
  from flask_cors import CORS
5
  from dotenv import load_dotenv
 
6
 
7
  from predict_from_supabase import predict_replacements
 
8
 
9
  load_dotenv()
10
 
11
  app = Flask(__name__)
12
  CORS(app)
13
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
 
15
  @app.route("/api/schedule", methods=["POST"])
16
  def schedule():
 
3
  from flask import Flask, request, jsonify
4
  from flask_cors import CORS
5
  from dotenv import load_dotenv
6
+ import numpy as np
7
 
8
  from predict_from_supabase import predict_replacements
9
+ from model import DegradationModel, COMPONENT_NAMES
10
 
11
  load_dotenv()
12
 
13
  app = Flask(__name__)
14
  CORS(app)
15
 
16
+ # Load the default degradation model once at startup
17
+ _DEFAULT_MODEL_PATH = "model.npz"
18
+ _degradation_model: DegradationModel | None = None
19
+
20
+ def _get_model(path: str = _DEFAULT_MODEL_PATH) -> DegradationModel:
21
+ global _degradation_model
22
+ if _degradation_model is None:
23
+ _degradation_model = DegradationModel.load(path)
24
+ return _degradation_model
25
+
26
+
27
+ @app.route("/api/predict", methods=["POST"])
28
+ def predict():
29
+ data = request.json or {}
30
+
31
+ h0_raw = data.get("h0")
32
+ X_raw = data.get("X")
33
+ weeks = float(data.get("weeks", 6))
34
+ model_path = data.get("model_path", _DEFAULT_MODEL_PATH)
35
+
36
+ if h0_raw is None:
37
+ return jsonify({"error": "h0 (current health state) is required"}), 400
38
+ if X_raw is None:
39
+ return jsonify({"error": "X (input conditions) is required"}), 400
40
+
41
+ try:
42
+ model = _get_model(model_path)
43
+ except FileNotFoundError:
44
+ return jsonify({"error": f"model file not found: {model_path}"}), 404
45
+
46
+ h0 = np.array(h0_raw, dtype=float)
47
+ X = np.array(X_raw, dtype=float)
48
+
49
+ if h0.shape != (model.N,):
50
+ return jsonify({"error": f"h0 must have {model.N} elements, got {h0.shape}"}), 400
51
+ if X.shape != (model.C,):
52
+ return jsonify({"error": f"X must have {model.C} elements, got {X.shape}"}), 400
53
+
54
+ # Euler integration from h0, deterministic, 100 steps per week
55
+ tau_hours = weeks * 7 * 24.0
56
+ n_steps = int(weeks) * 20
57
+ dt = tau_hours / n_steps
58
+ steps_per_week = n_steps // int(weeks)
59
+
60
+ h = h0.copy()
61
+ weekly_snapshots = [h0.tolist()]
62
+
63
+ for step in range(1, n_steps + 1):
64
+ h = np.clip(h + dt * model.f(h, X), 0.0, 1.0)
65
+ if step % steps_per_week == 0:
66
+ weekly_snapshots.append(h.tolist())
67
+
68
+ return jsonify({
69
+ "component_names": COMPONENT_NAMES,
70
+ "weeks": weeks,
71
+ "weekly_health": weekly_snapshots, # index 0 = now, index k = after k weeks
72
+ "final_health": h.tolist(),
73
+ })
74
+
75
 
76
  @app.route("/api/schedule", methods=["POST"])
77
  def schedule():