【问题标题】:How to continuously display python output in a webpage?如何在网页中连续显示python输出?
【发布时间】:2013-02-09 02:24:30
【问题描述】:

我希望能够访问一个网页,它会运行一个 python 函数并在网页中显示进度。

因此,当您访问网页时,您可以看到脚本的输出,就像您从命令行运行它一样,并在命令行中看到输出。

我需要在函数中做什么?

我需要在模板中做什么?

编辑:

我正在尝试将 Markus Unterwaditzer 的代码与模板一起使用。

{% extends "base.html" %}
{% block content %}

{% autoescape false %}

{{word}}

{% endautoescape %}

{% endblock %}

Python 代码

import flask
from flask import render_template
import subprocess
import time

app = flask.Flask(__name__)

@app.route('/yield')
def index():
    def inner():
        for x in range(1000):
            yield '%s<br/>\n' % x
            time.sleep(1)
    return render_template('simple.html', word=inner())
    #return flask.Response(inner(), mimetype='text/html')  # text/html is required for most browsers to show the partial page immediately

app.run(debug=True, port=8080)

它运行了,但我在浏览器中看不到任何东西。

【问题讨论】:

  • 问题出在您的 subprocess.Popen 中,您将错误的参数 None 作为命令传递。尝试在交互式 shell 中使用 Popen 并阅读其文档以了解 Popen 的工作原理。

标签: python python-2.7 flask jinja2


【解决方案1】:

这是一个非常简单的应用程序,它使用普通 HTTP 流式传输进程的输出:

import flask
import time

app = flask.Flask(__name__)

@app.route('/yield')
def index():
    def inner():
        for x in range(100):
            time.sleep(1)
            yield '%s<br/>\n' % x
    return flask.Response(inner(), mimetype='text/html')  # text/html is required for most browsers to show the partial page immediately

app.run(debug=True)

【讨论】:

  • 如何使用python函数?
  • 这实际上可能不是最好的例子,因为它使用了太多与问题无关的代码。我已经更新了它。希望现在更清楚了。
  • 好吧,我添加了一个延迟,它不断输出到网页!伟大的!我正在尝试将其输出到使用与我网站其余部分相同样式的模板,但我什么也没看到。
  • 这很好,但是如何将这些消息集成到模板中?
  • 不需要输入文本/html。更多关于流上下文的信息可以在这里找到:flask.pocoo.org/docs/0.11/patterns/streaming
【解决方案2】:

我今天遇到了同样的问题,并找到了一种方法来调整 Markus Unterwaditzer 的答案以使用模板。

关键是用jinja的Template.generate(),而不是flask的render_template()使用的Template.render()

import flask
import time

from jinja2 import Environment
from jinja2.loaders import FileSystemLoader

app = flask.Flask(__name__)

@app.route('/yield')
def index():
    def inner():
        for x in range(100):
            time.sleep(1)
            yield '%s<br/>\n' % x
    env = Environment(loader=FileSystemLoader('templates'))
    tmpl = env.get_template('result.html')
    return flask.Response(tmpl.generate(result=inner()))

app.run(debug=True)

假设有一个模板result.html,看起来像这样:

{% extends "layout.html" %}
{% block body %}
<body>
  {% for line in result %}
    {{ line }}
  {% endfor %}
</body>
{% endblock %}

【讨论】:

  • 我可以为这篇文章投票 80 次吗?!我知道这是不鼓励的,但谢谢!
  • envtmpl 变量添加到我的代码给我jinja2.exceptions.UndefinedError: 'url_for' is undefined
【解决方案3】:

我认为最直接的方法是创建页面,然后使用 AJAX 定期向服务器发出请求,并使用结果更新页面上的内容。这可能包括实现 long polling 来执行此操作。

无论您采用何种方式,您都需要以某种方式使您的函数处于非阻塞状态,以便您在它运行时仍然可以为请求提供服务。如果有一个等待,您可以手动编写一个为请求提供服务的函数,否则继续运行该函数的下一个“块”。这将涉及将您的功能分解为小部分,以便您可以根据需要分派它们。

更好的方法可能是使用线程或多处理,具体取决于您的函数是否受 IO 或 CPU 使用率的限制。

【讨论】:

    【解决方案4】:

    你有使用 WebSocket 的计划吗?如果有,可以参考:Websocket with Flask and Gevent

    【讨论】:

      【解决方案5】:

      您可以在其中一个模板中使用元刷新

      元 http-equiv="刷新" 内容="5"

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-03-13
        • 2017-08-25
        • 2012-04-19
        • 2021-12-06
        • 1970-01-01
        • 2014-09-18
        相关资源
        最近更新 更多