[PYTHON] In Django, display batch (command) results sequentially in HTML

(It feels like output_buffering is turned off in PHP)

Use StreamingHttpResponse.

Since the first argument of StreamingHttpResponse is a generator, write the batch with the generator.

In this example, a shell command is used as a generator.

import subprocess

from django.http import StreamingHttpResponse
from django.utils.encoding import smart_str
from django.utils.html import escape
from django.views import View


def run_process_as_generator(*args, **kwargs):
    """
Return subprocess result with generator
    :rtype: generator
    """
    kwargs.setdefault('stdout', subprocess.PIPE)
    kwargs.setdefault('stderr', subprocess.STDOUT)

    popen = subprocess.Popen(*args, **kwargs)

    while True:
        line = popen.stdout.readline()
        if line:
            yield line

        if not line and popen.poll() is not None:
            break


def linebreaksbr(gen):
    """
On each line of the generator<br />Put on
Smart just in case_str
    :type gen: generator
    :rtype: generator
    """
    for line in gen:
        yield '{}<br />\n'.format(escape(smart_str(line)))


def task():
    """
Run batch
    :rtype: generator
    """
    return linebreaksbr(
        run_process_as_generator(
            "for i in {1..10}; do sleep 1s; echo ${i}; done",
            shell=True
        ))


class SlowCommandView(View):
    """
    task()A view that returns the results of
    """
    def get(self, request, *args, **kwargs):
        response = StreamingHttpResponse(
            task(),
            content_type="text/html; charset=utf-8")

        return response

If you're writing batches in Python, it's a good idea to use yield instead of printing logs in print.

def task():
    yield 'start'
    ...
    yield 'phase-1'
    ...
    for xx in xxx:
         yield xx
    yield 'end'

reference: Get standard output in real time with Python subprocess-Qiita

Request and response objects | Django documentation | Django

Recommended Posts

In Django, display batch (command) results sequentially in HTML
Display HTML in Jupyter notebook
Django ~ Let's display it in the browser ~
Receive and display HTML form data in Python
Display error message when login fails in Django
Django HTML Template # 2
Models in Django
Django HTML template
Django + Docker command
Forms in Django