user3287829
user3287829

Reputation: 1444

How do I alter a response in flask in the after_request function?

I am new to Flask and python. I have a bunch of views that return a dictionary in jsonify() format. For each of these views I'd like to add an after_request handler to alter the response so I can add a key to that dictionary. I have:

@app.route('/view1/')
def view1():
  ..
  return jsonify({'message':'You got served!'})

@app.after_request
def after(response):
  d = json.loads(response.response)
  d['altered'] = 'this has been altered...GOOD!'
  response.response = jsonify(d)
  return response

The error I get is "TypeError: list indices must be integers, not str". How do I alter the response dictionary and add a key after the request is completed?

Upvotes: 19

Views: 22498

Answers (2)

Martijn Pieters
Martijn Pieters

Reputation: 1122322

response is a WSGI object, and that means the body of the response must be an iterable. For jsonify() responses that's just a list with just one string in it.

However, you should use either the response.data property here to retrieve the response body, as that'll flatten the response iterable for you.

As of Flask 1.0, you don't even have to decode the data from JSON, you can use the new Response.get_json() method instead.

The following should work:

d = response.get_json()
d['altered'] = 'this has been altered...GOOD!'
response.data = json.dumps(d)

Don't use jsonify() again here; that returns a full new response object; all you want is the JSON response body here.

You can instead assign back to response.data, which will take care of encoding back to bytes and adjust the Content-Length header to reflect the altered response size.

Upvotes: 39

Yongju Lee
Yongju Lee

Reputation: 251

This looks a bit old as the last reply was written four years ago.

There seems to be a way to get the response without parsing the response data string. Use

response.get_json()

The response returns a dict object, but as Flask returns an error if you are trying to update a key on a non-dict type. Use as follows:

data = response.get_json()

if type(data) is dict:

    data['hi'] = 'hi'

    response.data = json.dumps(data)


return response

Upvotes: 3

Related Questions