How to spawn Python2.5 process through Apache and return immediately under Windows
Question: I have two Python scripts, one launches the other with subprocess

invoke.py:

    
    
    import subprocess
    p = subprocess.Popen(['python', 'long.py'])
    print "Content-Type: text/plain\n"
    print "invoked (%d)" % (p.pid)
    

longtime.py:

    
    
    import time
    import os
    print "start (%d)" %(os.getpid())
    time.sleep(10)
    print "end (%d)" %(os.getpid())
    

When I execute invoke.py from shell it returns immediately and longtime.py
works in background (works on Windows and Linux). If I call invoke.py through
Web Interface (Apache CGI) it works under Linux **but not on Windows**
machine, there the website gets stuck and only returns after longtime.py has
finished.

How can I configure Python subprocess or Apache to get the same behavior under
Windows? Whats the difference?

Maybe the Apache config on Windows is somehow different but i didnt find
something.

Linux: Debian, Python2.5.2, Apache2.2.9  
Windows: WinXP, Python2.7, Apache2.2.17

Maybe you have also a better design approach (because its a little awkward how
I do it now).

What for?: I have a script on the webserver which takes quite a long time to
calculate (longtime.py). I want to activate the execution via web interface.
The Website should return immediatly and longtime.py should work in background
and writes output in a file. Later a request from web interface checks if the
file is generated and reads the output. I can not use common cloud-provider as
they dont support multithreading. Also I can not install a daemon handler on
the webserver because processes have a maximum runtime.


Answer: I've tested the code below on Windows XP and on OSX 10.6.6 (shell) and it
exits without waiting for the child process to finish.

**invoke.py:**

    
    
    from subprocess import Popen, PIPE
    import platform
    
    
    if platform.system() == 'Windows':
        close_fds=False
    else: 
        close_fds=True
    
    p = Popen('python long.py', stdin=PIPE, stdout=PIPE, stderr=PIPE, close_fds=close_fds, shell=True)
    print "Content-Type: text/plain\n"
    print "invoked (%d)" % (p.pid)
    

**long.py**

    
    
    import time
    import os
    print "start (%d)" %(os.getpid())
    time.sleep(10)
    print "end (%d)" %(os.getpid())
    

**Update:** Tested on Windows 7 + Apache 2.2.17 + Python 2.7 + mod_wsgi 3.3.

mod_wsgi.so file can be downloaded from
[here](http://code.google.com/p/modwsgi/wiki/DownloadTheSoftware?tm=2). File
should be renamed to mod_wsgi.so and and placed in apache modules folder.

**invoke.wsgi:** from subprocess import Popen, PIPE import platform

    
    
    def application(environ, start_response):
        if platform.system() == 'Windows':
            close_fds=False
        else: 
            close_fds=True
    
        p = Popen('python "C:\testing\long.py"', stdin=PIPE, stdout=PIPE, stderr=PIPE, close_fds=close_fds, shell=True)
    
        status = '200 OK'
        output = "invoked (%d)" % (p.pid)    
        response_headers = [('Content-type', 'text/plain'), ('Content-Length', str(len(output)))]
        start_response(status, response_headers)
    
        return [output]
    

**long.py** file was left unchanged.

changes made to **httpd.conf** :

append wsgi module:

    
    
    LoadModule wsgi_module modules/mod_wsgi.so
    

add directory to the config

    
    
    <Directory "C:/testing">
        AllowOverride None
        Options None
        Order allow,deny
        Allow from all
    </Directory>
    

link url with directory

    
    
    Alias /testapp "C:\testing"
    

link url with wsgi app

    
    
    WSGIScriptAlias /testapp "C:\testing\invoke.wsgi"
    

Restart web server. Go <http://server_name/testapp> App should show process id
and exit.

