In the previous article, I used Kaggle's House Sales in King County, USA dataset to generate a learning model with XGboost machine learning and turn that learning model into an API server in Flask. This time, I will explain the procedure from HTML to JSON Ajax communication using the API server. Please refer to the following article for the procedure to turn the model learned by machine learning into an API server.
Procedures for machine learning and API server using Kaggle House Sales in King County, USA dataset
Here, in order to be able to communicate from HTML with javascript Ajax, it is necessary to add the API server startup file written in Flask as follows. I'll add a library called flask_cors and related code. flask_cors must be pre-installed.
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 #to add
import pandas as pd
from sklearn.externals import joblib
import xgboost as xgb
model = joblib.load("house_sales_model.pkl")
app = Flask(__name__)
#add to
@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
#↑ Add up to here
# 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)
In the HTML file, the interface part is the input tag inside the tag, and creates a data input form. The input data is received by javascript, formatted, converted to JSON format, and POSTed by Ajax communication. When communication is successful, it receives the predicted value from the API server and displays it in the area of the textarea tag.
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Send JSON data by POST from HTML file</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>Send JSON data by POST from HTML file</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>Select 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,
//send basic authentication
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>
Recommended Posts