Sepsis Prediction API with FastAPI

Newton Kimathi
5 min readOct 15, 2023

--

Building a machine learning model is just one part of the picture. To be of any use in the real world, it must be accessible to users and developers. The easiest and most widely used method for deploying machine learning models is to wrap them inside a REST API, in this case using FastAPI.

Sepsis is a critical medical condition that requires prompt diagnosis and intervention (Manning, 2021). The underlying model is trained to provide accurate predictions, aiding healthcare professionals in making timely and informed decisions. The Exploratory data analysis, Data Processing, Model building and dataset are available in my GitHub repository.

The aim of this project is to deploy a Sepsis Prediction API using FastAPI. The goal is to create an efficient, easy-to-use, and well-documented API that leverages machine learning models to predict the likelihood of sepsis based on input parameters.This API is hosted on Hugging Face for easy accessibility and integration. You can interact with the API by visiting here.

What is FastAPI

According to the official documentation, FastAPI is a modern and fast web framework for building APIs with Python 3.6+. Performance-wise, it’s up there with NodeJS and Go (“FastAPI,” 2022). It is also easy enough to learn and comes with automatic interactive documentation.

Setting Up the Environment:

We start by creating our python virtual environment to isolate the dependencies of the project. This will help to avoid conflicts with other projects and ensures that the project uses the required versions of libraries. Let’s create it and activate the virtual environment:

# To create the virtual environment
python -m venv venv
# To activate it
venv\Scripts\activate

Now Let upgrade our pip and install the necessary libraries in the requirements.txt file:

# To upgrade pip
python -m pip install -q --upgrade pip
# To install the dependencies in the requirements file
python -m pip install -qr requirements.txt

Next we import the necessary libraries and set up our FastAPI instance. The machine learning components, including a trained model, scaler, and label encoder, are loaded using a function (`Ml_loading_components`) from a saved file.

# Importations
from typing import Union
from fastapi import FastAPI
import pickle
import pandas as pd
import os
from fastapi import HTTPException, status
from sklearn.preprocessing import StandardScaler
from sklearn.preprocessing import LabelEncoder

# Setup Section
# Create FastAPI instance
app = FastAPI(title="Sepsis Prediction API", description="API for Predicting Sepsis")

# A function to load machine Learning components to re-use
def Ml_loading_components(fp):
with open(fp, "rb") as f:
object=pickle.load(f)
return(object)

# Loading the machine learning components
DIRPATH = os.path.dirname(os.path.realpath(__file__))
ml_core_fp = os.path.join(DIRPATH,"ML","ML_Model.pkl")
# Load machine learning components
ml_components_dict = Ml_loading_components(fp=ml_core_fp)
label_encoder = ml_components_dict['label_encoder']
scaler = ml_components_dict['scaler']
model = ml_components_dict['model']

Input Data :

We’ll be using the pydantic library for the data validation layer of our API, this library will help to prevent the user provide wrong parameters in the api call..

from pydantic import BaseModel
class InputData(BaseModel):
PRG: int
PL: int
BP: int
SK: int
TS: int
BMI: float
BD2: float
Age: int

Prediction Endpoint:

We define a FastAPI endpoint /predict that accepts HTTP POST requests. The predict function will be executed when a request is made to this endpoint. The function expects inputs from the user, using the defined inputs in the InputData class defined above.

# Create prediction endpoint
@app.post("/predict")
def predict(df: InputData):

Structure and Preprocess the Inputs:

We will receive the data from the users inputs, and transform it into a Pandas DataFrame. This DataFrame is structured similarly to the notebook’s format. We will then do the necessary preprocessing (Encoding, Scaling, Imputing missing values) Using the pretrained components we saved while building the model. In this case, we will only do scaling using the previously loaded scaler :

# Prepare the feature and structure them like in the notebook
df = pd.DataFrame([df.dict().values()],columns=df.dict().keys())
print(f"[Info] The inputed dataframe is : {df.to_markdown()}")

# Scaling the inputs
df_scaled = scaler.transform(df)

Make Prediction :

We will use the the machine learning model (model) loaded, to make predictions based on the scaled input data.

# Prediction
raw_prediction = model.predict(df_scaled)

Prediction Results :

Depending on the prediction result, appropriate HTTP responses are raised. If the prediction is 0 or 1, a corresponding success response is raised. Otherwise, a server error response is raised.

if raw_prediction == 0:
raise HTTPException(status_code=status.HTTP_200_OK, detail="The patient does not have Sepsis")
elif raw_prediction == 1:
raise HTTPException(status_code=status.HTTP_200_OK, detail="The patient has Sepsis")
else:
raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail="Prediction Error")

Run FastAPI using Uvicorn :

We will set a block that starts the FastAPI application using Uvicorn when the script is executed directly. It runs the app on host “127.0.0.1” (accessible externally) and port 8000. The reload=True flag enables automatic code reloading for development.

if __name__ == "__main__":
uvicorn.run("main:app", host="127.0.0.1", port=8000, reload=True)

Dockerizing the API:

To ensure a consistent and isolated environment, we containerize our FastAPI application using Docker. The Dockerfile specifies the base image, sets up the working directory, installs dependencies, and runs the FastAPI application. You can access the dockerfile here.

# Specifying the base image
FROM python:3.11
# Set the working directory to /Sepsis
WORKDIR /Sepsis

# Copy the current directory contents into the container at /Sepsis
COPY ./requirements.txt /Sepsis/requirements.txt

# Install requirements.txt
RUN pip install --no-cache-dir --upgrade -r /Sepsis/requirements.txt

# Set up a new user named "user" with user ID 1000
RUN useradd -m -u 1000 user
# Switch to the "user" user
USER user
# Set home to the user's home directory
ENV HOME=/home/user \
PATH=/home/user/.local/bin:$PATH

# Set the working directory to the user's home directory
WORKDIR $HOME/app

# Copy the current directory contents into the container at $HOME/app setting the owner to the user
COPY --chown=user . $HOME/app

# Start the FastAPI app on port 7860, the default port expected by Spaces
CMD ["uvicorn", "main:app", "--host", "127.0.0.1", "--port", "8000"]

This Dockerfile is designed to create a containerized environment for running a FastAPI app, ensuring dependencies are installed and the app runs as a non-root user.

4. Testing and Running the API Locally:

We will build a Docker image named “fastapi-app.” as below:

# To build a docker image
docker build -t fastapi-app .

We will then run the container locally to test the API.

# To run the container
docker run -it -p 8000:7860 fastapi-app

5. Endpoint Access and Results:
Once the Docker container is running, you can access the API at http://127.0.0.1:8000/docs and make predictions by sending POST requests to the `/predict` endpoint.

Thanks for reading.

References

FastAPI. (2022). FastAPI. https://fastapi.tiangolo.com/

Installing a python environment. (n.d.). Python for Scientists, 235–243. https://doi.org/10.1017/9781108120241.013

Manning, A. M. (2021). Diagnosis and treatment of sepsis. Critical Care, 66–67. https://doi.org/10.1201/9781315140629-36

Welcome to Pydantic. (n.d.). Welcome to Pydantic — Pydantic. https://docs.pydantic.dev/latest/

--

--

Newton Kimathi

Data Scientist || Data Analyst || Python, R, SQL, PowerBI , Machine Learning ||