Skip to content Skip to sidebar Skip to footer

What Is The Best Way To Implement A Forced Page Refresh Using Flask?

Background I have a large number of fields that will be updating real time from an external process. I would like to update the Flask hosted pages periodically to show connected u

Solution 1:

To avoid refreshing the entire page you want to use what is called AJAX. It looks like this is easy to implement in flask.

Since you want it to happen periodically you need to call your AJAX functions from a timer function in javascript.

This means you just put the javascript from the flask page inside a timer call.

Here's approximately what the javascript would look like:

setInterval(                               //Periodically 
  function()
  {
     $.getJSON(                            //Get some values from the server
        $SCRIPT_ROOT + '/get_values',      // At this URL
        {},                                // With no extra parameters
        function(data)                     // And when you get a response
        {
          $("#result").text(data.result);  // Write the results into the 
                                           // #result element
        });
  },
  500);                                    // And do it every 500ms

Solution 2:

I think probably the easiest way to do this is using javascript as you already suggest in your question. In this case, Flask would be just delivering an HTML document that contains some javascript code to be executed by the browser, so I don't see why this could cause any problem to Flask. In this page, I've found some examples using different combinations such as using a timer (which seems to be what you're looking for).


Solution 3:

No. Well, as least there's nothing in side of Flask that would make this easier than other solutions. SO has some decent material on implementing comet servers in Python.

As you mentioned, there you can use JavaScript to poll the server for new data. This can be difficult for your server to manage though if you have many users. Opening concurrent TCP connections is fairly expensive. It also means that your UI may appear slightly jerky, because things will be updating every second or so, rather than when new data hits the server.

With that in mind, Flask is excellent for this second choice because it is so easy to attach response functions to individual URLs. The main thing to note is you should functions which block heavily on I/O. Long-running functions will seize the whole application.

Let's say you have two temperature gauges & you're using jQuery.

@app.route('/gauge/<int:gauge_id>')
def gauge_temp(gauge_id):
    temp = temp_from_db(gauge_id) #implement this yourself
    return dict(temp=temp, gauge_id=gauge_id)

In a JavaScript file, you could have some function that updates a DOM element every minute with the current temperature. This code should give you some idea of something you can build into an actual implementation:

function updateTemp(gauge_id, selector) {
  $.getJSON('/gauge/' + gauge_id, function(data){
    $(selector).text = response.temp;
  })
}

setInterval('updateTemp(1, "#gauge-1")', 1000 * 60);
setInterval('updateTemp(2, "#gauge-2")', 1000 * 60);

Solution 4:

One way to achieve this is in Flask through WebSockets using flask-socketio. I use APScheduler for the background process in the example, but any background process will do. this updates a price on the webpage every 4 seconds:

from flask import Flask, render_template
from apscheduler.schedulers.background import BackgroundScheduler
from flask_socketio import SocketIO, emit

app = Flask(__name__)
socketio = SocketIO(app)

#defines the job
def job():
    new_price = get_new_price();
    #job emits on websocket
    socketio.emit('price update',new_price, broadcast=True)

#schedule job
scheduler = BackgroundScheduler()
running_job = scheduler.add_job(job, 'interval', seconds=4, max_instances=1)
scheduler.start()

@app.route('/')
def index():
    return render_template('index.html')

if __name__ == '__main__':
    socketio.run(app, host='0.0.0.0')

Then the index.html template is:

<!DOCTYPE HTML>
<html>
<head>
    <title>WebSockets Example</title>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
    <script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/socket.io/1.3.6/socket.io.min.js"></script>
    <script type="text/javascript" charset="utf-8">
       $(document).ready(function(){

           var socket = io.connect('http://' + document.domain + ':' + location.port);

           socket.on('connect', function() {
               socket.emit('am up', {data: 'I\'m connected!'});
           });
           //listens to 'price update' message on socket
           socket.on('price update', function(msg) {
               $('#price_info').text(msg)
           });

       });
   </script>
</head>
<body>
  <div id="price_info"></div>
</body>
</html>

Post a Comment for "What Is The Best Way To Implement A Forced Page Refresh Using Flask?"