Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

python

flask

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?

like image 757
user3287829 Avatar asked Mar 08 '14 19:03

user3287829


People also ask

How do I send a custom response in Flask?

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 .

What is a response instance Flask?

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.

What does APP Before_request mean?

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.


2 Answers

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.

like image 157
Martijn Pieters Avatar answered Nov 15 '22 13:11

Martijn Pieters


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
like image 38
Yongju Lee Avatar answered Nov 15 '22 13:11

Yongju Lee