[PySide] PySide plus Django: How can I make the PySide application auto-start the server?

João Vale joao.vale at ndrive.com
Mon Sep 10 11:48:02 CEST 2012


Hm, it's possible that Popen is creating some sort of "shell" and only then
starting the Django server. In that case, it might be the case that the PID
you're getting is the server's parent PID. In which case you can probably
find it by looking for a process with that specific parent PID.

Cheers,
João



On Fri, Sep 7, 2012 at 6:20 PM, Zak <pyside at m.allo.ws> wrote:

>  Thanks for the suggestion. Although it seems like it should work, it
> does not, it returns the wrong PID. I tried it. In the following example,
> the correct PID to kill is '3', but subprocess.Popen.pid (a.k.a.
> server.pid) returns '2'. Here is a shortened example:
>
>
> import sys
> import subprocess
> from PySide.QtCore import *
> from PySide.QtGui import *
> from PySide.QtWebKit import *
>
> # Create a Qt application
> app = QApplication(sys.argv)
>
> pids = pm.get_python_pids()
> print "PID list 1:"
>
> print pids
> ## Assuming no other Python things are running,
> ## this prints a list of one PID, e.g. ['1']
>
> # Start the Django server
> server = subprocess.Popen(["python", manage_path, "runserver"])
>
> pids_1 = pm.get_python_pids()
> print "PID list 2:"
>
> print pids_1
> ## Prints a list of two PIDs, e.g. ['1', '2']
>
> # Enter Qt application main loop
> app.exec_()
>
> # If execution reaches this point, then the GUI window was closed
>
> # To kill the Django server, we must first figure out what
> # its Windows PID is
>
> pids_2 = pm.get_python_pids()
> print "PID list 3:"
>
> print pids_2
> ## Prints a list of three PIDs, e.g. ['1', '2', '3']
> ## The proper process to kill is whichever one is new in pids_2. That is to
> ## say, we should kill the process which is listed in pids_2 but is not
> ## present in pids_1. In this example, it would be PID '3'.
>
> ## Another idea to find the PID to kill:
> print "Server PID:"
> print server.pid
> ## This doesn't work. In the current example, this prints '2'.
> ## '2' is not the correct PID to kill, the correct PID
> ## is '3' in this example.
>
>
> # max_kill is the maximum number of processes named 'python.exe' to kill
> max_kill = 1
> for pid in pids_2:
>     if pid in pids_1:
>         continue
>     else:
>         subprocess.call(["taskkill", "/F", "/pid", pid])
>         max_kill -= 1
>     if max_kill == 0:
>         break
>
> # Now exit Python entirely
> sys.exit()
>
> Trying to kill the Django server in this way is equivalent to
> server.kill() or server.terminate() or server.send_signal(CTRL_C_EVENT).
> The problem with those three is the same: they send the signal to PID '2',
> which is simply not the PID of the Django server. It is the PID bound to
> the Popen instance, but that is not correct.
>
> Zak F.
>
>
> On 9/7/12 4:33 AM, João Vale wrote:
>
> Hi,
>
>  I think you're overcomplicating things when looking up Django's PID, the
> object returned by Popen already provides you that:
>
>  http://docs.python.org/library/subprocess.html#subprocess.Popen.pid
>
>  Cheers,
> João
>
>
>
> On Thu, Sep 6, 2012 at 6:18 PM, Zak <pyside at m.allo.ws> wrote:
>
>> To see my full solution, look at the code below. Here it is described in
>> English:
>>
>> Use the Windows command 'tasklist' to get a list of all running
>> processes. Unfortunately, several processes are named simply
>> 'python.exe', and I could not find a way to figure out which one
>> corresponded to manage.py. If you kill the wrong 'python.exe' process, a
>> process may essentially kill itself. If the process kills itself before
>> it kills manage.py, then manage.py will not be killed at all.
>>
>> To solve this problem, I ran 'tasklist' several times and kept track of
>> when new processes appeared and which PID they had. It turns out that
>> three 'python.exe' processes are created, and you need to kill the third
>> one.
>>
>> I eventually kill the process using 'taskkill /F /pid %s' % (pid_to_kill).
>>
>> Here is the code, simplified and merged into a single file:
>>
>> import re
>> import subprocess
>>
>> pyPat = re.compile("(?m)^python\.exe\s+(?P<pid>\d+)")
>> # pyPat matches if "python.exe" occurs at the start of a new line (not in
>> # the middle), followed by one or more spaces, followed by one or more
>> # digits. The digits are stored in the 'pid' group of the match object.
>>
>> def get_python_pids():
>>      tasklist = subprocess.check_output(["tasklist"])
>>      pids = []
>>      for mtch in pyPat.finditer(tasklist):
>>          pids.append(mtch.group('pid'))
>>      return pids
>>
>>
>> import sys
>> import subprocess
>> from PySide.QtCore import *
>> from PySide.QtGui import *
>> from PySide.QtWebKit import *
>>
>>
>> # Create a Qt application
>> app = QApplication(sys.argv)
>> # Create a browser window and show it
>> browser = QWebView(None)
>> browser.load(QUrl("http://127.0.0.1:8000/"))
>> browser.show()
>>
>> # pids = pm.get_python_pids()
>> # print "PID list 1:"
>> # print pids
>> ## Assuming no other Python things are running,
>> ## this prints a list of one PID, e.g. ['1']
>>
>> # Start the Django server
>> manage_path = local_settings.root_dir + 'manage.py'
>> server = subprocess.Popen(["python", manage_path, "runserver"])
>>
>> pids_1 = pm.get_python_pids()
>> # print "PID list 2:"
>> # print pids_1
>> ## Prints a list of two PIDs, e.g. ['1', '2']
>>
>> # Enter Qt application main loop
>> app.exec_()
>>
>> # If execution reaches this point, then the GUI window was closed
>>
>> # To kill the Django server, we must first figure out what
>> # its Windows PID is
>>
>> pids_2 = pm.get_python_pids()
>> # print "PID list 3:"
>> # print pids_2
>> ## Prints a list of three PIDs, e.g. ['1', '2', '3']
>> ## The proper process to kill is whichever one is new in pids_2. That is
>> to
>> ## say, we should kill the process which is listed in pids_2 but is not
>> ## present in pids_1. In this example, it would be PID '3'.
>>
>> # max_kill is the maximum number of processes named 'python.exe' to kill
>> max_kill = 1
>> for pid in pids_2:
>>      if pid in pids_1:
>>          continue
>>      else:
>>          subprocess.call(["taskkill", "/F", "/pid", pid])
>>          max_kill -= 1
>>      if max_kill == 0:
>>          break
>>
>> # Now exit Python entirely
>> sys.exit()
>>
>> Zak F.
>>  _______________________________________________
>> PySide mailing list
>> PySide at qt-project.org
>> http://lists.qt-project.org/mailman/listinfo/pyside
>>
>
>
>
> _______________________________________________
> PySide mailing list
> PySide at qt-project.org
> http://lists.qt-project.org/mailman/listinfo/pyside
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.qt-project.org/pipermail/pyside/attachments/20120910/b239d486/attachment.html>


More information about the PySide mailing list