How to continuously display Python output in a Webpage? How to continuously display Python output in a Webpage? flask flask

How to continuously display Python output in a Webpage?


Hi looks like you don't want to call a test function, but an actual command line process which provides output. Also create an iterable from proc.stdout.readline or something. Also you said from Python which I forgot to include that you should just pull any python code you want in a subprocess and put it in a separate file.

import flaskimport subprocessimport 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')


Here's a solution that allows you to stream the subprocess output & load it statically after the fact using the same template (assuming that your subprocess records it's own output to a file; if it doesn't, then recording the process output to a log file is left as an exercise for the reader)

from flask import Response, escapefrom yourapp import appfrom subprocess import Popen, PIPE, STDOUTSENTINEL = '------------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())

This way you get a consistent template used both during the initial running of the command (via POST) and during static serving of the saved logfile after the fact.