/FastAPI-ML-project

Primary LanguageJupyter Notebook

FastAPI project

This project has been created to apply FastAPI to a ML project and it's part of a challenge called Project-of-the-week that is being held by Datatalks.club.

Content

Enviroment

I'll use a conda enviroment for this project

conda create -n fastapi python=3.9
conda activate fastapi

Install fastapi

pip install fastapi

Install other libraries that we'll use

pip install -r requirements.txt

I'll use a previous model for this project. It has made on a previous project-of-the-week.

churn-prediction-app

Tools

  • Python
  • Anaconda
  • Pandas
  • Scikit-Learn
  • FastAPI

Learning FASTAPI

Youtube Video

First app

from fastapi import FastAPI

app = FastAPI()


@app.get("/")
async def root():
    return {"message": "Hello World"}

Run the app

uvicorn main:app --reload

The command uvicorn main:app refers to:

  • main: the file main.py (the Python "module").
  • app: the object created inside of main.py with the line app = FastAPI().
  • --reload: make the server restart after code changes. Only use for development.

Access to documentation

You can access to your app documentation following link

Prediction app

from fastapi import FastAPI
import pickle 

model_file = './models/pipeline.bin'

with open(model_file, 'rb') as f_in:
    pipeline = pickle.load(f_in)


app = FastAPI()

@app.post('/predict')
async def predict(customer:dict):
    y_pred = pipeline.predict_proba(customer)[0,1]
    churn = y_pred>=0.5

    result = {
        'churn_probability': float(y_pred),
        'churn': bool(churn)
    }

    return result 

Run the app

uvicorn predict:app --reload

Test request in https://localhost:8000/docs using this customer:

{
  "CreditScore": 597,
  "Geography": "Germany",
  "Gender": "Female",
  "Age": 35,
  "Tenure": 8,
  "Balance": 131101.04,
  "NumOfProducts": 1,
  "HasCrCard": 1,
  "IsActiveMember": 1,
  "EstimatedSalary": 192852.67,
  "Exited": 0
}

Result

{
  "churn_probability": 0.4,
  "churn": false
}

result

Create a python script to test the API

import requests

url = 'http://localhost:8000/predict'

customer = {
  "CreditScore": 597,
  "Geography": "Germany",
  "Gender": "Female",
  "Age": 35,
  "Tenure": 8,
  "Balance": 131101.04,
  "NumOfProducts": 1,
  "HasCrCard": 1,
  "IsActiveMember": 1,
  "EstimatedSalary": 192852.67,
  "Exited": 0
}

response = requests.post(url, json=customer).json()

print(response)

Run the script

python test.py

Error Handling

Documentation

Handling 404 Error.

from fastapi import FastAPI, HTTPException

    if not result:
        raise HTTPException(
        status_code=404, detail=f"There is no result."
    )

where:

  • status_code: the HTTP status code, like 404 or 422.
  • You have to import HTTPException in order to use it.

Dockerfile

I've created the following Dockerfile in order to use it as a container:

FROM python:3.9.15

WORKDIR /code

COPY ./requirements.txt /code/requirements.txt

RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt

COPY ./predict.py /code/predict.py

COPY ./models/pipeline.bin /code/models/pipeline.bin

CMD ["uvicorn", "predict:app", "--reload", "--host", "0.0.0.0", "--port", "8000"]

Build the image

docker build -t fastapi .

Run the container

docker run -d -p 8000:8000 fastapi

Testing docker container

docker