Python: Realtime web print out

There are some situationĀ  when we run a time-consuming process, we need to see the output of that command to see its progress. Normally, we would have to wait until the process ends , then we can see the output. The reason for this is because web or standard output normally buffer some contents, it will wait for enough data to print out to the client. To fix this issue, we tell our server/script not buffering anything, print out immediately when it can. Here are some steps that i did in Python.

Step1: Tell the server not buffering anything, don’t use gzip ( if we use gzip, it will wait for the whole content) .

Add this to your .htaccess

<FilesMatch \.py$>
    SetEnv no-gzip 1
</FilesMatch>

Sometimes we also need to disable mod_deflate.

For our code, we need to flush the content to the client. Here is my code.

#!/usr/bin/python -u
#Turn on debug mode.
import cgitb
import os
import subprocess
import signal
import sys
#cgitb.enable()
def myrun(cmd):
    """from http://blog.kagesenshi.org/2008/02/teeing-python-subprocesspopen-output.html
    """
    p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    stdout = []
    print "Process ID:",p.pid
    
    while True:
        line = p.stdout.readline()
        stdout.append(line)
        print line,
        sys.stdout.flush()
        if line == '' and p.poll() != None:
            break
    return ''.join(stdout)

# Print necessary headers.
print("Content-Type: text/plain")
print ""
sys.stdout.flush()
#we must run this as some browser waits for some data before displaying
for x in range (0,1000):
    print " ", #remember the "," as it will not print new line
print "<pre>"
sys.stdout.flush()
cmd = "ping -c 20 www.google.com"
myrun(cmd)

We can archive similar in PHP.

Leave a Reply

Your email address will not be published. Required fields are marked *