This repository has been archived by the owner on Aug 25, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 8
/
serve_http.py
85 lines (63 loc) · 1.99 KB
/
serve_http.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
"""
Script for serving.
"""
import json
import pickle
import numpy as np
import pandas as pd
from boxkite.monitoring.service import ModelMonitoringService
from flask import Flask, Response, current_app, request
model = pickle.load(open("/artefact/model.pkl", "rb"))
feature_cols = pickle.load(open("/artefact/feature_cols.pkl", "rb"))
# Simulate redis store
redis = pd.read_parquet("/artefact/test.gz.parquet")
def read_redis_features(sk_id: str) -> list:
"""Gets all the values from redis."""
# Simulate querying redis
row = redis.query(f"SK_ID_CURR == {sk_id}")
if row.empty:
return None
return row[feature_cols]
def predict_score(request_json: dict) -> float:
"""Predict function."""
# Get features
sk_id = request_json["sk_id"]
row_feats = read_redis_features(sk_id)
# Score
if row_feats is not None:
prob = model.predict_proba(row_feats)[:, 1].item()
# Log the prediction
current_app.monitor.log_prediction(
request_body=json.dumps(request_json),
features=row_feats.values[0],
output=prob,
)
return prob
return np.nan
# pylint: disable=invalid-name
app = Flask(__name__)
@app.before_first_request
def init_background_threads():
"""
Global objects with daemon threads will be stopped by
gunicorn --preload flag. So instantiate them here instead.
"""
current_app.monitor = ModelMonitoringService()
@app.route("/metrics", methods=["GET"])
def get_metrics():
"""Returns real time feature values recorded by prometheus
"""
body, content_type = current_app.monitor.export_http(
params=request.args.to_dict(flat=False),
headers=request.headers,
)
return Response(body, content_type=content_type)
@app.route("/", methods=["POST"])
def get_prob() -> dict:
"""Returns probability."""
return {"prob": predict_score(request.json)}
def main():
"""Starts the Http server"""
app.run()
if __name__ == "__main__":
main()