Building Flask REST App with Flask-Restful
By: Shashwat Tiwari
Tags: Web App Development, Python, Flask Restful, Flask, Machine Learning

Hi,

Machine learning and AI is revolutionizing every industry like health care, banking, insurance, it's important how to deploy your Machine learning Model in Real-world in order to get the prediction. I remember when I got fascinated by machine learning and its broad area of applications. Lot of efforts I had to put in the development of efficient machine learning models.

I thought I have carried out a lot of feature engineering talked to domain experts to make sure their insights are captured. But, I got a problem when I want to deploy a model in real-world so the what next?.

I started exploring and came out with this awesome tutorial in which we are going to deploy machine learning model using a simple and clear framework called Flask.

ML Models seems not good on jupyter notebooks and .py scripts unless they are deployed in real-time. To change human mankind with the power of machine learning, the model needs to be deployed in a way it’s usable by the general public and not just by the domain experts. In order to carry this forward ML model are encapsulated in REST APIs that other applications could use to communicate with the model. Explore the whole post to check it out.

Lets’s Begin!

Methods to deploy Machine learning Models

Folks after a lot of exploration here are the two ways by which we can deploy machine learning models in the real world.

Restructure whole code in a programming language which is widely used by developers across the globe, which however becomes very difficult because rewriting code in a language like javascript requires a lot of efforts and time which is not efficient.

which is widely used by developers across the globe, which however becomes very difficult because rewriting code in a language like javascript requires a lot of efforts and time which is not efficient. Another method is the API approach where Web APIs have made it easy for cross-language applications to work well. If a front-end developer needs to use your Machine learning model to create an ML-powered web application, they would just need to get endpoint of API to get predictions.’

API’s Introduction

Basically API’s are the pact between 2 software saying if the user software provides input in a pre-defined format, the later with extending its functionality and provide the outcome to the user software.

Nowadays the web has become a hub for API’s. If you wander around the internet then for sure used APIs. Sharing things on social media, making payments over the web, displaying a list of tweets through a social handle all of these services use API at the back.

Majority of the Big Cloud providers and smaller Machine Learning focussed companies provide ready-to-use APIs. They cater to the needs of developers/businesses that don’t have expertise in ML, who want to implement ML in their processes or product suites.

Terminologies related to APIs

Access : is the user or who is allowed to ask for data or services?

: is the user or who is allowed to ask for data or services? Request : is the actual data or service being asked for

: is the actual data or service being asked for Methods : i.e. the questions you can ask, assuming you have access (it also defines the type of responses available).

: i.e. the questions you can ask, assuming you have access (it also defines the type of responses available). Parameters : additional details you can include in the question or response.

: additional details you can include in the question or response. Response: the data or service as a result of your request.

No More theory Lets dive in for Flask REST App.

Prerequisite and Env setup

Folks, I am keeping an understanding that you will be able to create Machine learning models, provide training to them and later use them to predict results in python. This post is aimed to only provide insights on deploying a machine learning model into production for small-scale use.

Following libraries, we need to kick off our flask app-

Flask A python-based easy to use web framework. Here are the docs.

A python-based easy to use web framework. Here are the docs. pickle : A native python library to save (serialize) and load (de-serialize) python objects as files on the disk.

: A native python library to save (serialize) and load (de-serialize) python objects as files on the disk. flask_cors : for CORS headers.

: for CORS headers. flask-restful : Flask-RESTful provides the building blocks for creating a great REST API.

Flask-RESTful provides the building blocks for creating a great REST API. Other learning libraries as per needs like numpy, pandas, sklearn etc.

Use pip tool to install the above packages.

Machine learning Model Flow

Talking about the ML Model workflow start with the deployment of the model and its creation. However, I have already created the Machine learning Model which is used to solve problems of a patient having a presence of heart disease. The dataset used is available here.

If you are interested in knowing about this model you may refer to my github repository. I not much concerned about the accuracy of model moreover I focused on the deployment of Flask APIs.

Saving Machine Learning Models Serialization & Deserialization

In terms of computer science, nerds Serialization is the process of translating data structures or object state into a format that can be stored (for example, in a file or memory buffer, or transmitted across a network connection link) and reconstructed later in the same or another computer environment.

Mainly Machine learning models are serialized and then again deserialized in order to carry out prediction from Machine learning model. A module called pickle helps perform serialization and deserialization in python. We even pickled standard scaler object that can be used for transforming features into the mean and scaling to unit variance. Persistence saves you time and headache, even if the initial implementation seems to be ridiculous.

Stitch in time saves nine!

Python code for serialization:

Python code for deserialization:

REST API Build using Flask

Folder Structure

Before Building any Flask App it is important to follow a proper folder structure. So your REST app will be able to fetch required resources quickly. Below is the folder structure which I follow

Here we have .html files and their respective CSS and javascript which will be copied to folder htdocs/ under xaamp directory. Also, we have persisted model and scaled pickle file. One thing I want to make it clear that here we are using xaamp(Apache webserver ) for hitting our REST API and get the prediction from app.py.

Flask REST App Development

Following terminologies should be kept in mind while building REST App. It plays major role in constructing our wrapper function, Predictheart(Resource):

Getting the request data (for which predictions are to be made)

data (for which predictions are to be made) Loading our model persistence file

jsonify our predictions using javascript and send the response back with status code: 200

from flask import Flask, request, render_template

import pickle

import numpy as np

from flask_restful import Api,Resource

from flask_cors import CORS

import seaborn as se

import pandas as pd app = Flask(__name__) CORS(app) API_NAME = Api(app) app.config['SECRET_KEY'] = 'disable the web security' app.config['CORS_HEADERS'] = 'Content-Type' class Predictheart(Resource): def get(self, vizdata): info = vizdata.split(",") age = int(info[0]) sex = int(info[1]) chest_pain_type = float(info[2]) resting_blood_pressure = float(info[3]) cholesterol = float(info[4]) fasting_blood_sugar = float(info[5]) rest_ecg = float(info[6]) max_heart_rate_achieved = float(info[7]) exercise_induced_angina = float(info[8]) st_depression = float(info[9]) st_slope = float(info[10]) num_major_vessels = float(info[11]) thalassemia = float(info[12]) model = load_model() data = ([[age, sex, chest_pain_type, resting_blood_pressure,cholesterol,fasting_blood_sugar,rest_ecg,max_heart_rate_achieved,exercise_induced_angina,st_depression,st_slope, num_major_vessels,thalassemia]]) col = ['age', 'sex', 'chest_pain_type', 'resting_blood_pressure','cholesterol','fasting_blood_sugar','rest_ecg','max_heart_rate_achieved','exercise_induced_angina','st_depression','st_slope', 'num_major_vessels','thalassemia'] data = pd.DataFrame(data,columns = col) data = data_scaling(data) data = model.predict(data) if data == 0: result = "No" else: result = "Yes" # return render_template('result.html', glycohemoglobin=abs(round(w_glyco)*10), glucose_serum=abs(round(w_gluco)*10), albumin_urine=abs(round(w_albumin)*10), pred=result) return {'isHeart': result} API_NAME.add_resource(Predictheart, '/heartpredict/viz/<vizdata>', methods=['POST', 'GET']) def load_model(): """This function load the pickled model as API for flask :returns: loaded_model :rtype: float64 method's invoked: None""" loaded_model = pickle.load(open('rf_model.pkl', 'rb')) return loaded_model

def data_scaling(df): cont_data = df.values m = open('scaled_model.pkl', 'rb') model = pickle.load(m) cont_data = model.transform(cont_data) return cont_data if __name__ == '__main__': app.run(host='localhost', port=5000, debug=True, threaded=True)

Above code, snippet seems to be complex let me break it down for you.

There are two helper function namely load_model() and data_scaling().These functions are used load the persisted pickle file for standard scaling and predicting our raw inputs which hit the REST Apis.

As you have observed in the import section we have fetched Resources and Api module from flask_restful library. Api is basically used to create an object to access methods available in flask restful. Resources are built on top of Flask pluggable views, giving you easy access to multiple HTTP methods just by defining methods on your resource.

Moving further we have created a python class Predictheart(Resources) that encapsulate method get(self,vizdata). The arguments passed in this method basically hold the data which we are getting from our REST APIs.Flask-RESTful understands multiple kinds of return values from view methods. Similar to Flask, you can return any iterable and it will be converted into a response, including raw Flask response objects.

The add_resouce() method on the Api object. Each one will be routed to your Resource. Your Endpoints will be created with /heartprediction/viz/<vizdata>. If a request does not match any of your application’s endpoints, Flask-RESTful will return a 404 error message.

In add_resource() method we are handling both GET & POST request.However, we ran this application using our localhost serving on port 5000 so final Endpoints will look something like this.

127.0.0.1 “GET /heartpredict/viz/21,1,1,124,12,126,0,60,0,13,1,33,1 HTTP/1.1”

The values got after putting GET request will be pushed to data_scaling() function followed by load_model() function which throws the prediction that will be jsonify to insert into the HTML page.

Handling CORS request and sending a response.

The Cross-origin request is handled by flask CORS python package, which by default enables CORS support on all routes, for all origins and methods. It allows parameterization of all CORS headers on a per-resource level.

<script> function validateForm() { var alu = document.forms["predictions"]["aul"].value; var ucl = document.forms["predictions"]["ucl"].value; var acl = document.forms["predictions"]["acl"].value; var cl = document.forms["predictions"]["cl"].value; var grsl = document.forms["predictions"]["grsl"].value; var irsl = document.forms["predictions"]["irsl"].value; var ld = document.forms["predictions"]["ld"].value; var ol = document.forms["predictions"]["ol"].value; var rc = document.forms["predictions"]["rc"].value; var plc = document.forms["predictions"]["plc"].value; var glyl = document.forms["predictions"]["glyl"].value; var uc = document.forms["predictions"]["uc"].value; var uf = document.forms["predictions"]["uf"].value; var col_val = [alu,ucl,acl,cl,grsl,irsl,ld,ol,rc,plc,glyl,uc,uf]; alert(col_val); console.log(col_val); var data1; function createCORSRequest(method, url) { var xhr = new XMLHttpRequest(); if ("withCredentials" in xhr) { xhr.open(method,url,true); } else if (typeof XDomainRequest != "undefined") { xhr = new XDomainRequest(); xhr.open(method, url); } else { xhr =null; } return xhr; } function makeCorsRequest() { var url = 'http://localhost:5000/heartpredict/viz/'+col_val; var xhr = createCORSRequest('GET', url); if(!xhr) { return; } xhr.onload = function() { data1 = JSON.parse(xhr.responseText); alert(data1); load(data1); }; xhr.onerror = function() { }; xhr.send(); } makeCorsRequest(); function load(data1) { var tr = data1; var html = "<h3> "+tr['isHeart']+"</h3>"; $("#result_t2d").html(""); $('#result_t2d').append(html); console.log(tr['isHeart']); console.log(tr); } } $("#contact-form").submit(function(e) { e.preventDefault(); }); </script>

Above javascript, function validateform() is intended to get input values from .html page and pass it to the javascript function makeCorsRequest().

In between validateform () and makeCorsRequest() function we have createCORSRequest() which creates the cross-origin request with the help GET method and rest apis endpoints.

In End, we use JSON parsing to parse the response from flask python app and throw it to the frontend application UI.

Flask REST Application Example

I have created a simple single page template that can be used to receive the input features through an HTML form and make a request to the API to fetch results. Even if you aren’t proficient with HTML-CSS-JavaScript you can easily edit this template.

The template, as well as the Flask REST application along with jupyter notebook for development of Machine learning model for predicting Heart Diseases, is available on Github repository.

In the End

This Blog drives you to create simple flask rest API that will help with prototyping a data product, to make it as fully functional, production-ready API a few more additions are required that aren’t in the scope of this blog. Following points, I ponder while creating an API-

Analyze your Machine learning workflow to create clean, usable API. It will save a lot of efforts and time.

Make use of pipelines and custom estimators for preprocessing or any other related task. Also, be sure that estimator, as well as train code, should be kept along with the persisted model.

The main disadvantage of using flask is that it does not provide version control. Persisting and tracking of machine learning model seem to be complex in flask. Here is the article that helps.

References

If you like this post, please follow me as well as Press that Clap button as long as you think I deserve it. If you have noticed any mistakes in the way of thinking, formulas, animations or code, please let me know.

Cheers!