Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Sure.</p> <p>There's traditional server-driven approach, where the script runs just once, but takes a long time to complete, spitting out bits of page as it goes:</p> <pre><code>import sys, time sys.stdout.write('Content-Type: text/html;charset=utf-8\r\n\r\n') print '&lt;html&gt;&lt;body&gt;' for i in range(10): print '&lt;div&gt;%i&lt;/div&gt;'%i sys.stdout.flush() time.sleep(1) </code></pre> <p>When writing an app to WSGI, this is done by having the application return an iterable which outputs each block it wants sent separately one at a time. I'd really recommend writing to WSGI; you can deploy it through CGI now, but in the future when your app needs better performance you can deploy it through a faster server/interface without having to rewrite.</p> <p>WSGI-over-CGI example:</p> <pre><code>import time, wsgiref.handlers class MyApplication(object): def __call__(self, environ, start_response): start_response('200 OK', [('Content-Type', 'text/html;charset=utf-8')]) return self.page() def page(self): yield '&lt;html&gt;&lt;body&gt;' for i in range(10): yield '&lt;div&gt;%i&lt;/div&gt;'%i time.sleep(1) application= MyApplication() if __name__=='__main__': wsgiref.handlers.CGIHandler().run(application) </code></pre> <p>Note that your web server may foil this approach (for CGI <em>or</em> WSGI) by adding buffering of its own. This typically happens if you're using output-transforming filters like <code>mod_deflate</code> to automatically compress webapp output. You'll need to turn compression off for partial-response-generating scripts.</p> <p>This limits you to rendering the page bit-by-bit as new data comes in. You can make it prettier by having the client-side take care of altering the page as new data comes in, eg.:</p> <pre><code>def page(self): yield ( '&lt;html&gt;&lt;body&gt;&lt;div id="counter"&gt;-&lt;/div&gt;' '&lt;script type="text/javascript"&gt;' ' function update(n) {' ' document.getElementById("counter").firstChild.data= n;' ' }' '&lt;/script&gt;' ) for i in range(10): yield '&lt;script type="text/javascript"&gt;update(%i);&lt;/script&gt;'%i time.sleep(1) </code></pre> <p>This relies on client-side scripting so it might be a good idea to include backup non-script-based final output at the end.</p> <p>All the while doing this, the page will appear to be still loading. If you don't want that, then you'd need to split the script into a first request that just spits out the static content, including client-side script that checks back with the server using either one XMLHttpRequest that it polls for new data through, or, for the really long-running cases, many XMLHttpRequests each of which returns the status and any new data. This approach is much more complicated as it means you have to run your work process as a background daemon process apart from the web server, and pass data between the daemon and the front-end CGI/WSGI request using eg. pipes or a database.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload