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'susingPython. - Basics of
Machine Learning. - Deploy Python
REST API'stoAzure. - Setup
CI/CDusingGithub Actions. - Use
PostManto 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.
flaskis used to createREST API's, which means our API can be consumed by web app , mobile app , desktop app, IOT etc. AsREST API'sreturnJsondata, so it becomes easy to Deserialize to objects of any programming language.flask-corsis used to allow request from another domian, this will be usefull if your front end is deployed in different domain.scikit-learnis 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)