Lets Build A Fitness Machine Learning
App and Deploy to Azure
.
Today I am going to share how to deploy simple Machine Learning
Model in Azure
and will also share the challenges i faced while deploying this python flask
app in Azure
.
What you will learn ?
You can upskill in below skills:
- Create Basic
REST API's
usingPython
. - Basics of
Machine Learning
. - Deploy Python
REST API's
toAzure
. - Setup
CI/CD
usingGithub Actions
. - Use
PostMan
to test Your MLAPI
.
Lets get started....
Prerequisite
Install Required Python Packages
Open your command prompt
and execute below commands:
1. py -m pip install flask
2. py -m pip install -U flask-cors
3. py -m pip install -U scikit-learn
Here we are using 3 packages
.
flask
is used to createREST API's
, which means our API can be consumed by web app , mobile app , desktop app, IOT etc. AsREST API's
returnJson
data, so it becomes easy to Deserialize to objects of any programming language.flask-cors
is used to allow request from another domian, this will be usefull if your front end is deployed in different domain.scikit-learn
is used for Machine Learning.
Machine Learning Fitness DataSet:
For training our ML model
we are using Dataset
from here.
Basically we are going to find ideal weight to be fit based on your height and current weight. We have trained our model to predict from 5 feet to 6 feet of male dataset, you can train for other height ranges if required.
Code Walkthrough:
Open VS code
inside your project folder, Create app.py
file in VS Code
and paste below code as required.
First we are importing all required modules required in our flask
code.
from flask import Flask, jsonify, abort, request
from werkzeug.exceptions import HTTPException
from flask_cors import CORS
from sklearn import tree
Second we are creating objects, constructors and configuration necessary for app
to run.
app = Flask(__name__)
CORS(app)
app.config["DEBUG"] = True
Finally we are implementing REST API
functions, which will be called when a URL
is requested by client.
Below is the function , which helps us to handle errors globally in our REST API
.
@app.errorhandler(Exception)
def handle_error(e):
code = 500
if isinstance(e, HTTPException):
code = e.code
return jsonify(error=str(e)), code
Next we have our simple function named as get-message
to return Hello World!
Json
data, when a client initiates GET
requests to /api/get-message
endpoint.
@app.route('/api/get-message', methods=['GET'])
def getMessage():
data = {'message': 'Hello World!'}
return jsonify(data)
Then we have our Machine Learning
endpoint which predicts fitness and returns Json
data, indicating you are fit or not. :) The code is explained using comments.
@app.route('/api/predict-fitness', methods = ['POST'])
def predict_fitness():
if not request.json or not 'userHeight' in request.json:
abort(400)
# Data Cleaning, remvoing dot from userHeight value
userHeight = request.json.get('userHeight', "")
userHeight = int(str(userHeight).replace('.', ''))
userWeight = int(request.json.get('userWeight', ""))
if userHeight == 51: # Just a fix because python is removing trailing zeros while coverting to str or int
userHeight = 510
# Set up training data
# Expected User Inputs to classifier
# Example, For a person with 5 feet height, the expected weight is 43 to 53 kg
# So for this we mention in features like : features = [[5, 43], [5, 99],....]]
# which means for 5 feet height, user can enter values from 43 to 99
# but the expected weight will be 4353 as mentioned in labels like: labels = [4353, 4353,.....]
features = [[5, 43], [5, 99], [51, 45], [51, 99], [52, 48], [52, 99], [53, 50], [53, 99],
[5.4, 53], [54, 99], [55, 55], [55, 99], [56, 58], [56, 99], [57, 60], [57, 99],
[58, 63], [58, 99], [59, 65], [59, 99], [510, 67], [510, 99], [511, 70], [511, 99],
[6, 72], [6, 99], [6, 72], [6, 99]]
# Expected output values based on user inputs or expected weight ranges based on person height
labels = [4353, 4353, 4555, 4555, 4859, 4859, 5061, 5061, 5365, 5365 ,5558 ,5558, 5870,
5870, 6074,6074 , 6376, 6376 ,6580 , 6580 ,6783 , 6783, 7085, 7085, 7289, 7289, 7289, 7289]
# Train classifier
classifier = tree.DecisionTreeClassifier() # Decision tree classifier is used
classifier = classifier.fit(features, labels) # Find common patterns in training data
# Make predictions using the trained model
expectedWeight = classifier.predict([[userHeight,userWeight]])
# Get first two numbers from expected Weight
expectedWeight = int(expectedWeight)
fromEpectedWeight = int(str(expectedWeight)[:2])
# Get last two numbers from expected Weight
toExpectedWeight = int(str(expectedWeight)[2:4])
# Check if weight is in between the range of expected weight
is_Weight_In_between = userWeight >= fromEpectedWeight and userWeight <= toExpectedWeight
if is_Weight_In_between:
message = f'Congratulations!, Your expected weight is in between {fromEpectedWeight} kg and {toExpectedWeight} kg.'
else:
message = f'Your expected weight should be in between {fromEpectedWeight} kg and {toExpectedWeight} kg.'
fitData = {
'isFit': is_Weight_In_between,
'message': message
}
return jsonify( { 'fitInfo': fitData } ), 201
Finally we have below line to run the app.
app.run(debug=True)
Deploying Python Flask REST API to Azure:
Next we are going to use a service in Azure known as Azure App Service
to host our Python Flask
App.
Login to Azure portal. Search for Azure App Service
In the Search box and select it.
Next Click Create, and fill details in Basic tab, Enter Resource Group name or create new and give a name, enter your app name.
In Run Time Stack select Python 3.7 , Then Click Review and Create.
Just review your details and click finally Create.
Then it will show you that your Deployment is Progress, it may take few minutes.
Once your Deployment is done, click Go to resource which will take you to App Management blade.
Next go to your Github Account and create a Repository and upload the code using Github
website or using git
commands or even simple, just Fork
my code repository from here
Note: As we are deploying to Azure
so along with app.py
file in our repo we need requirements.txt
file which contains all required packages to be installed in Azure App Service
for hosting as shown below:
Flask==1.1.2
Flask-Cors==3.0.10
scikit-learn==0.24.1
Setup CI/CD with Deployment Center and Github Actions:
Once you have your Repository and the code, then next we have to connect your Repository to Azure Deployment
Center which provides CI/CD
outofbox with providers like Github Actions
, Bitbucket
etc.
Select Github
as source control and authorize using your Github
credentials, then select you Repository as below:
In Run Time Stack select Python 3.7
Once you click Save, the deployment starts and a workflow file is created in your Github
repo to start CI/CD
, as you can see below in my Github
repo, in GithHub
Actions tab, the build is completed and the final deploy is in progress. Here the deploy Job
is pushing your code changes automatically toAzure Web App
as you make any changes to your code and push to your Github
repo. Its that easy :)
Check your deployed REST API:
App Service Application URL: https://<Your app name>.azurewebsites.net/api/get-message
If you are getting Hello World!
as response then your API
is successfully deployed. :)
Test ML REST API using Post Man:
Open Postman
desktop app and create a new request, give a name. next we select the Http Verb
as POST
and paste in our API URL.
In the Body
we select Raw
and Json
and POST
Json
data to API
. Paste Below Payload in Body:
{
"userHeight":"6",
"userWeight":"80"
}
Next click Send
. Finally the API
predicts the result and gives back the Json
results as below:
{
"fitInfo": {
"isFit": true,
"message": "Congratulations!, Your expected weight is in between 72 kg and 89 kg."
}
}
Wow we are done! 😄. Congratulations!
My Initial struggle with Azure App Service Deployment:
I have deployed many .NET
apps to Azure
but this was first time I am deploying a Python
App to Azure
.
After following online tutorials to deploy Python
Apps, the Azure
Web App was down with 502
errors. After many hours of struggle Finally got a advice in Microsoft
doc to check Debug console
using Kudu Console or the SCM Dashboard
for your app. The Link looks like below:
https://<Your app name>.scm.azurewebsites.net/.
From the Log Stream I came to know that Azure is using docker and containers
behind the scene and the container
is failing to start.
Finding and Killing The Root Issue:
By Digging deeper, I came to know that some process is still running in port 8000
so the port is in use and thus container
is not able to start.
So as advised in this SO
post, lets kill the process running in port 8000
, using the below Bash
command.
alias kill8000="fuser -k -n tcp 8000"
Finally deployed Python REST API
to Azure
. 😄
Github Link to Code:
shaijut / Python-ML-Fitness-API
A Fitness Machine Learning API build using Python Flask and deployed to Azure using GitHub Actions CI/CD
Python-ML Fitness API
-
A Fitness Machine Learning API build using Python Flask and deployed to Azure using GitHub Actions CI/CD
-
Check below Dev.to Post:
https://dev.to/shaijut/build-a-fitness-machine-learning-app-and-deploy-to-azure-24g4
PS: You can even test this API in VS Code
and PostMan
in your local machine without deploying to Azure
.
If you have any doubts let me know in comments. Hope you enjoyed. 😄.
Have a great day.
References:
https://dev.to/rtficial/building-your-first-restful-api-with-python-flask-1lmc
https://blog.miguelgrinberg.com/post/designing-a-restful-api-with-python-and-flask
https://programminghistorian.org/en/lessons/creating-apis-with-python-and-flask
https://stackoverflow.com/questions/25594893/how-to-enable-cors-in-flask
https://stackoverflow.com/questions/29332056/global-error-handler-for-any-exception
https://scikit-learn.org/stable/install.html
https://docs.microsoft.com/en-in/azure/app-service/troubleshoot-http-502-http-503
https://stackoverflow.com/questions/16756624/gunicorn-connection-in-use-0-0-0-0-5000
https://stackoverflow.com/questions/9168392/shell-script-to-kill-the-process-listening-on-port-3000
Top comments (0)