I'm trying to set of a REST web service using Flask. I'm having a problem with the error handling #app.errorhandler(404)
#!flask/bin/python
from flask import Flask, jsonify, abort
app = Flask(__name__)
#app.errorhandler(404)
def not_found(error):
return jsonify({'error':'not found'}), 404
if __name__ == '__main__':
app.run(debug = True)
When I cURL it, I get nothing. In my debugger, it's telling me I have a TypeError: 'Response' object is not iterable
I used jsonify in another method with a dictionary with no problem, but when I return it as an error, it doesn't work. Any ideas?
from flask import Flask, jsonify
app = Flask(__name__)
#app.errorhandler(404)
def not_found(error):
return jsonify({'error':'not found'}), 404
app.run()
With code above, curl http://localhost:5000/ give me:
{
"error": "not found"
}
Are you using flask.jsonify?
As mentioned in the comments for the previous answer, that code isn't supported on Flask 0.8, and would require 0.9 or higher. If you need to support Flask 0.8, here is a compatible version that assigns the "status_code" instead:
#app.errorhandler(404)
def not_found(error):
resp = jsonify({'error':'not found'})
resp.status_code = 404
return resp
Related
I am facing an issue with my flask program.
I hosted a flask application on IIS running on Win 11. But from Postman I am Getting Get response but 500 error when Methos = POST.
But there is no error when running the same code from VS Code.
My Flask code:
import decodedata
import Call_printer
from flask import Flask, request, render_template,jsonify
app = Flask(__name__)
#app.route('/print',methods = ['GET','POST'])
def printer():
if request.method == 'POST':
req_data = request.json
print(req_data)
data = req_data['data']
printername= req_data['printername']
xml = decodedata.decode_xml(data)
msg = Call_printer.sendprintjob(printername,xml)
status={"Status":msg}
return jsonify(status)
if request.method == 'GET':
return "Hello World."
if __name__ == '__main__':
app.debug = True
app.run()
Below is an error when running from IIS.
Error in IIS
Below is the correct POST Response from VS CODE
Success in VS Code
But I am receiving responses in GET method from IIS. Only for POST, I am receiving 500 error?
Can it be because I am calling other py files for POST?
Any idea how can I fix it?
Regards,
Mayank Pande
When I run this code it gives a "404 page not found" error
from flask import Flask, render_template
app = Flask(__name__)
#app.route('/Home')
def home():
return "Hello World!"
if __name__ == '__main__':
app.run(debug=True)
You should set the route to home as just "/"
#app.route('/')
def home():
...
or visit /Home in your browser
Try changing the last line to app.run(host='0.0.0.0') and then use localhost:5000 to access the API. Here is a great tutorial I've used on setting up Flask on Ubuntu: https://www.digitalocean.com/community/tutorials/how-to-serve-flask-applications-with-uswgi-and-nginx-on-ubuntu-18-04.
Using just the Flask server with Python, the following get request works:
from flask import Flask, request
app = Flask(__name__)
class Result(Resource):
def get(self):
image_id = request.headers.get('image_id')
api.add_resource(Result, '/results')
if __name__ == '__main__':
app.run(host='0.0.0.0', port=int(os.getenv('PORT', 5000)))
However, using Waitress, the following does not work (image_id is None):
from waitress import serve
from flask import Flask, request
app = Flask(__name__)
class Result(Resource):
def get(self):
image_id = request.headers.get('image_id')
api.add_resource(Result, '/results')
if __name__ == '__main__':
serve(app, host="0.0.0.0", port=int(os.getenv('PORT', 5000)))
POST and other GET requests work fine, it's just GET with headers that doesn't work. Anyone have any ideas?
I had the same issue, after searching around I found this issue on GitHub. Apparently it is a security feature and you should not use _ in your header. So you should rename your header to image-id or something else without a _ character for it to work.
all my code is just:
from splinter import Browser
from flask import Flask, request
from splinter.driver.flaskclient import FlaskClient
app = Flask(__name__)
browser = Browser('flask', app=app)
browser.visit('https://www.google.com')
print(browser.html)
which print the 404 html:
404 Not Found
Not Found
The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.
there is anything I should do?
You are getting a 404 error because your Flask app has no routes.
I believe the purpose of the Splinter Flask client is to test your Flask app, not to test/request other domains. Visiting another domain with the Splinter Flask client will simply request the URL from your domain. You have not specified any routes for your Flask app, so Flask is responding with a 404 error.
Here's an example that shows how the Splinter Flask client is working:
# define simple flask app
from flask import Flask
app = Flask(__name__)
#app.route('/')
def hello_world():
return 'Hello, World!'
#app.route('/<name>')
def hello_world(name):
return 'Hello, {name}!'.format(name=name)
# initiate splinter flask client
from splinter import Browser
browser = Browser('flask', app=app)
# simple flask app assertions
browser.visit('http://127.0.0.1:5000')
assert browser.html == 'Hello, World!'
browser.visit('http://127.0.0.1:5000/haofly')
assert browser.html == 'Hello, haofly!'
# Notice that requesting other domains act as if it's your domain
# Here it is requesting the previously defined flask routes
browser.visit('http://www.google.com')
assert browser.html == 'Hello, World!'
browser.visit('http://www.google.com/haofly')
assert browser.html == 'Hello, haofly!'
Here's another test that demonstrates what's really going on:
from flask import Flask
app = Flask(__name__)
#app.errorhandler(404)
def page_not_found(e):
return 'Flask 404 error!', 404
from splinter import Browser
browser = Browser('flask', app=app)
browser.visit('http://www.google.com/haofly')
assert browser.html == 'Flask 404 error!'
I have a flask web app which uses render_template as follows.I need to add a Content-Security-Policy as additional http response headerin the response. I tried following ways but both fail and give me 500.
1.
from flask import \
Flask, \
render_template
app = Flask(__name__,template_folder='tmpl')
#app.route('/')
def index():
resp =make_response(render_template('index.html'))
resp.headers['Content-Security-Policy']='default-src \'self\''
return resp
if __name__ == '__main__':
app.run(host='0.0.0.0', port=3001)
2.
#app.route('/')
def index():
resp =render_template('index.html')
resp.headers.add('Content-Security-Policy','default-src \'self\'')
return resp
if __name__ == '__main__':
app.run(host='0.0.0.0', port=3001)
What can be wrong here?
On the terminal i see following when I access the web app as localhost:3001
127.0.0.1 - - [06/Apr/2015 01:45:01] "GET / HTTP/1.1" 500 -
render_template returns a string, not a response. A string returned from a view is automatically wrapped in a response by Flask, which is why you may be confused. Construct the response with the rendered template.
from flask import make_response
r = make_response(render_template('index.html'))
r.headers.set('Content-Security-Policy', "default-src 'self'")
return r
The prettiest way to handle this, assuming that you want to same headers attached to all of your responses is with flasks builtin decorator:
#app.after_request
So in this case just add this function to your routes module:
#app.after_request
def add_security_headers(resp):
resp.headers['Content-Security-Policy']='default-src \'self\''
return resp
With this in place your functions just return the render_template(...) value as before and flask automatically wraps it in a response which is passed to the after_request function before being returned to the client.