4

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 returned rather than the JSON data. How can I call one view from another view and get the data?

@app.route('/promoters/<int:id>', methods=['GET'])
def get_promoter(id):
    ...

>>> get_promoter(3)
<Response 440 bytes [200 OK]>
davidism
  • 121,510
  • 29
  • 395
  • 339

3 Answers3

3

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.

HelloWorld
  • 2,392
  • 3
  • 31
  • 68
1

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)
    ...
joebeeson
  • 4,159
  • 1
  • 22
  • 29
0

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.

davidism
  • 121,510
  • 29
  • 395
  • 339