Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 15 additions & 4 deletions week3/project/app/classifier.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
from typing import List

from loguru import logger
import joblib

from sentence_transformers import SentenceTransformer
from sklearn.base import BaseEstimator, TransformerMixin
from sklearn.pipeline import Pipeline
Expand Down Expand Up @@ -72,7 +70,12 @@ def predict_proba(self, model_input: dict) -> dict:
...
}
"""
return {}
X = [
model_input['title'] + ' | ' + model_input['description']
]
probs = self.pipeline.predict_proba(X)[0]

return dict(zip(self.classes, probs))

def predict_label(self, model_input: dict) -> str:
"""
Expand All @@ -83,4 +86,12 @@ def predict_label(self, model_input: dict) -> str:

Output format: predicted label for the model input
"""
return ""
probs = self.predict_proba(model_input)
highest_prob = 0
label = ""
for k, v in probs.items():
if v > highest_prob:
highest_prob = v
label = k

return label
36 changes: 35 additions & 1 deletion week3/project/app/server.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
import json
import math
import time
from datetime import datetime
from fastapi import FastAPI
from pydantic import BaseModel
from loguru import logger
Expand All @@ -19,6 +23,7 @@ class PredictResponse(BaseModel):

MODEL_PATH = "../data/news_classifier.joblib"
LOGS_OUTPUT_PATH = "../data/logs.out"
global_data = {}

app = FastAPI()

Expand All @@ -34,6 +39,11 @@ def startup_event():
Access to the model instance and log file will be needed in /predict endpoint, make sure you
store them as global variables
"""

global_data['file_log_handler'] = open(LOGS_OUTPUT_PATH, 'w+')
global_data['cls'] = NewsCategoryClassifier(verbose=True)
global_data['cls'].load(MODEL_PATH)

logger.info("Setup completed")


Expand All @@ -45,6 +55,10 @@ def shutdown_event():
1. Make sure to flush the log file and close any file pointers to avoid corruption
2. Any other cleanups
"""

if global_data['file_log_handler'] is not None:
global_data['file_log_handler'].close()
global_data['file_log_handler'] = None
logger.info("Shutting down application")


Expand All @@ -65,7 +79,27 @@ def predict(request: PredictRequest):
}
3. Construct an instance of `PredictResponse` and return
"""
response = PredictResponse(scores={"label1": 0.9, "label2": 0.1}, label="label1")

t0 = time.monotonic_ns()
X = {
'source': request.source,
'url': request.url,
'title': request.title,
'description': request.description
}
probs = global_data['cls'].predict_proba(X)
label = global_data['cls'].predict_label(X)
response = PredictResponse(scores=probs, label=label)
t1 = time.monotonic_ns()

log = {
'timestamp': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
'request': request.dict(),
'latency(ms)': (t1 - t0) / 1000000
}
global_data['file_log_handler'].write(json.dumps(log) + '\n')
global_data['file_log_handler'].flush()

return response


Expand Down
11 changes: 11 additions & 0 deletions week3/project/e2e.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/bin/bash -e

while IFS= read -r line; do

curl --location 'http://localhost/predict' \
--header 'accept: application/json' \
--header 'Content-Type: application/json' \
--data "$line"
echo ""

done < data/requests.json