Flask by Example: Response Object Structure
While you can return strings or dictionaries from views, sometimes you need more control. The Response object allows you to set headers, cookies, and status codes explicitly.
Code
from flask import Flask, make_response, render_template_string
app = Flask(__name__)
@app.route('/xml')
def return_xml():
content = '<data><item>Value</item></data>'
# 1. Create a Response object
response = make_response(content)
# 2. Set the Content-Type header
response.headers['Content-Type'] = 'application/xml'
# 3. Set a custom header
response.headers['X-Custom-Header'] = 'MyValue'
# 4. Set the status code
response.status_code = 200
return response
@app.route('/cookie')
def set_cookie():
resp = make_response("Cookie Set")
# 5. Set a cookie
resp.set_cookie('username', 'flask_user')
return respExplanation
While view functions usually return strings, the Response object allows for much finer control over what is sent back to the client. This includes the ability to return non-HTML data, such as XML or binary files.
The make_response() utility wraps your return value into a Response object that you can then modify. You can use this object to set specific HTTP headers, change the status code, or attach cookies before returning it.
This pattern is essential for implementing advanced features. Whether you are facilitating file downloads, setting security headers like HSTS or CSP, or managing authentication tokens via cookies, the Response object is your primary tool.
Code Breakdown
make_response(content) creates the object. You could also instantiate Response(content) directly, but make_response is more flexible as it accepts the same arguments as a view return value (e.g., body, status, headers tuple).response.headers is a dictionary-like object. Setting Content-Type is crucial here; otherwise, the browser would try to render the XML string as plain text or HTML.response.status_code allows you to explicitly set the HTTP status. While 200 is default, you might change this to 201 (Created) or 202 (Accepted) depending on your logic.resp.set_cookie() adds the Set-Cookie header. This is the only way to set cookies in Flask; you cannot set them on the global request object because that represents incoming data.
