Esvanth commited on
Commit
ff2be28
Β·
verified Β·
1 Parent(s): 818583c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +75 -40
app.py CHANGED
@@ -2,35 +2,49 @@
2
  MindScan β€” Flask Backend
3
  NCI H9DAI Research Project 2026
4
 
5
- Loads all 12 models (3 classical + XLM-RoBERTa per dataset)
6
- and serves predictions via a single /predict endpoint.
 
 
 
 
 
 
 
 
 
7
 
8
- Run: python app.py
9
  Open: http://localhost:5000
10
  """
11
 
12
  from flask import Flask, request, jsonify, render_template
13
- import os, time
14
-
15
- # Import our prediction module
16
- from predict import load_all_models, predict_all, models_loaded
17
 
18
  app = Flask(__name__)
19
 
 
 
 
 
20
  # ─────────────────────────────────────────────────────────────────
21
- # Load models once at startup β€” not per request
22
  # ─────────────────────────────────────────────────────────────────
23
  print("\n" + "="*55)
24
  print(" MindScan β€” Starting up")
25
  print("="*55)
26
- print(" Loading models... (XLM-RoBERTa takes ~30s on CPU)")
27
-
28
- start = time.time()
29
- load_all_models()
30
- elapsed = time.time() - start
31
 
32
- print(f" βœ… All models loaded in {elapsed:.1f}s")
33
- print(f" 🌐 Open: http://localhost:5000")
 
 
 
 
 
 
 
 
 
 
34
  print("="*55 + "\n")
35
 
36
 
@@ -40,54 +54,75 @@ print("="*55 + "\n")
40
 
41
  @app.route('/')
42
  def index():
43
- """Serve the main UI."""
44
  return render_template('index.html')
45
 
46
 
 
 
 
 
 
47
  @app.route('/predict', methods=['POST'])
48
  def predict():
49
- """
50
- POST /predict
51
- Body: { "text": "your text here" }
52
- Returns: full prediction JSON from all 12 models
53
- """
54
  data = request.get_json()
55
 
56
  if not data or 'text' not in data:
57
  return jsonify({'error': 'Missing "text" field in request body'}), 400
58
 
59
  text = data['text'].strip()
60
-
61
  if not text:
62
  return jsonify({'error': 'Text cannot be empty'}), 400
63
-
64
  if len(text) > 5000:
65
  return jsonify({'error': 'Text too long (max 5000 characters)'}), 400
66
 
67
- if not models_loaded():
68
- return jsonify({'error': 'Models not loaded yet β€” try again in a moment'}), 503
69
-
70
- try:
71
- t0 = time.time()
72
- result = predict_all(text)
73
- result['processing_time_ms'] = round((time.time() - t0) * 1000)
74
- return jsonify(result)
75
- except Exception as e:
76
- print(f"Prediction error: {e}")
77
- return jsonify({'error': f'Prediction failed: {str(e)}'}), 500
 
 
 
 
 
 
 
 
 
 
 
 
 
 
78
 
79
 
80
  @app.route('/health')
81
  def health():
82
- """Quick health check endpoint."""
83
- return jsonify({
84
- 'status': 'ok',
85
- 'models_ready': models_loaded()
86
- })
 
 
 
 
 
 
 
87
 
88
 
89
  # ─────────────────────────────────────────────────────────────────
90
  # START
91
  # ─────────────────────────────────────────────────────────────────
92
  if __name__ == '__main__':
93
- app.run(debug=False, host='0.0.0.0', port=int(os.environ.get('PORT', 5000)))
 
 
 
 
2
  MindScan β€” Flask Backend
3
  NCI H9DAI Research Project 2026
4
 
5
+ Two modes β€” auto-detected at startup:
6
+
7
+ PROXY mode (default, no local models needed)
8
+ Forwards /predict to the HuggingFace Space.
9
+ Set HF_SPACE_URL env var to override the target.
10
+ Run: python app.py
11
+
12
+ LOCAL mode (models/ directory present)
13
+ Loads all 12 models from disk and runs inference locally.
14
+ Activated automatically when models/ exists.
15
+ Run: python app.py
16
 
 
17
  Open: http://localhost:5000
18
  """
19
 
20
  from flask import Flask, request, jsonify, render_template
21
+ import os, time, requests as _requests
 
 
 
22
 
23
  app = Flask(__name__)
24
 
25
+ HF_SPACE_URL = os.environ.get('HF_SPACE_URL', 'https://esvanth-mindscan.hf.space')
26
+ _LOCAL_MODELS = os.path.join(os.path.dirname(__file__), 'models', 'classical')
27
+ _use_local = os.path.isdir(_LOCAL_MODELS)
28
+
29
  # ─────────────────────────────────────────────────────────────────
30
+ # Startup
31
  # ─────────────────────────────────────────────────────────────────
32
  print("\n" + "="*55)
33
  print(" MindScan β€” Starting up")
34
  print("="*55)
 
 
 
 
 
35
 
36
+ if _use_local:
37
+ print(" LOCAL mode β€” loading models from disk...")
38
+ from predict import load_all_models, predict_all, models_loaded
39
+ start = time.time()
40
+ load_all_models()
41
+ print(f" βœ… Models loaded in {time.time()-start:.1f}s")
42
+ else:
43
+ print(" PROXY mode β€” no local models found")
44
+ print(f" β†’ Forwarding requests to: {HF_SPACE_URL}")
45
+ print(" (Download models/ from Google Drive to switch to LOCAL mode)")
46
+
47
+ print(f" 🌐 Open: http://localhost:{os.environ.get('PORT', 5001)}")
48
  print("="*55 + "\n")
49
 
50
 
 
54
 
55
  @app.route('/')
56
  def index():
 
57
  return render_template('index.html')
58
 
59
 
60
+ @app.route('/flow')
61
+ def flow():
62
+ return render_template('flow_diagram.html')
63
+
64
+
65
  @app.route('/predict', methods=['POST'])
66
  def predict():
 
 
 
 
 
67
  data = request.get_json()
68
 
69
  if not data or 'text' not in data:
70
  return jsonify({'error': 'Missing "text" field in request body'}), 400
71
 
72
  text = data['text'].strip()
 
73
  if not text:
74
  return jsonify({'error': 'Text cannot be empty'}), 400
 
75
  if len(text) > 5000:
76
  return jsonify({'error': 'Text too long (max 5000 characters)'}), 400
77
 
78
+ if _use_local:
79
+ # ── Local inference ───────────────────────────────────────
80
+ if not models_loaded():
81
+ return jsonify({'error': 'Models not ready yet β€” try again in a moment'}), 503
82
+ try:
83
+ t0 = time.time()
84
+ result = predict_all(text)
85
+ result['processing_time_ms'] = round((time.time() - t0) * 1000)
86
+ return jsonify(result)
87
+ except Exception as e:
88
+ print(f"Prediction error: {e}")
89
+ return jsonify({'error': f'Prediction failed: {str(e)}'}), 500
90
+ else:
91
+ # ── Proxy to HuggingFace Space ────────────────────────────
92
+ try:
93
+ r = _requests.post(
94
+ f'{HF_SPACE_URL}/predict',
95
+ json={'text': text},
96
+ timeout=120,
97
+ )
98
+ return r.content, r.status_code, {'Content-Type': 'application/json'}
99
+ except _requests.exceptions.Timeout:
100
+ return jsonify({'error': 'HuggingFace Space timed out β€” it may be waking up, try again in 30s'}), 504
101
+ except _requests.exceptions.ConnectionError:
102
+ return jsonify({'error': f'Cannot reach {HF_SPACE_URL} β€” check your internet connection'}), 503
103
 
104
 
105
  @app.route('/health')
106
  def health():
107
+ if _use_local:
108
+ from predict import models_loaded
109
+ return jsonify({'status': 'ok', 'mode': 'local', 'models_ready': models_loaded()})
110
+ else:
111
+ try:
112
+ r = _requests.get(f'{HF_SPACE_URL}/health', timeout=10)
113
+ data = r.json()
114
+ data['mode'] = 'proxy'
115
+ data['hf_space'] = HF_SPACE_URL
116
+ return jsonify(data)
117
+ except Exception as e:
118
+ return jsonify({'status': 'error', 'mode': 'proxy', 'message': str(e)}), 503
119
 
120
 
121
  # ─────────────────────────────────────────────────────────────────
122
  # START
123
  # ─────────────────────────────────────────────────────────────────
124
  if __name__ == '__main__':
125
+ import threading, webbrowser
126
+ port = int(os.environ.get('PORT', 5001))
127
+ threading.Timer(1.2, lambda: webbrowser.open(f'http://localhost:{port}')).start()
128
+ app.run(debug=False, host='0.0.0.0', port=port)