-
Notifications
You must be signed in to change notification settings - Fork 0
/
app.py
117 lines (95 loc) · 3.2 KB
/
app.py
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
from flask import Flask, request, jsonify, abort
from dotenv import load_dotenv
import os
import time
if os.getenv("IS_PROD") == "true":
print("Loading in prod")
else:
print("Loading in dev")
load_dotenv(verbose=True)
from chalicelib import log_config
from chalicelib.db import ModelsDatabase
from chalicelib.features import FeatureExtractor
from chalicelib.dao.blobstore.s3.s3blobstore import S3Blobstore
from chalicelib.dao.docstore.dynamo import DynamoDocstore as Docstore
app = Flask(__name__)
access_key = os.getenv('ACCESS_KEY')
secret_key = os.getenv('SECRET_KEY')
bucket_name = os.getenv('PRIMARY_BUCKET')
table_name = os.getenv('DYNAMO_TABLE')
print(bucket_name, "is the bucket")
blobstore = S3Blobstore(bucket_name, access_key, secret_key)
docstore = Docstore(table_name, access_key, secret_key)
models_db = ModelsDatabase(blobstore, docstore)
fe = FeatureExtractor()
@app.route('/')
def index():
resp = {
'model_loading_status': models_db.status,
'models_loaded' : list(models_db.cache.keys())
}
return jsonify(resp)
@app.route('/model/<model_id>/<version>/predict', methods=['POST'])
def predict(model_id, version):
try:
req = request.get_json(force=True)
except Exception as e:
print(str(e))
return f'Invalid JSON body \n {str(e)} \n', 500
t0 = time.time()
try:
model = models_db.get_model(model_id, version) # LudwigModel
except KeyError as e:
print(e)
return str(e), 404
# # features = fe.extract_features(model, req) # TODO: implement this
t1 = time.time()
try:
prediction = model.predict(req, blobstore) #TODO: why a delay the first time?
except ValueError as e:
print(e)
return str(e), 404
t2 = time.time()
username = models_db.cache[f'{model_id}/{version}']['metadata'].get('username', 'unknown') # TODO turn this into a method
model.increment_counter(docstore, username, model_id, version)
t3 = time.time()
resp = {
"time_to_get_model" : t1 - t0,
"time_to_get_prediction" : t2 - t1,
"time_to_increment_counter" : t3 - t2,
"total_response_time" : t3 - t0
}
if isinstance(prediction, dict):
resp = {**resp, **prediction}
else:
resp['prediction'] = prediction
# models_db.save_prediction(resp)
return jsonify(resp)
@app.route('/reload')
def reload():
try:
models_db.reload_models()
except Exception as e:
print(str(e))
return 'reload unsuccessful', 400
return 'reload successful', 200
@app.route('/model/<model_id>/<version>/remove', methods=['DELETE'])
def remove(model_id, version):
try:
resp = models_db.remove_model(model_id, version)
except Exception as e:
print(str(e))
return 'removal unsuccessful', 400
return resp
@app.route('/model/<model_id>/<version>/load', methods=['GET'])
def load(model_id, version):
try:
resp = models_db.load_model(model_id, version)
except Exception as e:
print(str(e))
return 'model load unsuccessful', 500
return resp
def main():
app.run(debug=False, host=os.getenv("host"), port=int(os.getenv("PORT")), threaded=True)
if __name__ == '__main__':
main()