How to return 400 (Bad Request) on Flask?
You have a variety of options:
The most basic:
@app.route('/')def index(): return "Record not found", 400
If you want to access the headers, you can grab the response object:
@app.route('/')def index(): resp = make_response("Record not found", 400) resp.headers['X-Something'] = 'A value' return resp
Or you can make it more explicit, and not just return a number, but return a status code object
from flask_api import status@app.route('/')def index(): return "Record not found", status.HTTP_400_BAD_REQUEST
Further reading:
You can read more about the first two here: About Responses (Flask quickstart)
And the third here: Status codes (Flask API Guide)
I like to use the flask.Response
class:
from flask import Response@app.route("/")def index(): return Response( "The response body goes here", status=400, )
flask.abort
is a wrapper around werkzeug.exceptions.abort
which is really just a helper method to make it easier to raise HTTP exceptions. That's fine in most cases, but for restful APIs, I think it may be better to be explicit with return responses.
Here's some snippets from a Flask app I wrote years ago. It has an example of a 400 response
import werkzeugfrom flask import Flask, Response, jsonfrom flask_restplus import reqparse, Api, Resource, abortfrom flask_restful import requestfrom flask_cors import CORSapp = Flask(__name__)CORS(app)api = Api(app)parser = reqparse.RequestParser()parser.add_argument('address_to_score', type=werkzeug.datastructures.FileStorage, location='files')class MissingColumnException(Exception): passclass InvalidDateFormatException(Exception): pass@api.route('/project')class project(Resource): @api.expect(parser) @api.response(200, 'Success') @api.response(400, 'Validation Error') def post(self): """ Takes in an excel file of addresses and outputs a JSON with scores and rankings. """ try: df, input_trees, needed_zones = data.parse_incoming_file(request) except MissingColumnException as e: abort(400, 'Excel File Missing Mandatory Column(s):', columns=str(e)) except Exception as e: abort(400, str(e)) project_trees = data.load_needed_trees(needed_zones, settings['directories']['current_tree_folder']) df = data.multiprocess_query(df, input_trees, project_trees) df = data.score_locations(df) df = data.rank_locations(df) df = data.replace_null(df) output_file = df.to_dict('index') resp = Response(json.dumps(output_file), mimetype='application/json') resp.status_code = 200 return resp@api.route('/project/health')class projectHealth(Resource): @api.response(200, 'Success') def get(self): """ Returns the status of the server if it's still running. """ resp = Response(json.dumps('OK'), mimetype='application/json') resp.status_code = 200 return resp