|
from fastapi import FastAPI |
|
from pydantic import BaseModel |
|
import pickle |
|
import pandas as pd |
|
import numpy as np |
|
import uvicorn |
|
|
|
|
|
app = FastAPI(title="API") |
|
|
|
|
|
def load_model_and_scaler(): |
|
with open("model.pkl", "rb") as f1, open("scaler.pkl", "rb") as f2: |
|
return pickle.load(f1), pickle.load(f2) |
|
|
|
model, scaler = load_model_and_scaler() |
|
|
|
def predict(df, endpoint="simple"): |
|
|
|
scaled_df = scaler.transform(df) |
|
|
|
|
|
prediction = model.predict_proba(scaled_df) |
|
|
|
highest_proba = prediction.max(axis=1) |
|
|
|
|
|
predicted_labels = ["Patient does not have sepsis" if i == 0 else "Patient has sepsis" for i in highest_proba] |
|
print(f"Predicted labels: {predicted_labels}") |
|
print(highest_proba) |
|
|
|
response = [] |
|
for label, proba in zip(predicted_labels, highest_proba): |
|
|
|
output = { |
|
"prediction": label, |
|
"probability of prediction": str(round(proba * 100)) + '%' |
|
} |
|
response.append(output) |
|
|
|
return response |
|
|
|
|
|
class Patient(BaseModel): |
|
Blood_Work_R1: int |
|
Blood_Pressure: int |
|
Blood_Work_R3: int |
|
BMI: float |
|
Blood_Work_R4: float |
|
Patient_age: int |
|
|
|
class Patients(BaseModel): |
|
all_patients: list[Patient] |
|
|
|
@classmethod |
|
def return_list_of_dict(cls, patients: "Patients"): |
|
patient_list = [] |
|
for patient in patients.all_patients: |
|
patient_dict = patient.dict() |
|
patient_list.append(patient_dict) |
|
return patient_list |
|
|
|
|
|
|
|
@app.get("/") |
|
def root(): |
|
message = """ |
|
Welcome to the Sepsis Prediction API! |
|
|
|
This API provides endpoints for predicting sepsis based on patient data. |
|
|
|
Endpoints: |
|
|
|
[GET] / |
|
Description: Root endpoint providing information about the API. |
|
|
|
[POST] /predict |
|
Description: Endpoint to make a single patient sepsis prediction. |
|
Input: JSON payload containing patient data. |
|
Example Payload: |
|
{ |
|
"Blood_Work_R1": 123, |
|
"Blood_Pressure": 80, |
|
"Blood_Work_R3": 100, |
|
"BMI": 25.5, |
|
"Blood_Work_R4": 4.7, |
|
"Patient_age": 50 |
|
} |
|
|
|
[POST] /predict_multiple |
|
Description: Endpoint to make sepsis predictions for multiple patients. |
|
Input: JSON payload containing an array of patient objects. |
|
Example Payload: |
|
{ |
|
"all_patients": [ |
|
{ |
|
"Blood_Work_R1": 123, |
|
"Blood_Pressure": 80, |
|
"Blood_Work_R3": 100, |
|
"BMI": 25.5, |
|
"Blood_Work_R4": 4.7, |
|
"Patient_age": 50 |
|
}, |
|
{ |
|
"Blood_Work_R1": 140, |
|
"Blood_Pressure": 90, |
|
"Blood_Work_R3": 95, |
|
"BMI": 27.2, |
|
"Blood_Work_R4": 5.2, |
|
"Patient_age": 45 |
|
} |
|
] |
|
} |
|
""" |
|
return { |
|
"message": message.strip() |
|
} |
|
|
|
|
|
|
|
|
|
@app.post("/predict") |
|
def predict_sepsis(patient: Patient): |
|
|
|
data = pd.DataFrame(patient.dict(), index=[0]) |
|
parsed = predict(df=data) |
|
return {"output": parsed} |
|
|
|
|
|
@app.post("/predict_multiple") |
|
def predict_sepsis_for_multiple_patients(patients: Patients): |
|
"""Make prediction with the passed data""" |
|
data = pd.DataFrame(Patients.return_list_of_dict(patients)) |
|
parsed = predict(df=data, endpoint="multi") |
|
return {"output": parsed} |
|
|
|
if __name__ == "__main__": |
|
uvicorn.run("main:app", reload=True) |
|
|