This question already has an answer here:
Flask view raises TypeError: 'bool' object is not callable
(1 answer)
Closed 3 years ago.
from flask import Flask, jsonify, request
app = Flask(__name__)
#app.route('/add-two-numbers', methods=["POST"])
def add_two_numbers():
request_payload = request.get_json()
x = request_payload["x"]
y = request_payload["y"]
return str(x + y)
if __name__ == "__main__":
app.run(debug=True)
The above code is working.. however, I get an "int is not callable" error in my return statement when I do return x+y but it is fine when I do return str(x+y). Why is this?
This is answered here, but in short, a response can be a string, but not int.
The documentation:
If a response object of the correct type is returned it’s directly returned from the view.
If it’s a string, a response object is created with that data and the default parameters.
If a tuple is returned the items in the tuple can provide extra information. Such tuples have to be in the form (response, status, headers) or (response, headers) where at least one item has to be in the tuple. The status value will override the status code and headers can be a list or dictionary of additional header values.
If none of that works, Flask will assume the return value is a valid WSGI application and convert that into a response object.
Related
This question already has answers here:
Flask view return error "View function did not return a response"
(3 answers)
Closed 1 year ago.
I am trying to send a webhook with a json to my flask app- it then takes the key values and inputs it to my search engine and should reply back with the results and 200 (code that it was successful) my code looks like this:
from flask import Flask, request, abort
from Webhooks.TGSearchEngine import TGSearch
app = Flask(__name__)
#app.route('/', methods=['POST'])
def webhook():
sys.stdout.flush()
if request.method == 'POST':
reply = request.json['reply']
query = request.json['query']
channel = request.json['channel']
messageid = request.json['id']
return TGSearch.main(reply, query, channel, messageid), 200
else:
abort(400)
But I get TypeError( TypeError: The view function did not return a valid response. The function either returned None or ended without a return statement.
My TGSearch.main() module takes the vars and returns a dictionary with the results. I don't understand why it would throw this error. Any ideas?
If you are sure that TGSearch.main(reply, query, channel, messageid), 200 doesn't return None value, you had to convert the result of the response to a valid response object.
Try one of these options:
You can pass the result in a variable to a template rendering:
response = TGSearch.main(reply, query, channel, messageid), 200
return render_template("example.html", response)
You can convert the response into a JSON:
from flask.json import jsonify
result = TGSearch.main(reply, query, channel, messageid), 200
response = jsonify(result)
Or in the case you are getting a tuple, you can access separate values and make them a string.
result = TGSearch.main(reply, query, channel, messageid), 200 // "Message", 200
return str(result[0]) + str(result[1])
Flask must always return something. In your else statement you should add a return.
Note: you specified methods=['POST'] in your route, so the only method allowed will be POST, I don't think it's necessary to check if request.method == 'POST'
This question already has answers here:
How to get POSTed JSON in Flask?
(13 answers)
Return JSON response from Flask view
(15 answers)
Closed 3 years ago.
I have a return statement,however it gives the error View function did not return a response. How can I solve this issue?
#app.route('/out/', methods=[ 'POST'])
def extract():
json_request = request.get_json()
print (json_request)
data = json.loads(json.dumps(json_request))
return data
if __name__ == "__main__":
app.run()
My front end is an angular js application which calls the API of Flask in postman i am able to get the request but not from the front end
front end code
aURL: string = 'http://127.0.0.1:5000/out';
return this.httpClient.post(`${this.aURL}/`,JSON.stringify(request),{headers: headers});
In order to resolve the Question, for the next users. The issue is that Flask did not receive the JSON as JSON.
print(request.json) returned a None but print(request.body) returned the correct body. Which indicates the data was sent not as JSON and/or with a wrong ContentType, fixing the ContentType in the Frontend resolves the issue
I'm trying to send two files in a json object with flask restfull and send_file.
When I try to access the json object on client side i get this error:
TypeError: Object of type 'Response' is not JSON serializable
This is what i do i my flask app:
class Download(Resource):
def get(self):
try:
return {"file1" : send_file('uploads/kode.png'), "file2" : send_file('uploads/kode.png')}, 200
except:
return {"message" : "File not found!"}, 404
How can I return a json of files?
If I do the same thing with only one file without wrapping the send_file() in {}, I can access that file on the front end with java script.
You mean like:
return send_file('path/to/file.png')
That works, because Flask's send_file function actually returns a Response object.
This is also valid code (as of flask version 1.1.0):
return {"message" : "File not found!"}, 404
Here you're returning a dictionary with the key 'message' and value 'File not found!'. Flask will turn this into a Response object, with a status code of 404.
That dictionary is jsonified automatically (as of flask version 1.1.0).
When you try to return this:
return {"file1" : send_file('uploads/kode.png')}, 200
The Response object returned by send_file is then jsonified, hence the exception:
TypeError: Object of type 'Response' is not JSON serializable
The obvious way to make this work is that the frontend should make a separate request to the server for each image, passing some kind of ID which the Flask route function should then obtain and use to work out the filepath, then ultimately: return sendfile(filepath).
If you really want to send several images in one JSON response, you could look at base64 encoding the image and making a data_uri string which can be JSON serialized. However unless you really need that data to be passed as JSON, the former option is probably the go-to.
I think your except is too broad. but to get a json object back, import json and its object.json()
import json
try:
return file.json()
except Exception as e:
print(e)
or your can import the json library from flask
from flask import jsonify
def myMethod():
....
response = jsonify(data)
response.status_code = 200 # or 400 or whatever
return response
I am trying to show the list of connected devices in browser using flask. I enabled flask on port 8000:
in server.py:
#server.route('/devices',methods = ['GET'])
def status():
return app.stat()
if __name__ == '__main__':
app.run()
in app.py:
def stat():
return(glob.glob("/dev/tty57") + glob.glob("/dev/tty9"))
And this is my test:
url = "http://127.0.0.1:8000"
response = requests.get(url + "").text
print response
but I keep getting this error:
"TypeError": 'list' object is not callable.
Am I doing sth wrong in checking if ttyUSB, ... and other devices existing?
The problem is that your endpoint is returning a list. Flask only likes certain return types. The two that are probably the most common are
a Response object
a str (along with unicode in Python 2.x)
You can also return any callable, such as a function.
If you want to return a list of devices you have a couple of options. You can return the list as a string
#server.route('/devices')
def status():
return ','.join(app.statusOfDevices())
or you if you want to be able to treat each device as a separate value, you can return a JSON response
from flask.json import jsonify
#server.route('/devices')
def status():
return jsonify({'devices': app.statusOfDevices()})
# an alternative with a complete Response object
# return flask.Response(jsonify({'devices': app.statusOfDevices()}), mimetype='application/json')
I am trying to show the list of connected devices in browser using flask. I enabled flask on port 8000:
in server.py:
#server.route('/devices',methods = ['GET'])
def status():
return app.stat()
if __name__ == '__main__':
app.run()
in app.py:
def stat():
return(glob.glob("/dev/tty57") + glob.glob("/dev/tty9"))
And this is my test:
url = "http://127.0.0.1:8000"
response = requests.get(url + "").text
print response
but I keep getting this error:
"TypeError": 'list' object is not callable.
Am I doing sth wrong in checking if ttyUSB, ... and other devices existing?
The problem is that your endpoint is returning a list. Flask only likes certain return types. The two that are probably the most common are
a Response object
a str (along with unicode in Python 2.x)
You can also return any callable, such as a function.
If you want to return a list of devices you have a couple of options. You can return the list as a string
#server.route('/devices')
def status():
return ','.join(app.statusOfDevices())
or you if you want to be able to treat each device as a separate value, you can return a JSON response
from flask.json import jsonify
#server.route('/devices')
def status():
return jsonify({'devices': app.statusOfDevices()})
# an alternative with a complete Response object
# return flask.Response(jsonify({'devices': app.statusOfDevices()}), mimetype='application/json')