I am running a Python script开发者_运维问答 on Apache 2.2 with mod wsgi.
Is it possible to run pdb.set_trace() in a python script using daemon mode in wsgi?
Edit The reason I want to use daemon mode instead of embedded mode is to have the capability to reload code without having to restart the Apache server every time (which embedded mode requires). I would like to be able to use code reloading without restarting Apache everytime and still be able to use pdb...
I had the same need to be able to use the amazingly powerful pdb
, dropping a pdb.set_trace()
wherever I wanted to debug some part of the Python server code.
Yes, Apache spawns the WSGI application in a place where it is out of your control [1]. But I found a good compromise is to
maintain your Apache
WSGIScriptAlias
and also give yourself the option of starting your Python server in a terminal as well (testing locally and not through Apache anymore in this case)
So if one uses WSGIScriptAlias
somewhat like this...
pointing to your python WSGI script called webserver.py
<VirtualHost *:443>
ServerName myawesomeserver
DocumentRoot /opt/local/apache2/htdocs
<Directory /opt/local/apache2/htdocs>
[...]
</Directory>
WSGIScriptAlias /myapp /opt/local/apache2/my_wsgi_scripts/webserver.py/
<Directory /opt/local/apache2/my_wsgi_scripts/>
[...]
</Directory>
[...]
SSLEngine on
[...]
</VirtualHost>
And so your webserver.py
can have a simple switch to go between being used by Apache and getting started up for debugging manually.
Keep a flag in your config file such as, in some settings.py
:
WEBPY_WSGI_IS_ON = True
And webserver.py
:
import web
import settings
urls = (
'/', 'excellentWebClass',
'/store', 'evenClassier',)
if settings.WEBPY_WSGI_IS_ON is True:
# MODE #1: Non-interactive web.py ; using WSGI
# So whenever true, the Web.py application here will talk wsgi.
application = web.application(urls, globals()).wsgifunc()
class excellentWebClass:
def GET(self, name):
# Drop a pdb wherever you want only if running manually from terminal.
pdb.set_trace()
try:
f = open (name)
return f.read()
except IOError:
print 'Error: No such file %s' % name
if __name__ == "__main__":
# MODE #2: Interactive web.py , for debugging.
# Here you call it directly.
app = web.application(urls, globals())
app.run()
So when you want to test out your webserver interactively, you just run it from a terminal,
$ python webserver.py 8080
starting web...
http://0.0.0.0:8080/
[1] Footnote: There are some really complex ways of getting Apache child processes under your control, but I think the above is much simpler if you just want to debug your Python server code. And if there are actually easy ways, then I would love to learn about those too.
精彩评论