19

I currently have a Flask web server that pulls data from a JSON API using the built-in requests object.

For example:

def get_data():
    response = requests.get("http://myhost/jsonapi")
    ...
    return response

@main.route("/", methods=["GET"])
def index():
    return render_template("index.html", response=response)

The issue here is that naturally the GET method is only run once, the first time get_data is called. In order to refresh the data, I have to stop and restart the Flask wsgi server. I've tried wrapping various parts of the code in a while True / sleep loop but this prevents werkzeug from loading the page.

What is the most Pythonic way to dynamically GET the data I want without having to reload the page or restart the server?

4
  • 1
    If you're willing to route your get_data() method to a URL, you could just use AJAX to call it from the client and update the page with the results. Commented Oct 23, 2014 at 19:52
  • @Celeo that's one way. But say I have get_data() in a separate file and I don't want to add another route? My question pertains to whether this can be accomplished using Flask or a Flask extension. Commented Oct 23, 2014 at 19:58
  • 1
    You'll have to have some way for the client to get data from the server after the server has already rendered the template. If you just want the data to update in the background without client-interaction, you could try Celery. Commented Oct 23, 2014 at 20:00
  • Thanks, I should add that the background task manager I chose for this particular scenario is RQ. Commented Oct 23, 2014 at 21:49

2 Answers 2

17

You're discussing what are perhaps two different issues.

  1. Let's assume the problem is you're calling the dynamic data source, get_data(), only once and keeping its (static) value in a global response. This one-time-call is not shown, but let's say it's somewhere in your code. Then, if you are willing to refresh the page (/) to get updates, you could then:

    @main.route("/", methods=['GET'])
    def index():
        return render_template("index.html", response=get_data())
    

    This would fetch fresh data on every page load.

  2. Then toward the end of your question, you ask how to "GET the data I want without having to reload the page or restart the server." That is an entirely different issue. You will have to use AJAX or WebSocket requests in your code. There are quite a few tutorials about how to do this (e.g. this one) that you can find through Googling "Flask AJAX." But this will require an JavaScript AJAX call. I recommend finding examples of how this is done through searching "Flask AJAX jQuery" as jQuery will abstract and simplify what you need to do on the client side. Or, if you wish to use WebSockets for lower-latency connection between your web page, that is also possible; search for examples (e.g. like this one).

Sign up to request clarification or add additional context in comments.

3 Comments

Good point on separating into two issues. This answers both my specific case and the general question. It may be worth sharing Flask-SocketIO here as well.
In your answer you reference that a one-time-call is not shown... what would that one-time-call look like in Python code?
@RussellBurdt The OP has a get_data() function, and later does return render_template("index.html", response=response). Presumably there is a global response = get_data() somewhere not shown; it'd be needed to make that example work. My suggestion is basically to move the function call into the route hander, so that it's called every request, not just statically once per program run.
0

To add to Jonathan’s comment, you can use frameworks like stimulus or turbo links to do this dynamically, without having to write JavaScript in some cases as the frameworks do a lot of the heavy lifting. https://stimulus.hotwired.dev/handbook/origin

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.