0

I have created a ML model using logistic regression. I am trying to deploy it on local machine using Flask. I have written html code to get the input values from the user through form. I am accepting the input from user and feeding it to ML model whose output will be returned by the flask's predict function and it is supposed to be printed on screen as pop-up box. In a nutshell, the process is as follows :

  1. User submits html form
  2. The data is passed to flask's predict function which contains trained ML model weights
  3. Flask function returns the output (it is a string - a statement stating whether patient is positive or not)
  4. This string returned by flask's predict function needs to be printed on the screen as a pop-up box on the same page where we had collected data from the user using html form. Please note that pop-up box pops up as soon as 'submit' button is pressed so all this will occur in a moment. If in case model takes more time to predict, it pop-up box should display 'loading' followed by the output.

I have written the code for predict function and the code for pop up box using online resources and code-snippets. However, I don't know how to fetch the output of flask and provide it to html pop-up box. The code of predict function is as follows :

@app.route('/index')
def index():
    return flask.render_template('index.html')

@app.route('/predict', methods=['POST'])
def predict():
    input_values = request.form.to_dict()
    X_datapoint = list(input_values.values())
    encoder = pickle.load(open('OneHot_Encoder.sav', 'rb'))
    X_datapoint = encoder.transform(X_datapoint.values.reshape(1,-1))
    model = pickle.load(open('finalized_model.sav', 'rb'))
    y = model.predict(X_datapoint)[0]
    if y == 0 :
        y_proba = round(model.predict_proba(X_datapoint)[0][0]*100)
        final_output = "We are {} sure that the patient will NOT be readmitted in 30 days".format(y_proba)
    else :
        y_proba = round(model.predict_proba(X_datapoint)[0][1]*100)
        final_output = "We are {} sure that the patient will be readmitted in 30 days".format(y_proba)

    return final_output 
    
if __name__ == '__main__':
    app.debug = True
    app.run(host='0.0.0.0', port=8080)

Here, 'OneHot_Encoder.sav' and 'finalized_model.sav' are the files that contain trained One Hot encoder model weights and trained logistic regression model weights respectively.

The code for pop-up box is as follows :

            <div id="popup1" class="overlay">
                <div class="popup">
                    <h2>Will the patient be readmitted in 30 days ?</h2>
                    <a class="close" href="#">&times;</a>
                    <div class="content">
                    <script>Not sure what to write here, I want to print the output returned by flask here  </script>
                    </div>
                </div>
            </div>

My question is, how can I print the value returned by predict function in the pop-up box which pops up as soon as the form's 'submit' button is pressed. I am not sure, if this is the right way to do it.

E_net4
  • 27,810
  • 13
  • 101
  • 139
  • You could render the template again in predict except the template would contain the pop up box. This way, you can simply pass the output via templating. But what you describe sounds more like a job for javascript. You could use javascript `fetch` to call the predict function and use callbacks to update the content. – Tim Feb 22 '21 at 05:27
  • @Tim Could you please explain the same with code, I am new to Flask and Javascript. – rishikesh fulari Feb 22 '21 at 05:30

1 Answers1

3

With flask you can write another template for the predict output. For example,

predict.html

...
<div id="popup1" class="overlay">
    <div class="popup">
        <h2>Will the patient be readmitted in 30 days ?</h2>
        <a class="close" href="#">&times;</a>
        <div id="predict_content" class="content">
            {{ predict_content }}
        </div>
    </div>
</div>

Then, in predict function, you can render this template like the following

@app.route('/predict', methods=['POST'])
def predict():
    ...
    return flask.render_template('predict.html', predict_content=final_output )

So whenever predict finishes running, it will render and display the html with the popup box. By providing predict_content=final_output, this will replace {{ predict_content }} in the template with whatever is the final_output.


Alternatively, you can use javascript. So in your form, instead of having the form submit to /predict. You can assign a function to the submit button. For example,

<form id='myForm'>
...
</form>
<button onClick='submit()'>Submit</button>

And you can define the javascript submit_function like the following (vanilla javascript):

<script>
function submit() {
    var xhr = new XMLHttpRequest();
    xhr.open("POST", "/predict"); 
    xhr.onload = function(event){ 
        alert("Success, server responded with: " + event.target.response); // raw response in alert popup
        document.getElementById("predict_content").innerHTML = event.target.response; // set content of the div with id "predict_content" to the server response.
    }; 
    // or onerror, onabort
    var formData = new FormData(document.getElementById("myForm")); 
    xhr.send(formData);
}
</script>

This gives you a pop-up alert window with the response. It also sets the content of the div with id="predict_content".

You can also use jQuery, etc. See source below.
Source: How do I capture response of form.submit

Tim
  • 3,178
  • 1
  • 13
  • 26