Response Types
Flask is flexible about what your view functions return. The simplest case is a string โ Flask automatically wraps it in a proper HTTP response with a 200 status code and HTML content type:
@app.route("/")
def home():
return "Hello, World!"
Return a dictionary and Flask converts it to JSON:
@app.route("/api/data")
def api_data():
return {"message": "Success", "count": 42}
This is incredibly handy for building APIs. Flask sets the Content-Type to application/json automatically.
For more control, use make_response(). It lets you customize the status code, headers, and content:
from flask import make_response
@app.route("/custom")
def custom_response():
response = make_response("Custom response", 201)
response.headers["X-Custom-Header"] = "hello"
return response
When you need to send users somewhere else, use redirect():
from flask import redirect, url_for
@app.route("/old-page")
def old_page():
return redirect(url_for("new_page"))
@app.route("/new-page")
def new_page():
return "This is the new page!"
And when something goes wrong, abort() stops processing and returns an error page:
from flask import abort
@app.route("/secret")
def secret():
if not user_is_authenticated():
abort(401)
return "Top secret content"
You can also return a tuple with a response body and a status code, or a body, status code, and headers โ all in one line:
@app.route("/created")
def created():
return "Resource created", 201
@app.route("/with-headers")
def with_headers():
return "OK", 200, {"X-Request-Id": "abc123"}
The Content-Type header tells the browser how to interpret your response. Flask defaults to text/html for strings and application/json for dicts. You can override it when needed:
@app.route("/plain")
def plain_text():
return "Just plain text", 200, {"Content-Type": "text/plain"}