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
CodePudding user response:
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.