A stream of streaming output from a Flask view works, but never ends

I want to stream a stream from multiple python3 scripts to my browser. I followed some suggestions from different SO answers and almost solved it. But my read cycle from stdout starts in an infinite loop after the script is executed. The result is correct and everything is in order, but an infinite loop is a problem. How can I end the stream after the output is complete?

@app.route('/stream/<script>')
def execute(script):
    def inner():
        assert re.match(r'^[a-zA-Z._-]+$', script)
        exec_path = "scripts/" + script + ".py"
        cmd = ["python3", "-u", exec_path]  # -u: don't buffer output

        proc = subprocess.Popen(
            cmd,
            stdout=subprocess.PIPE,
        )

        for line in iter(proc.stdout.readline, ''):
            yield highlight(line, BashLexer(), HtmlFormatter())
            # If process is done, break loop
   #         if proc.poll() == 0:
   #             break

    env = Environment(loader=FileSystemLoader('app/templates'))
    tmpl = env.get_template('stream.html')
    return Response(tmpl.generate(result=inner()))

When I poll the subprocess to see if this has ended, the script output is broken because it does not print the entire stdout stream when the prints go too fast. If I add sleep(1)between each print, the problem does not occur.

, . , - , . if not running: break, , .

+4
1

iter(proc.stdout.readline, '') readline, - ''. proc.stdout.readline bytes , '' - str, !

for line in iter(proc.stdout.readline, b''):

:

for line in proc.stdout:
+2

Source: https://habr.com/ru/post/1606831/


All Articles