Python Flask日期更新实时

时间:2017-04-25 00:12:01

标签: javascript python flask

我正在使用带有JavaScript的Python Flask构建一个Web应用程序。我是Javascript的初学者。

我现在所做的过程:

在Flask Python代码中,
1.我通过废弃网络获取数据(每分钟更新的数字数据)。 2.使用数据并计算一些东西并获得最终数字。 3.列出包含最终数字的列表 4.通过将列表添加到页面的Flask定义中,将列表提供给页面 5.现在在HTML中通过使用{{data | safe}}标记

捕获列表来获取列表

6。使用它与Javascript制作图表。

问题是: 在步骤1中,我得到的数据每分钟都在更新。例如,在该网页上现在有15个数据点。我解析了该网页的最后10个数据点,然后我将它们放入Python的列表中,然后执行以下步骤并在我的网页上制作图表。一分钟后,在数据源网页中,将有16个数据点可用,我需要获取最后10个数据点。在这种情况下,我需要再次运行python代码以获取最新的10个数据点,以使用它们在我的网页上制作图表。

所以,我需要始终运行整个python代码,这是整个Flask应用程序init.py文件并重新渲染我的网页以查看更新的图表。如果我不在我的服务器中重新运行init.py文件,那么即使在10分钟或2小时后,我也只会看到我第一次解析的数据。

我应该如何运行Flask并始终获取更新的数据,而不是每次都重新运行烧瓶init.py。

我考虑过使用time.sleep(60),以便每1分钟运行一次烧瓶app python文件。但是,当我的代码更多地考虑计算时,这确实需要很多时间。并没有真正的工作。

我该如何解决这个问题?

我应该使用time.sleep吗?或者是更好的方式?

2 个答案:

答案 0 :(得分:7)

这是一个经典的"推"更新问题。您的Web服务器会更新您希望经常更新(或#34;推送")到您的Web客户端前端的信息。

作为PJ Santoro suggests,您可以重复轮询您的服务器(每10秒钟一次)沿着"是否有新数据?不,好的有新数据吗?不,好的有新数据吗?是的,在这里!大!有新数据吗? ...."它效率很低,但对于低数据量,您可能永远不会看到这个问题。

更高效的更新系统将使服务器仅在新数据准备就绪时发送更新信号。有两种主要方法可以做到这一点:

  1. 长轮询,也称为反向AJAX Comet 。您的网页在服务器URL上打开一个AJAX请求,例如/update_data,其超时时间非常长(例如30分钟或一小时)。当服务器有数据时,它通过等待的AJAX连接发送它。这有很多复杂的问题,包括管理服务器端的并发性(不是历史上Python的强项)以及甚至最大超时(我使用这种技术的最后一小时)可能会在没有数据的情况下到期,并且会出现一些错误需要处理来管理它。如果你想尝试长轮询/反向AJAX,here is an example using Flask

  2. <强>的WebSockets 即可。 WebSockets是一种更新的交互式方法,并且推动了#34;服务器和客户端之间的更新它们使用得非常好;像Jupyter Notebook这样的项目广泛依赖于它们。它们非常高效且非常适合客户端状态的这种增量更新,并且代码通常比反向AJAX等改造更容易被拜占庭和混乱。但是...... WebSockets也存在复杂性。例如,在Flask服务器端管理并发性仍然是一个重要问题。如果您想将WebSockets视为更新机制,here is an example了解如何在Flask中使用它们。

  3. 您使用的任何一种方法,如果您的数据随着时间的推移而增长,您还需要构建每次更新时传输的数据,以便进行增量更新。无论管道有多好,如果每次更新都传输数千个数据点,它就不会很快。但是,长轮询和WebSockets管道应该至少可以让您与合法的实时更新功能保持一致。

答案 1 :(得分:1)

嗯......在一个理想的世界中,你会把它分成2个应用程序:

  • Scrape&amp;从网上解析数据(不需要暴露在网络上)

  • 通过网络应用向用户提供数据

您可以使用某种CI工具(例如Jenkins)监控外部数据并将其添加到数据库中,然后使用Flask应用程序向用户提供此预处理数据。

如果步骤1-6相对较快,您可以在Flask中设置XHR端点,然后使用setInterval() javascript函数在一定时间间隔内调用它以告知应用程序更新数据。 E.g:

setInterval(function() {
    var req = new XMLHttpRequest();
    req.open('GET', '/refresh_data?time=234', true);
    req.onreadystatechange = function(e) {
        if(req.readyState !== 4) {
            return;
        }
        if ([200, 304].indexOf(req.status) === -1) {
            console.warn('Error! XHR failed.');
        }
        else {
            data = JSON.parse(e.target.responseText);
            processData();
            updateChart();
        }
    };
    req.send();
}, 10000);  // time in milliseconds (e.g. every 10 seconds)

并有一个烧瓶终点,如:

@app.route('/refresh_data')
def refresh_data():
    time = requests.args.get('time', type=int)
    if not time:
        return jsonify({status: 'error: incorrect parameters'})
    data = requests.get('http://api.getmoredata.com?time=%s' % time)
    # process the results...
    return jsonify({status: 'success', data: data})

理想情况下,你有某种类型的图表,它有一个refresh()方法,你可以传递新数据并继续添加...(例如,我是D3的粉丝像这样)。

可能会从您的init.py代码中删除此内容,但对于&#34;首次加载&#34;可能是可以接受的。一个烧瓶应用程序(例如任何Web应用程序)响应HTTP请求,并且在请求之间服务器上没有任何内容持续存在,因此time.sleep()对您没有太大作用...如果您想在服务器上运行持久性代码,那么您需要; d需要查看类似celery的内容来管理后台任务。