45

Each time I use jsonify, I get the JSON keys sorted alphabetically. I don't want the keys sorted. Can I disable the sorting done in jsonify?

from flask import request, jsonify

@app.route('/', methods=['POST'])
def index():
    json_dict = request.get_json()
    user_id = json_dict['user_id']
    permissions = json_dict['permissions']
    data = {'user_id': user_id, 'permissions': permissions}
    return jsonify(data)
davidism
  • 121,510
  • 29
  • 395
  • 339
Athul Muralidharan
  • 693
  • 1
  • 10
  • 18

4 Answers4

98

Yes, you can modify this using the config attribute:

app = Flask(__name__)
app.config['JSON_SORT_KEYS'] = False

However, note that this is warned against explicitly in the documentation:

By default Flask will serialize JSON objects in a way that the keys are ordered. This is done in order to ensure that independent of the hash seed of the dictionary the return value will be consistent to not trash external HTTP caches. You can override the default behavior by changing this variable. This is not recommended but might give you a performance improvement on the cost of cacheability.

juanpa.arrivillaga
  • 88,713
  • 10
  • 131
  • 172
  • 10
    It should be noted as of Python 3.6, dicts retain their insertion order so the argument from the docs doesn't apply anymore in that general sense. – hynek Nov 28 '19 at 14:33
  • 3
    I think the answer should be updated because this is an important sidenote from @hynek. – Ri1a Dec 03 '19 at 12:47
  • @hynek still seems to work on my version at python v3.7.3 & Flask v1.1.1 – Cory C Feb 25 '20 at 04:08
  • 1
    Nobody said that it doesn’t work anymore; just that the rational for sorting keys that is in the docs quote is nil nowadays. Leaving it there could be confusing to new users. – hynek Feb 26 '20 at 05:04
  • @hynek I need my dict be in reverse order based on keys..so i do the same and return the response..but when passed through jsonify its back to its same order. How can I overcome this issue? – Dinesh Apr 13 '20 at 10:42
3

For Flask 2.3+:

app = Flask(__name__)
flask.json.provider.DefaultJSONProvider.sort_keys = False
newproject
  • 31
  • 2
  • Hello, please don't just submit code in your answer(s), add some details as to why you think this is the optimal solution. – Destroy666 May 29 '23 at 17:46
3

The JSON_SORT_KEYS config option from the accepted answer was deprecated in Flask 2.2 and removed in Flask 2.3.

As of Flask 2.2, the recommended way of disabling sorting is through the app.json provider:

app = Flask(__name__)
app.json.sort_keys = False
Philipp
  • 41
  • 1
  • Thanks for the heads up and for a related question, see https://stackoverflow.com/questions/76134147/how-do-you-work-around-deprecated-prettyprint-regular-flask-setting question. – mbigras Jul 15 '23 at 07:54
0

If you don't want to change the configuration for your entire API, you can return an unsorted JSON response using a small function like this:

def make_unsorted_response(results_dict: dict, status_code: int):
    resp = make_response({}, status_code)
    j_string = json.dumps(results_dict, separators=(',', ':'))
    resp.set_data(value=j_string)
    return resp

I like using flask-restx, here's how I'd use this function:

@api.route('/test', endpoint='test')
@api.doc(params={}, description="test")
class Health(Resource):
    def get(self):
        my_dict = {'z': 'z value',
                   'w': 'w value',
                   'p': 'p value'}
        results_dict = {"results": my_dict}
        return make_unsorted_response(results_dict, 200)

When called it returns an unsorted response like this:

{"results":{"z":"z value","w":"w value","p":"p value"}}

The syntax is pretty much the same in Flask. I would also recommend you add some exception handling to the function if you decide to use it, I'm just showing a basic example.

sudo
  • 1