I have a view that returns JSON data. I want to get that data from another view as well, so I tried calling the JSON view from it. However, a Response
was ret
The decorator of a view-function can convert your return-value in a Response object depending on it's type (more information about these rules check out here). The json data is stored in r.response
where r
is the Response
object.
The better solution is to create a separate function, which returns the json data, which can be called from two different view-functions.
Your view has return jsonify(...)
at the end of it. jsonify
returns a Response
with JSON data, it doesn't return the raw data directly. You could re-parse the JSON data from the response object, or you could separate the function that generates data from the view that returns a response.
from flask import json
r = get_promoter(id)
data = json.loads(r.data, encoding=r.charset))
# or separate the data from the view
def get_promoter(id):
return json.dumps(...)
@app.route(...)
def promoter(id):
return jsonify(**get_promoter(id))
@app.route(...)
def other_view():
promoter = get_promoter(400617)
...
Other views may return other types of data. jsonify
happens to return a Response
object, but other valid return values are strings (from render_template
, for example) and tuples. Any of these will be turned into Responses
when Flask is handling a request, but when just calling the view functions they return whatever they return, which might happen to be a Response
.
You can write a decorator for your views to handle this:
from flask import jsonify
from functools import wraps
def jsonify_or_raw(func):
@wraps(func)
def wrapper(*args, **kwargs):
raw = False
if "raw" in kwargs:
raw = kwargs["raw"]
del kwargs["raw"]
result = func(*args, **kwargs)
return jsonify(result) if not raw else result
return wrapper
You would use the decorator like so:
@app.route('/promoters/<int:id>', methods=['GET'])
@jsonify_or_raw
def get_promoter(id):
return {"your data": "goes here"}
The decorator will handle wrapping your data in a response via flask.jsonify
-- but you can also get the data from another view by doing the following:
@app.route('/some_page', methods=['GET'])
def some_page():
promoter = get_promoter(1, raw=True)
...