Dans l'article précédent, j'ai utilisé le jeu de données Kaggle's House Sales dans le comté de King, aux États-Unis, pour générer un modèle de formation avec l'apprentissage automatique XGboost et transformer ce modèle de formation en serveur API avec Flask. Cette fois, je vais vous expliquer la procédure de communication HTML vers JSON Ajax en utilisant ce serveur API. Veuillez consulter l'article suivant pour connaître la procédure permettant de transformer le modèle appris par machine learning en un serveur API.
Ici, pour pouvoir communiquer depuis HTML avec javascript Ajax, il est nécessaire d'ajouter le fichier de démarrage du serveur API écrit en Flask comme suit. J'ajouterai une bibliothèque appelée flask_cors et le code associé. flask_cors doit être préinstallé.
housesails_app.py
import json
from flask import Flask
from flask import request
from flask import abort
from flask_httpauth import HTTPBasicAuth
from flask_cors import CORS #ajouter
import pandas as pd
from sklearn.externals import joblib
import xgboost as xgb
model = joblib.load("house_sales_model.pkl")
app = Flask(__name__)
#ajouter à
@app.after_request
def after_request(response):
response.headers.add('Access-Control-Allow-Origin', '*')
response.headers.add('Access-Control-Allow-Headers', 'Content-Type,Authorization')
response.headers.add('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS')
return response
#↑ Ajouter ici
# BasicAuth
auth = HTTPBasicAuth()
users = {
"username1": "password1",
"username2": "password2"
}
@auth.get_password
def get_pw(username):
if username in users:
return users.get(username)
return None
# Get headers for payload
headers = ['sqft_living','sqft_above','sqft_basement','lat','long','sqft_living15','grade_3','grade_4','grade_5','grade_6','grade_7','grade_8','grade_9','grade_10','grade_11','grade_12']
@app.route('/house_sails', methods=['POST'])
# BasicAuth
@auth.login_required
def housesails():
if not request.json:
abort(400)
payload = request.json['data']
values = [float(i) for i in payload.split(',')]
data1 = pd.DataFrame([values], columns=headers, dtype=float)
predict = model.predict(xgb.DMatrix(data1))
return json.dumps(str(predict[0]))
if __name__ == "__main__":
app.run(debug=True, port=5000)
Dans le fichier HTML, la partie interface est la balise d'entrée à l'intérieur de la balise et crée un formulaire d'entrée de données. Les données d'entrée sont reçues par javascript, formatées, converties au format JSON et POSTées par la communication Ajax. Lorsque la communication aboutit, la valeur prédite du serveur API est reçue et affichée dans la zone de la balise textarea.
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Envoyer des données JSON par POST à partir d'un fichier HTML</title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2" crossorigin="anonymous">
</head>
<body>
<div class="container">
<h1>Envoyer des données JSON par POST à partir d'un fichier HTML</h1>
<div class="alert alert-primary" role="alert">
<p>URL: <input type="text" id="url_post" name="url" class="form-control" size="100" value="http://localhost:5000/house_sails"></p>
</div>
<div class="d-flex bd-highlight">
<div class="flex-fill bd-highlight alert alert-primary mr-3" role="alert">
<p>sqft_living: <input type="number" id="value1" class="form-control" size="30" value=-1.026685></p>
</div>
<div class="flex-fill bd-highlight alert alert-primary mr-3" role="alert">
<p>sqft_above: <input type="number" id="value2" class="form-control" size="30" value=-0.725963></p>
</div>
<div class="flex-fill bd-highlight alert alert-primary" role="alert">
<p>sqft_basement: <input type="number" id="value3" class="form-control" size="30" value=-0.652987></p>
</div>
</div>
<div class="d-flex bd-highlight">
<div class="flex-fill bd-highlight alert alert-primary mr-3" role="alert">
<p>lat: <input type="number" id="value4" class="form-control" size="30" value=-0.323607></p>
</div>
<div class="flex-fill bd-highlight alert alert-primary mr-3" role="alert">
<p>long: <input type="number" id="value5" class="form-control" size="30" value=-0.307144></p>
</div>
<div class="flex-fill bd-highlight alert alert-primary" role="alert">
<p>sqft_living15: <input type="number" id="value6" class="form-control" size="30" value=-0.946801></p>
</div>
</div>
<div class="alert alert-primary" role="alert">
<p>Sélectionnez le grade:
<select name="grade" id="grade" class="form-control form-control-lg">
<option value="grade1">grade1</option>
<option value="grade2">grade2</option>
<option value="grade3">grade3</option>
<option value="grade4">grade4</option>
<option value="grade5">grade5</option>
<option value="grade6">grade6</option>
<option value="grade7">grade7</option>
<option value="grade8">grade8</option>
<option value="grade9">grade9</option>
<option value="grade10">grade10</option>
<option value="grade11">grade11</option>
<option value="grade12">grade12</option>
</select>
</p>
</div>
<p>usename: <input type="text" name="username" id="username" class="form-control" value="bitstudio"/></p>
<p>password: <input type="password" name="password" id="password" class="form-control" value="hirayama"/></p>
<p><button id="button" type="button" class="btn btn-primary">submit</button></p>
<textarea id="response" class="form-control" cols=120 rows=4 disabled></textarea>
<p><p>
</div>
</body>
<script type="text/javascript">
$(function(){
$("#response").html("Response Values");
$("#button").click( function(){
let value07 = 0;
let value08 = 0;
let value09 = 0;
let value10 = 0;
let value11 = 0;
let value12 = 0;
let value13 = 0;
let value14 = 0;
let value15 = 0;
let value16 = 0;
let element = document.getElementById("grade");
let grade01 = element.value;
if (grade01 == "grade1") {
value07 = 0;
}else if (grade01 == "grade2") {
value07 = 0;
}else if (grade01 == "grade3") {
value07 = 1;
}else if (grade01 == "grade4") {
value08 = 1;
}else if (grade01 == "grade5") {
value09 = 1;
}else if (grade01 == "grade6") {
value10 = 1;
}else if (grade01 == "grade7") {
value11 = 1;
}else if (grade01 == "grade8") {
value12 = 1;
}else if (grade01 == "grade9") {
value13 = 1;
}else if (grade01 == "grade10") {
value14 = 1;
}else if (grade01 == "grade11") {
value15 = 1;
}else{
value16 = 1;
}
var url = $("#url_post").val();
var feature1 =
$("#value1").val() + "," +
$("#value2").val() + "," +
$("#value3").val() + "," +
$("#value4").val() + "," +
$("#value5").val() + "," +
$("#value6").val() + "," +
value07 + "," +
value08 + "," +
value09 + "," +
value10 + "," +
value11 + "," +
value12 + "," +
value13 + "," +
value14 + "," +
value15 + "," +
value16;
var JSONdata = {
data: feature1
};
alert(JSON.stringify(JSONdata));
var username = $("input#username").val();
var password = $("input#password").val();
$.ajax({
type: 'POST',
url: url,
//envoyer une authentification de base
beforeSend: function(xhr){
xhr.setRequestHeader('Authorization', 'Basic ' + btoa(username+':'+password));},
data: JSON.stringify(JSONdata),
contentType: 'application/JSON',
dataType: 'JSON',
scriptCharset: 'utf-8',
success : function(data) {
// Success
alert("success");
alert(JSON.stringify(JSONdata));
$("#response").html(JSON.stringify(data));
},
error : function(data) {
// Error
alert("error");
alert(JSON.stringify(JSONdata));
$("#response").html(JSON.stringify(data));
}
});
})
})
</script>
</html>