an error in sending json data to flask server

Question:

I have a json data as

{"age":59.0,"bp":70.0,"sg":1.01,"al":3.0,"su":0.0,"rbc":1.0,"ba":0.0,"bgr":76.0,"bu":186.0,"sc":15.0,"sod":135.0,"pot":7.6,"hemo":7.1,"pcv":22.0,"wbcc":3800.0,"rbcc":2.1,"htn":1.0,"dm":0.0,"cad":0.0,"appet":0.0,"pe":1.0,"ane":1.0}

I have to send this json into a ML model that is inside a flask server to predict outcome class as 0 or 1.

so for that I wrote the following code in app.py

# flask route for ml model
import numpy as np
from flask import Flask, request, jsonify
from flask_cors import CORS
import keras
import ast

app = Flask(__name__)
CORS(app)

@app.route('/predict', methods=['POST'])
def predict():
    if request.method == 'POST':
        data_raw = request.get_json()
        print(data_raw)
        #convert json to dict
        new_dict = ast.literal_eval(data_raw)
        # initialize a new list to store the dict values
        data=[]
        for i in new_dict.values():
            data.append(i)
        # converted the values list to np array and reshaped it
        data = np.array(data)
        data = np.array(data.reshape(1, -1))
        print(data)
        # load model
        model = keras.models.load_model('model.pkl', 'rb')
        # make prediction
        prediction = model.predict(data)
        print(prediction)
        return jsonify({'prediction': prediction.tolist()})
    else:
        return jsonify({'prediction': 'error'})

# run flask app
if __name__ == '__main__':
    app.run(debug=True)

But on sending that json as POST request to localhost:5000/predict I am getting an error as

ValueError: malformed node or string: {'age': 59.0, 'bp': 70.0, 'sg': 1.01, 'al': 3.0, 'su': 0.0, 'rbc': 1.0, 'ba': 0.0, 'bgr': 76.0, 'bu': 186.0, 'sc': 15.0, 'sod': 135.0, 'pot': 7.6, 'hemo': 7.1, 'pcv': 22.0, 'wbcc': 3800.0, 'rbcc': 2.1, 'htn': 1.0, 'dm': 0.0, 'cad': 0.0, 'appet': 0.0, 'pe': 1.0, 'ane': 1.0}

Though the same data preprocessing part of pushing the dict in the model.predict is working in the training code, but its creating an error here.

model url for use in reconstruction of code

Asked By: Samar Pratap Singh

||

Answers:

The request.get_json() method is already doing the work of converting your JSON to a Python object. You can already use data_raw as a dictionary:

@app.route('/predict', methods=['POST'])
def predict():
    if request.method == 'POST':
        data_raw = request.get_json()
        print(type(data_raw))  # prints 'dict' in the terminal used to start the server
        data = np.array(data_raw.values()).reshape(1, -1)
        # do model stuff

The error you were getting is because ast.literal_eval() expects a valid string representation of a literal Python object. By passing what you didn’t realize was already a dict object, Python complained that the input was malformed.

By the way, in general when working with JSON in other contexts, you should be using json.loads(some_json_string) and json.dumps(some_python_object_you_want_to_serialize). The ast.literal_eval() function is not something you should ever really need, generally speaking.

Answered By: ddejohn
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.