Comment afficher en continu la sortie Python sur une page web?

je veux être en mesure de visiter une page web et il va exécuter une fonction python et affiche la progression dans la page web.

Ainsi, lorsque vous visitez le site, vous pouvez voir la sortie du script que si vous avez exécuté depuis la ligne de commande.

basé sur la réponse ici

comment afficher en continu la sortie python sur une page web?

j'essaie d'afficher la sortie de PYTHON

j'essaie D'utiliser Markus Le code d'Unterwaditzer avec une fonction python.

import flask
import subprocess

app = flask.Flask(__name__)

def test():
    print "Test"

@app.route('/yield')
def index():
    def inner():
        proc = subprocess.Popen(
            test(),
            shell=True,
            stdout=subprocess.PIPE
        )

        while proc.poll() is None:
            yield proc.stdout.readline() + '<br/>n'
    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=5005)

Et il fonctionne, mais je ne vois rien dans le navigateur.

19
demandé sur Community 2013-02-26 19:30:08

2 réponses

Hi semble comme vous ne voulez pas appeler une fonction de test, mais un processus de ligne de commande réelle qui fournit la sortie. Créer aussi un itérable à partir de proc.la sortie standard stdout.readline ou quelque chose. Vous avez aussi dit de Python que j'ai oublié d'inclure que vous devriez simplement tirer n'importe quel code python que vous voulez dans un sous-processus et le mettre dans un fichier séparé.

import flask
import subprocess
import time          #You don't need this. Just included it so you can see the output stream.

app = flask.Flask(__name__)

@app.route('/yield')
def index():
    def inner():
        proc = subprocess.Popen(
            ['dmesg'],             #call something with a lot of output so we can see it
            shell=True,
            stdout=subprocess.PIPE
        )

        for line in iter(proc.stdout.readline,''):
            time.sleep(1)                           # Don't need this just shows the text streaming
            yield line.rstrip() + '<br/>\n'

    return flask.Response(inner(), mimetype='text/html')  # text/html is required for most browsers to show th$

app.run(debug=True, port=5000, host='0.0.0.0')
21
répondu Drew Larson 2013-03-12 06:04:05

Voici une solution qui vous permet de streamer la sortie du sous-processus et de la charger statiquement après le fait en utilisant le même modèle (en supposant que votre sous-processus enregistre sa propre sortie vers un fichier; si ce n'est pas le cas, alors enregistrer la sortie du processus dans un fichier journal est laissé comme un exercice pour le lecteur)

from flask import Response, escape
from yourapp import app
from subprocess import Popen, PIPE, STDOUT

SENTINEL = '------------SPLIT----------HERE---------'
VALID_ACTIONS = ('what', 'ever')

def logview(logdata):
    """Render the template used for viewing logs."""
    # Probably a lot of other parameters here; this is simplified
    return render_template('logview.html', logdata=logdata)

def stream(first, generator, last):
    """Preprocess output prior to streaming."""
    yield first
    for line in generator:
        yield escape(line.decode('utf-8'))  # Don't let subproc break our HTML
    yield last

@app.route('/subprocess/<action>', methods=['POST'])
def perform_action(action):
    """Call subprocess and stream output directly to clients."""
    if action not in VALID_ACTIONS:
        abort(400)
    first, _, last = logview(SENTINEL).partition(SENTINEL)
    path = '/path/to/your/script.py'
    proc = Popen((path,), stdout=PIPE, stderr=STDOUT)
    generator = stream(first, iter(proc.stdout.readline, b''), last)
    return Response(generator, mimetype='text/html')

@app.route('/subprocess/<action>', methods=['GET'])
def show_log(action):
    """Show one full log."""
    if action not in VALID_ACTIONS:
        abort(400)
    path = '/path/to/your/logfile'
    with open(path, encoding='utf-8') as data:
        return logview(logdata=data.read())

de cette façon, vous obtenez un modèle cohérent utilisé à la fois pendant l'exécution initiale de la commande (via POST) et pendant la portion statique du fichier journal enregistré après le fait.

1
répondu robru 2016-02-25 23:46:36