Build REST API for Machine Learning model using Python FLASK
This post talks on how to host your trained machine learning model as a REST API so that we can use the model for prediction. This post considers python Flask for building REST endpoint and docker for containerizing.
You need knowledge of the following:
- Machine Learning
- REST API
Table of contents
- Why we need REST API for ML model?
- Create a Machine Learning model using SKLearn
- Package the model in to pickle file
- Create FLASK API
- Create a docker image
- Run the container locally
- Use REST end-point for prediction
1. Why we need REST API for ML model?
Once we train our machine learning model, we want the model to start predicting the outcomes using real time data. These predictions can be batch predictions or online. For example, if you have a front end application which needs to display predictions, exposing the model as a REST end-point is the way to go.
2. Create a Machine Learning model using SKLearn
We are going to use a model that predicts the concrete strength. It’s a supervised regression model which takes Cement, Blast Furnace Slag, Fly Ash, Water, Superplasticizer, Coarse Aggregate, Fine Aggregate and Age features along with the target variable Concrete compressive strength and predicts the concrete strength of new data that it hasn’t seen.
The original dataset is available in .csv format at Concrete Data set .
Since the intention of this post is to build a REST end-point for the trained model, we are going to skip the steps of model building and training.
The model is built using python and Scikit-Learn machine learning library. You can access the model jupiter notebook file here: model.ipynb
3. Package the Trained Model in to Pickle file
Once we create our trained model, serialize the model in to pickle file. The following code creates a .pkl file by serializing our trained model instance.
import picklewith open('concrete_strength_trained_model.pkl', 'wb') as m:
Here, gb_rs_cv.best_estimator is the final trained hyper tuned model instance, which gets serialized in to concrete_strength_trained_model.pkl pickle file.
4. Create Flask API
Flask is an API of Python that allows us to build web-applications.
To install Flask using pip, run the below command.
pip install Flask
For other types of installations, please refer Flask Installation
Once the installation is done, create a file called server.py and paste the below code:
server.py is the file that we run to execute the flask project.
predictor_api is from another python file (we will see in short) that we imported which has the code for REST resource.
app.register_blueprint(predictor_api, url_prefix=’/model’) is registering the REST end points to the FLASK app and prefixing /model in the REST url for all the endpoints inside predictor_api.
The following code gets executed first when we run the server.py
if __name__ == '__main__': load_model() # load the model on flask start app.config['model'] = model app.run(host='0.0.0.0', port=80)
load_model() function reads the .pkl file (make sure you have the concrete_strength_trained_model.pkl file in the same directory) that we created earlier, loads the model instance and assign it to the variable ‘model’
app.config['model'] = model
we are assigning the model instance to the app config so that it can be used across different python files in the project, in our case predictor.py
The above line starts the server on localhost and on the port 80.
Create a new file with name predictor.py in the same folder where we created server.py earlier and paste the following code:
The predict() function outside of Predictor class is our REST endpoint with url “/predict” and can be invoked as HTTP PUT method. This function reads the JSON request payload and calls the predict function of the Predictor class by passing model instance (The instance is retrieved from app.config, current_app.config[‘model’] does that) and the request payload
predict(self, model, payload) method of Predictor class, converts the payload in to pandas data frame and executes the model.predict method against the data frame. Finally, it returns the predicted concrete strength with 200 http status.
5. Create a docker image
A Docker container is an open source software development platform. Its main benefit is to package applications in containers, allowing them to be portable to any system running a Linux or Windows operating system (OS).
This post is not going to go in details about the docker container as that is a whole new topic. It also assumes that you have docker agent installed in your machine
Create “requirements.txt” in the folder where we created server.py, predictor.py files and paste the following entries.
In requirements.txt file, we list all our dependent libraries so we can install these dependencies and have it readily available inside our docker image.
Now create a file with name “Dockerfile” under the same folder. Paste the below code
FROM python:3.6-slim — pulls the base python docker image
All COPY commands will copy the corresponding files in to the folder “deploy”
WORKDIR /deploy/ — makes “deploy” folder as the working directory
RUN pip install -r requirements.txt — installs each library specified in requirements.txt file
EXPOSE 80 — expose the port as 80
ENTRYPOINT [“python”, “server.py”] — runs “server.py” file
It’s time to build our docker image and run it. Before building it, make sure the docker agent is running in your machine
To build the docker image, run the following command
docker build -t <<docker_image_name>> .
The dot “.” at the end is important as it specifies that the Dockerfile exists in the current directory
Once you run the above command, run docker images to see the list of docker images in your machine and you should see an entry with the name that you provided in the above command
Once we have the docker image we can deploy in any container orchestrator services like kubernetes or AWS ECS for production use. In this post we will run the container in our local machine.
6. Run the container locally
To run the docker container, execute the below command
docker run -p 80:80 <<docker_image_name>>
7. Use REST end-point for prediction
Finally, invoke the model as REST for predicting the concrete strength. To do that, we can use any REST client, I have used post-man. The end point url for our model is going to be http://localhost:80/model/predict
For the given test data, our model predicted that the concrete strength is 30.261782 mpa (Mega pascals)
The full flask project is available at Flask API Github