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?
Creating Response as a String When Flask sees that we are returning a string from a view function it automatically converts the string into a response object ( using make_response() method ) with string as the body of the response, HTTP status code of 200 and content-type header set to text/html .
The Flask response class, appropriately called Response , is rarely used directly by Flask applications. Instead, Flask uses it internally as a container for the response data returned by application route functions, plus some additional information needed to create an HTTP response.
The before_request decorator allows us to execute a function before any request. i.e, the function defined with the . before_request() decorator will execute before every request is made. We can do this by decorating a function with @app.before_request : @app.before_request.
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With