【问题标题】:How to stream (yield) text data to jinja2 template for a flask app on pythonanywhere如何将文本数据流式传输(生成)到 pythonanywhere 上的烧瓶应用程序的 jinja2 模板
【发布时间】:2015-07-24 12:00:02
【问题描述】:

我尝试在我的 Pythonanywhere 帐户上实现“流式传输内容”。

看起来或多或少与那里显示的内容相似: 参看。 http://flask.pocoo.org/docs/0.10/patterns/streaming/

除了我的视图正在计算一个可能一分钟的复杂过程并将其数据生成到我的模板中,其中一个脚本应该更新一些进度条(''source.onmessage'')。

这在我的开发机器上完美运行,但不适用于我的 pythonanywhere 帐户。在这台服务器上,进程看起来很卡(进度条永远不会更新,除非在最后突然从 0% 增长到 100%),尽管一切都在后台运行良好,eg my @ 987654322@ 语句正确呈现到我的服务器日志中)。

在上面引用的sn-p中,有一个注解:

请注意,尽管某些 WSGI 中间件可能会中断流式传输,但请注意 在带有探查器和其他东西的调试环境中小心 你可能已经启用了。

可能是这里的问题吗?是否有解决方法?

我的 jinja2 模板中的 JS 代码:

    <script type="text/javascript">
    /* progress bar */
    var source = new EventSource("{{ url_for('BP.run', mylongprocess_id=mylongprocess_id) }}");
    source.onmessage = function(event) {
        console.log(event.data);
        var data = event.data.split("!!");
        var nodeid = data[0];
        var process = data[1];
        var process_status = data[2];
        var postpro = data[3];
        var postpro_status = data[4];
        $('.pb1').css('width', process+'%').attr('aria-valuenow', process);   
        $('.pb2').css('width', postpro+'%').attr('aria-valuenow', process);   
        document.getElementById("process_status").innerHTML = process_status;
        document.getElementById("postpro_status").innerHTML = postpro_status;
        document.getElementById("nodeid").innerHTML = nodeid;
        if (postpro >= 100) {
            setTimeout(function() {
                console.log("progress is finished!");
                document.getElementById("status").innerHTML = "redirecting to {{url_for('.view_sonix_result', mylongprocess_id=mylongprocess_id)}}";
                window.location.replace("{{url_for('.terminate_analysis', mylongprocess_id=mylongprocess_id)}}");
                                  }, 2); // / setTimeout function
            } // /if
        else {
            document.getElementById("status").innerHTML = "pending...";
            } // /else
        } // /function
</script>

我的(简化的)观点:

@BP.route('/run/<int:mylongprocess_id>')
@login_required
def run(mylongprocess_id):
    mylongprocess = mylongprocess.query.get_or_404(mylongprocess_id)
    project = Project.query.get_or_404(mylongprocess.project_id)
    check_rights(current_user, project, 'user', 404)
    A, lcs = _create_analysis(mylongprocess)
    @copy_current_request_context
    def gen(mylongprocess, nodeid, store_path):
        print('now runing %s' % A)
        for (loopnb, total_loops, pct, lclabel) in A.runiterator(lcs):
            print('ran %d/%d (%.1f%%) "%s"' % (loopnb, total_loops,
                                               pct, lclabel))
            progress = ('data: %s!!%f!!%s!!%f!!%s\n\n' %
                        (nodeid, pct, lclabel, 0, 'waiting...'))
            yield progress
        print('now postprocessing %s' % A)
        postpro = load_node(store_path, node_id=nodeid)
        for step, total, pct, action in postpro._builditer(target='web',
                                                       buildfile=None):
            progress = ('data: %s!!%f!!%s!!%f!!%s\n\n' %
                        (nodeid, 100, 'ok',  pct, action.replace('_', ' ')))
            yield progress
        print('now terminating %s' % A)
        _terminate_analysis(A, mylongprocess)

    return Response(gen(mylongprocess, mylongprocess.nodeid), mimetype='text/event-stream')

【问题讨论】:

    标签: flask wsgi pythonanywhere


    【解决方案1】:

    当您的流量托管在 PythonAnywhere 上时,您的流量会通过 nginx 代理,除非另有说明,否则 nginx 会缓冲响应。

    为了让所有东西都冲洗干净,

    1. 给你的烧瓶响应标题response.headers['X-Accel-Buffering'] = 'no'
    2. 在要生成的字符串末尾有一个'\n',因为 python 也会缓冲到行尾。

    【讨论】:

      猜你喜欢
      • 2017-05-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-26
      • 1970-01-01
      相关资源
      最近更新 更多