Deploy a Machine learning Application By hatem ben tayeb
Devops Engineer @ Astrolab-agency Sousse
linkedin.com/in/hatembentayeb/
facebook.com/htayeb2
Opensource Guy, Automation Enthusiast, Archlinux SuperFan
Dev
Ops
DevOps is the practice of operations and development engineers participating together in the entire service lifecycle, from design through the development process to production support. "The agile admin"
(Basics)
Is a set of processes and practices that will save you time, increase your flexibility, and improve your system uptime
Ansible Playbooks
Is the management of infrastructure (networks, virtual machines, load balancers, and connection topology) in a descriptive model.
Requires us to describe and observe systems with declarative specifications that eventually form the basis of continuous everything
Getting a global visibility of your server including :
Tools: Prometheus,docker,cAdvisor,Grafana
(ML python application)
The app is based on flask that exposes those APIs:
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.cluster import KMeans
from sklearn.metrics import adjusted_rand_score
import json
import os
# Importing the libraries
import numpy as np
import pandas as pd
from flask import Flask,jsonify,request,render_template
app = Flask(__name__)
@app.route('/')
def main_page():
return render_template('index.html')
@app.route('/kmeans', methods=['POST'])
def kmeans_pred():
posted_data = request.get_json()
true_k = posted_data['num_cluster']
documents = posted_data['data']
feeds = dict()
vectorizer = TfidfVectorizer(stop_words='english')
X = vectorizer.fit_transform(documents.split('.'))
model = KMeans(n_clusters=true_k, init='k-means++', max_iter=100, n_init=1)
model.fit(X)
order_centroids = model.cluster_centers_.argsort()[:, ::-1]
terms = vectorizer.get_feature_names()
print(terms)
for i in range(true_k):
feeds.update({"cluster_"+str(i)+"": [terms[ind] for ind in order_centroids[i, :10]]})
return jsonify(feeds)
@app.route("/ads", methods=['POST'])
def purshase():
posted_data = request.get_json()
age = int(posted_data['age'])
salary = int(posted_data['salary'])
new_data = [[age,salary]]
# Importing the dataset
dataset = pd.read_csv('Social_Network_Ads.csv')
X = dataset.iloc[:, [2, 3]].values
y = dataset.iloc[:, 4].values
# Splitting the dataset into the Training set and Test set
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.25, random_state = 0)
# Feature Scaling
from sklearn.preprocessing import StandardScaler
sc = StandardScaler()
X_train = sc.fit_transform(X_train)
X_test = sc.transform(X_test)
new_data_pred = sc.transform(new_data)
# Fitting SVM to the Training set
from sklearn.svm import SVC
classifier = SVC(kernel = 'linear', random_state = 0)
classifier.fit(X_train, y_train)
# Predicting the Test set results
y_pred = classifier.predict(new_data_pred)
response = {
"result" : str(y_pred)
}
return jsonify(response)
if __name__ == '__main__':
app.run(host="0.0.0.0", port=os.environ.get('PORT'))
Main.py
The landing page of the application
It will be used to test the CI workflow
<!DOCTYPE html>
<html>
<title>EPI DSC</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Raleway">
<style>
body,h1 {font-family: "Raleway", sans-serif}
body, html {height: 100%}
.bgimg {
background-image: url('/static/img.jpg');
min-height: 100%;
background-position: center;
background-size: cover;
}
</style>
<body>
<div class="bgimg w3-display-container w3-animate-opacity w3-text-white">
<div class="w3-display-topleft w3-padding-large w3-xlarge">
#YUP
</div>
<div class="w3-display-middle">
<h1 class="w3-jumbo w3-animate-top">Hello EPI :D</h1>
<hr class="w3-border-grey" style="margin:auto;width:40%">
<p class="w3-large w3-center"> DSC EPI Cloud Engineering Track 2020</p>
</div>
</div>
</body>
</html>
Index.html
It's time to ship the app into an isolated container to be shippable on any Server !
FROM frolvlad/alpine-python-machinelearning
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
EXPOSE 3000
ENV ENVIRONMENT dev
COPY . /app
CMD python main.py
Dockerfile
https://gitlab.com/hatemBT/REST-API-KMEANS
# Clone the project
git clone https://gitlab.com/hatemBT/REST-API-KMEANS
# Run it locally
pip install -r requirements.txt
# Run the code
python main.py
#To build the docker image (change the port=os.environ.get('PORT') => port=5000 (you can choose yor custom port))
docker build -t kmeans_app .
#Run with docker
docker run -p 5000:5000 kmeans_app
(Heroku)
Heroku is a platform as a service (PaaS) that enables developers to build, run, and operate applications entirely in the cloud.
We need just 2 things :
We need the .netrc file to hold our credentials (login,password) for the :
machine api.heroku.com
login <mail>
password <apiKey>
machine git.heroku.com
login <mail>
password <apiKey>
(Gitlab)
We need to put the apiKey and the registry url in gitlab as secrets.
go to : settings->CI/CD->variables
RegistryUrl format: registry.heroku.com/{app_name}/{container_name}
It matches: registry.heroku.com/hello-devops-eniso/web
The pipeline has a single stage "development" that will deploy the container to the "hello-devops-eniso" app
image : docker:latest
services:
- docker:dind
variables:
DOCKER_DRIVER: overlay
stages:
- devloppement
devloppement:
stage : devloppement
script:
- echo -e " Start Building Docker image from Docker file .. "
- docker build -t $HEROKU_APP .
- echo -e "\n build complete\n\n Start pushing image to registry.heroku.com ..."
- docker login --username=_ -p $HEROKU_TOKEN registry.heroku.com
- docker push $HEROKU_APP
- echo -e " push complete ."
- echo -e " Start pushing the app to the developpement server .. "
- docker run --rm -e HEROKU_API_KEY=$HEROKU_TOKEN wingrunr21/alpine-heroku-cli container:release web --app hello-devops-eniso
- echo -e " complete"
Steps:
(Curl)
Test the /kmeans route
Test the /ads route
curl -X POST -H "Content-Type: application/json" "http://hello-devops-eniso.herokuapp.com/kmeans" -d @data.json | jq "."
curl -X POST -H "Content-Type: application/json" "http://hello-devops-eniso.herokuapp.com/ads" -d "{\"age\":36,\"salary\":140000}" | jq "."
Check my