Cannot get data from request.get_json(force=True) - python

import requests
import numpy as np
import json
from flask import Flask, request, jsonify
url = 'http://localhost:5000/api'
dat = np.genfromtxt('/home/panos/Manti_Milk/BigData/50_0_50_3.5_3-3.dat')
d1 = dat[:,0]
data = {"w0": d1[0], "w1": d1[1], "w2": d1[2], "w3": d1[3], "w4": d1[4],
"w5": d1[5], "w6": d1[6], "w7": d1[7], "w8": d1[8], "w9": d1[9], "w10": d1[10],
"w11": d1[11], "w12": d1[12], "w13": d1[13], "w14": d1[14], "w15": d1[15]}
jsondata = json.dumps(data, indent=4)
r = request.post(url, json = jsondata)
#app.route('/api',methods=['POST','GET'])
def predict():
jsondata = request.get_json(force=True)
dummy = json.loads(jsondata)
arr = np.fromiter(dummy.values(), dtype=float).reshape(16,1)
return {"data": arr}
if __name__ == '__main__':
app.run(port=5000, debug=True)
It returns Bad Request
Failed to decode JSON object: Expecting value: line 1 column 1 (char 0)
When setting force=False, returns "Null"
Any Help?
I have read several questoins/answers where it should work. But this is not the case!

You do not need to decode json data after request.get_json(), it is already the Python dict. So the line dummy = json.loads(jsondata) is unnecessary.
#app.route('/api',methods=['POST','GET'])
def predict():
jsondata = request.get_json(force=True)
arr = np.fromiter(jsondata.values(), dtype=float)
EDIT:
First file - server.py:
import numpy as np
from flask import Flask, request
app = Flask(__name__)
#app.route('/api', methods=['POST', 'GET'])
def predict():
jsondata = request.get_json(force=True)
arr = np.fromiter(jsondata.values(), dtype=float).reshape(16, 1)
print(arr) # do whatever you want here
return "1"
app.run(debug=True)
Second file - client.py:
import requests
import numpy as np
dat = np.genfromtxt('data.dat')
d1 = dat[:, 0]
data = {"w0": d1[0], "w1": d1[1], "w2": d1[2], "w3": d1[3], "w4": d1[4],
"w5": d1[5], "w6": d1[6], "w7": d1[7], "w8": d1[8], "w9": d1[9], "w10": d1[10],
"w11": d1[11], "w12": d1[12], "w13": d1[13], "w14": d1[14], "w15": d1[15]}
requests.post("http://127.0.0.1:5000/api", json=data)
Then execute them separately (from different console tabs):
At first, start the server in [1] tab:
$ python server.py
* Running on http://127.0.0.1:5000
Press CTRL+C to quit
* Restarting with stat
* Debugger is active!
And after that run request from client in another [2] tab:
$ python client.py
Then you will see desired output in server tab [1]:
[[2297.]
[1376.]
[1967.]
[2414.]
[2012.]
[2348.]
[2293.]
[1800.]
[2011.]
[2340.]
[1949.]
[2015.]
[2338.]
[1866.]
[1461.]
[2158.]]

Related

I am seeing this error in server.py file, " The browser (or proxy) sent a request that this server could not understand."

Here I am attaching my server.py and util.py
I have trained a model, and now wish to print the data on user's demand.
server.py
from flask import Flask, request, jsonify
#from waitress import serve
import util
import json
#%run util.ipynb
app = Flask(__name__)
#app.route('/hi')
def hi():
return util.areas()
#app.route('/locations')
def locations():
response = jsonify({
'locations': util.locations()
})
response.headers.add('Access-Control-Allow-Origin', '*')
return response
#app.route('/predict_home_price', methods=['GET', 'POST'])
def predict_home_price():
total_sqft = float(request.form['total_sqft'])
location = request.form['location']
size = int(request.form['size'])
bath = int(request.form['bath'])
area_type = request.form['area_type']
balcony = int(request.form['balcony'])
response = jsonify({
'estimated_price': util.get_estimated_price(area_type, location, size, total_sqft, bath, balcony)
})
response.headers.add('Access-Control-Allow-Origin', '*')
return response
if __name__ == '__main__':
print('python flask started')
app.run()
#serve(app, host='0.0.0.0', port=50100, threads=1)
util.py
import json
import joblib
import numpy as np
__locations = None
__area = None
__model = None
def get_estimated_price(area_type, location, size, total_sqft, bath, balcony):
x = np.zeros(6)
x[0] = __area.index(area_type)
x[1] = __locations.index(location)
x[2] = size
x[3] = total_sqft
x[4] = bath
x[5] = balcony
return round(__model.predict([x])[0][0],2)
def locations():
return __locations
def areas():
return __area
def load_saved_artifacts():
print("loading saved artifacts...start")
global __data_columns
global __locations
global __area
with open('./artifacts/locations.json','r') as f:
__locations = json.load(f)['data_locations']
with open('./artifacts/area.json','r') as f:
__area = json.load(f)['data_area']
global __model
__model = joblib.load('./artifacts/Banglore_Real_State_Price')
print(" loading artifacts is done")
if __name__ == '__main__':
load_saved_artifacts()
#print(locations())
#print(areas())
print(get_estimated_price('Super built-up Area','Electronic City Phase II',2,1056,2,1))
print(get_estimated_price('Built-up Area','Uttarahalli',3,1440,2,3))
print(get_estimated_price('Super built-up Area','Lingadheeranahalli',3,1521,3,1))
print(get_estimated_price('Super built-up Area','Kothanur',2,1200,2,1))
Immediate help is really appreciated
I have trained a model, and now wish to print the data on user's demand.
I am seeing this error in server.py file, " The browser (or proxy) sent a request that this server could not understand." I checked everything works fine if I am sending data to browser but not when asking for the data, I tried Postman for sending the data.
http://127.0.0.1:5000/predict_home_price -> shows bad request.
http://127.0.0.1:5000/locations -> shows correct data
http://127.0.0.1:5000/hi -> shows correct data
As you mentioned, when you're sending data to the server it works, and that's because you're using a POST request and the request has form data in it.
But when you're "asking for data", you're probably using a GET request, which has no form data in it, and that's why the server responses with an error.
You can modify your code so you can decide what you should do for each type of request:
#app.route('/predict_home_price', methods=['GET', 'POST'])
def predict_home_price():
if request.method == "POST":
# get form data and do something with it
elif request.method == "GET":
# return some value, without looking for form data

Add cache-control to my python app in Flask

I am doing a few tests about my website.
My app was developped using flask,
I want to add cach-control "max-age=3600" in my function below :
from flask import Flask, jsonify, abort
from waitress import serve
import pandas as pd
from time import time as t
from load_data.connexion_to_blob import connexion_to_blob
from load_data.load_recos import load_recos
# CONFIG FILE
import configparser
config = configparser.ConfigParser()
config.read('config.ini')
# CHARGE DATA FROM BLOB
mode = 'blob'
blob_service_client = connexion_to_blob("AZURE_STORAGE_CONNECTION_STRING")
load_recos(blob_service_client, langue='fr', mode='blob')
# LOAD DATA IN APP
recos_fr_file = config['PATH']['recos_fr_file']
recos_fr = pd.read_pickle(recos_fr_file)
recos_dict = {'fr': recos_fr}
app = Flask(__name__)
#app.route('/<langue>/<program_id>/<top>')
def get_reco(langue, program_id, top=10):
t_all = t()
top = int(top)
if program_id not in list(recos_dict[langue].keys()):
abort(404, description="programId not found")
else:
recos_list = recos_dict[langue][program_id][:top]
json_output = {
"data": [
{"programId": programId}
for programId in recos_list
]
}
print("temps exec total: ", (t() - t_all))
print('---------------------------------')
return jsonify(json_output)
if __name__ == '__main__':
serve(app, host='X.X.X.X', port=XX, threads=8)
I already check some documentation,
My question is at what level should this be done?
Thank you.
We can add cach control using :
#app.after_request
def apply_caching(response):
response.headers['Cache-Control'] = 'public, max-age=3600,stale-while-revalidate=600, stale-if-error=259200'
return response

How to properly convert a variable byte of an array to list[int] in flask?

I have this flask code wherein it can receive an inputted data from the client side(angular). Example of the passed data into the flask is this [23410, 23910, 25609, 23145, 22115]. These passed data can be read in flask by this code request.data but this code only stored the passed data into bytes. So I tried to convert these passed data from bytes to list[int] using dataConvert = list(data) but the output was [90, 50, 40, 70, 60, 80, 50, 20, 30, 60, 40....] instead of [23410, 23910, 25609, 23145, 22115]. In summary how can I properly convert a variable byte into list[int]? or maybe how can I properly request a data so that it will store those passed data into list[int] automatically
from flask import Flask, jsonify, redirect, request, url_for
import flask;
import pickle
import numpy as np
import flask
from flask_cors import CORS
from app import pred_dataout;
app = Flask(__name__)
CORS(app)
TAG =" ============>>>>>>>>"
#app.route("/adminData", methods = ['POST'])
def reportData():
data = request.data
dataConvert = list(data)// this is problem, I dont know how to properly convert a variable byte into list[int]
print(TAG, data)
return jsonify("ello")
if __name__ == '__main__':
app.run(debug=True)
As you're sending a payload using POST request, your data is in dictionary, not in list so if the assumed payload you're sending is
{'values':[23410, 23910, 25609, 23145, 22115]}
then your Flask view would be something like this:
from flask import Flask, json, jsonify, request, make_response
#app.route("/adminData", methods = ['POST'])
def reportData():
status = 200 # default success
try:
data = request.json # Read json dictionary from request
values = data.get("values", None) # Get list from payload
if values:
result = {"message": "success", "values": values}
else:
status = 500 # Failure
result = {"message": "error", "values": []}
except Exception as e:
status = 500 # Failure
result = {"message": "error", "values": []}
return make_response(jsonify(result), status)

Having Not Acceptable Error posting Json to an external url in Flask

Having a raise JSONDecodeError(errmsg, string, idx)
simplejson.errors.JSONDecodeError: Expecting value: line 1 column 1 (char 0) ERROR running the above code its been days now please help still new to python and flask as well.
from flask import request
from flask import Flask, jsonify
import json
import requests
import base64
from icalendar import Calendar, Event
from datetime import datetime
from pytz import UTC # timezone
import os
app = Flask(__name__)
#app.route('/')
def hello_world():
return "Webhook"
#app.route('/webhook', methods = ['POST'])
def webhook():
if request.headers['Content-Type']=='application/json':
res = request.get_json()
for product in res['Attachments']:
encode = product['Content']
encoded= encode
data = base64.b64decode(encoded)
f = open("guru99.ics","wb")
f.write(data)
f.close()
cal = Calendar()
cal.add('prodid', '-//My calendar product//mxm.dk//')
cal.add('version', '2.0')
g = open('guru99.ics','rb')
gcal = Calendar.from_ical(g.read())
for component in gcal.walk():
print (component.name)
g.close()
print()
g = open('guru99.ics','rb')
gcal = Calendar.from_ical(g.read())
for component in gcal.walk():
if component.name == "VEVENT":
start = component.get('dtstart')
end = component.get('dtend')
stamp =component.get('dtstamp')
organ = component.get('ORGANIZER')
organiser =organ.split(":",1)
organiser = organiser[1]
loca =component.get('LOCATION')
location =loca.split(",",1)
location = location[0]
attend = component.get('ATTENDEE')
summary =component.get('summary')
duration = end.dt-start.dt
print(summary)
print(organiser)
print(location)
print(start.dt)
print(end.dt)
print(stamp.dt)
print(end.dt-start.dt)
for element in attend :
if element:
attendee = list(element.split(":",1))
attendee = attendee[1]
print(attendee)
url = 'https://www.qa.******.com/api/receive_register.php'
data = {'organiser': organiser, 'location': location,'attendee': attend,'meeting_name': summary, 'start_date': str(start.dt), 'end_date': str(end.dt), 'timestamp': str(stamp.dt)}
response = requests.post(url, json.dumps(data), headers = {'Content-type': 'application/json'})
print(response.text)
return response.json()
g.close()
Having a raise JSONDecodeError(errmsg, string, idx)
simplejson.errors.JSONDecodeError: Expecting value: line 1 column 1 (char 0) running the above code its been days now please help still new to python and flask as well.
I found the solution, was to reach my service provider's customer service to whitelist the endpoint to accept calls from my external Api.Mod_Security error. Hope that will someone who might get stuck at some point.

How to describe and visualize continued changed data from mongoDB using pandas

I'm setting up an API using Flask, and add some JSON post using postman to be transferred to mongoDB database.
Then I had to visualize statistics of the real time data from the database into lets say data_analysis_script.py, which means if I post some JSON from postman, the statistics should be changed since the data had been added.
Any suggestion about function or library I could use further in script for showing the data statistics ?
I had tried using manager which could run both app.run() and the code, but not print the code
API code
from flask import Flask, jsonify, request
from flask_pymongo import PyMongo
import pandas as pd
app = Flask(__name__)
app.config['MONGO_DBNAME'] = 'db'
app.config['MONGO_URI'] = 'mongodb://localhost:8000/db'
mongo = PyMongo(app)
#app.route('/stocks', methods=['GET'])
def get_all_stocks():
stocks = mongo.db.stocks
output = []
for i in stocks.find():
output.append({'name' : i['name'], 'item' : i['item']})
return jsonify({'Here yours' : output})
#app.route('/add', methods=['POST'])
def add_stocks():
stocks = mongo.db.stocks
name = request.json['name']
item = request.json['item']
item_id = stocks.insert({'name': name, 'item': item})
new_stocks = stocks.find_one({'_id': stocks_id })
output = {'name' : new_stocks['name'], 'item' : new_stocks['item']}
return jsonify({'Here yours' : output})
#app.route('/stocks/', methods=['GET'])
def get_one_stocks(name):
stocks = mongo.db.stocks
c = stocks.find_one({'name' : name})
if s:
output = {'name' : c['name'], 'item' : c['item']}
else:
output = "Nothing"
return jsonify({'Here yours' : output})
if __name__ == '__main__':
app.run(debug=True)
I expect the data visualization and statistics changed when there is a JSON entry

Categories