[PYTHON] Procedure from HTML to JSON Ajax communication of API server

Introduction

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

Ajax communication

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)

POST from HTML and send JSON data to API server

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

Procedure from HTML to JSON Ajax communication of API server
[Ansible installation procedure] From installation to execution of playbook
Sample API server to receive JSON in Golang
How to hide your Google Maps API key from HTML
Procedure from environment construction to operation test of testinfra, a server environment test tool made by Python
Easy to see difference of json
From the introduction of GoogleCloudPlatform Natural Language API to how to use it
Procedure from AWS CDK (Python) development to AWS resource construction * For beginners of development
Script to generate directory from json file
Push notification from Python server to Android
From Attention of Zero Tsuku 2 to Transformer
Summary of vtkThreshold (updated from time to time)
Convert from Markdown to HTML in Python
API explanation to touch mastodon from python
Introduction to Scapy ① (From installation to execution of Scapy)
Connect to coincheck's Websocket API from Python
SSH login to the target server from Windows with a click of a shortcut