Running pdb in daemon mode with WSGI - python

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.

Related

OSError: [Errno 98] Address already in use Running Flask Application on Apache2

I have my flask code in app.py
/some code//
if __name__ == '__main__':
app.run()
and i have set up my wsgi file as in the path /var/www/AutomateTests
#!/usr/bin/python3.6
import sys
import logging
sys.path.insert(0,"/var/www/AutomateTests/")
from app import app as application
application.root_path = '/var/www/AutomateTests/'
and I have /etc/apache2/sites-available/automate_tests.conf
VirtualHost *:80>
ServerName htstool.arubanetworks.com
ServerAdmin admin#htstool.arubanetworks.com
ServerAlias htstool.arubanetworks.com
ErrorLog /var/log/apache2/hts-error.log
CustomLog /var/log/apache2/htstool-access.log combined
WSGIDaemonProcess AutomateTests user=www-data group=www-data threads=5
WSGIScriptAlias / /var/www/AutomateTests/automate_tests.wsgi
<Directory /var/www/AutomateTests>
WSGIProcessGroup AutomateTests
WSGIApplicationGroup %{GLOBAL}
Order allow,deny
Allow from all
</Directory>
LogLevel info
</VirtualHost>
I have set up everything rightly and i have been stuck on this problem for weeks now. Can someplease help me on how to bring it up on the server. Is there a step i am missing.
im setting the same error of my port is in use although ITS NOT!
See the picture of my error
enter image description here
But as you can see my ports are empty and not being used. I check that using the command netstat -ntlp
see my ports are listening and not established
Can someone please please help me. I am stuck and don't mark it as already answered before checking it completely. I have tried all the answers and they don't work! Please be patient and let others help me because I can't do it myself.
My server is running fine and I'm seeing the default ubuntu page which means that my apache2 server is working fine so there is something wrong with either the configuration or my ports
Two things come to mind when I see this.
Do you have Apache installed and running on the server? Apache may be listening on port 80 and preventing your Python script from binding to that port, but the way you ran netcat won't show this. You can check this at [sever_ip]:80.
But as you can see my ports are empty and not being used. I check that using the command netstat -ntlp
Note the first line of output from that command: (Not all processes could be identified, non-owned process info will not be shown, you would have to be root to see it all.) Apache runs with elevated privileges, so you'll need to run as root (append sudo to the beginning of your command) to see its port binding. I'd bet that this is the issue. Once this is fixed, you may run in to the following issue:
Are you running the script as root? On Linux, you need to use sudo to bind to ports 0 through 1024 (as explained here).
One more thing, not related to the script specifically, but it looks like you're using AWS EC2 in the screenshots (correct me if I'm wrong). If you want to be able to reach the instance on port 80 from the public internet, you'll need to make sure you allow it in the Security Group. I know this can cause some confusion for people using AWS EC2 for the first time, sure did for me.
Hope this helps!

Error 404 when trying to set up a Bottle-powered web app on Apache/mod_wsgi

I am a beginner programmer. I started using Python and Bottle for a small web app to print a form, so far so good. The real issue is configuring Apache and mod_wsgi, as my knowledge is almost none.
My problem: I keep getting this error:
Error 404: Not Found
Sorry, the requested URL /factura/ caused an error: Not found
In work they gave me and address redirecting to a IP:port; after some days of reading Apache docs and looking examples through the web I managed to set up the configuration so my VirtualHost doesn't breaks the others virtualhosts already running. The config looks like this (based on the bottle tutorial deployment section):
Listen port
NameVirtualHost IP:port
<VirtualHost IP:port>
ServerName IP:port
WSGIDaemonProcess factura processes=1 threads=5
WSGIScriptAlias / /var/www/factura/app.wsgi
<Directory /var/www/factura>
WSGIProcessGroup factura
WSGIApplicationGroup %{GLOBAL}
Order deny,allow
Allow from all
</Directory>
</VirtualHost>
My app.wsgi is almost the same as the one in the Bottle tutorial-deployment section. I only added the line sys.stdout = sys.stderr:
import sys, os, bottle
# Change working directory so relative paths (and template lookup) work again
sys.path = ['/var/www/factura'] + sys.path
os.chdir(os.path.dirname(__file__))
# Error output redirect
# Exception KeyError in 'threading' module
sys.stdout = sys.stderr
import factura
application = bottle.default_app()
Here is a bit of the python code which is related to Bottle:
from lib import bottle
app = bottle.Bottle()
#serves files in folder 'static'
#app.route('/static/:path#.+#', name='static')
def ...
#app.route("/factura")
#bottle.view("factura")
def ...
#app.route("/print_factura", method="POST")
def ...
I have read some of the others question similar to this, but I can't manage to see what I'mm missing. I suppose the problem is in app.wsgi?
UPDATE
file structure
/var/www/factura/ ## .py files
/views ## here is the web template
/static ## .css and .js of template
/lib ## package with bottle and peewee source files
/data ## inkscape file to play with
/bin ## backup stuff in repo, not used in code
Apache error log only shows
Exception KeyError: KeyError(-1211426160,) in <module 'threading' from '/usr/lib/python2.6/threading.pyc'> ignored
that is a warning from wsgi/python issues, harmless by wsgi issue 197
UPDATE 2 working
added #app.route("/factura/") notice the trail slash, that with the change in app import from factura import app as application those two together made it work
If you create your application explicitly:
app = bottle.Bottle()
then you should import it in your app.wsgi instead of application = bottle.default_app():
from factura import app as application
But what is far important is this. In your WSGI file, you do import bottle, yet in the app code file, you do from lib import bottle. As you have explained, you have two copies of Bottle: one installed server-wide, another under the lib directory.
That's why you were receiving 404 Not Found. You were actually working with one instance of the library (creating app), and then giving Apache a different (default_app) from a different instance of the library!
It started to work okay when you began to return the proper app.

How deploy Flask application on Webfaction?

Anybody know how to deploy a simple Flask application on Webfaction?
I know Webfaction support mod_wsgi and I read the guide on the Flask site but still I can't make my app working. Anybody have a working configuration?
UPDATE to answer a comment by Graham Dumpleton.
I get a 500 Internal server error. Apache does not show any error in the logs. The WSGI script is executed and seems to create the application correctly, but I keep getting a 500 error.
Thanks.
I got it working with the following procedure:
create and app named 'myapp' of type mod_wsgi 3.3/Python 2.7. Webfaction will create the following folders:
myapp
|- apache2
|- htdocs
Webfaction will also automatically create a simple script index.py in your htdocs directory. Check if the sample script work visiting the root of your newly created application (to do thin on Webfaction you need to "mount" the app on a website). If it's all OK modify the script deleting the content and adding:
from myapp import app as application
In apache2/conf/httpd.conf add the follwing lines:
WSGIPythonPath /home/username/webapps/myapp/htdocs/
#If you do not specify the next directive the app *will* work but you will
#see index.py in the path of all subdir
WSGIScriptAlias / /home/username/webapps/myapp/htdocs/index.py
<Directory /home/username/webapps/myapp/htdocs>
AddHandler wsgi-script .py
RewriteEngine on
RewriteBase /
WSGIScriptReloading On
</Directory>
Restart apache2
You need to set up a "Custom app (listening on port)" application. Make a note of the port that is assigned. Then in your Flask code, you need to put hardcode the port:
if __name__ == __main__:
app.run(host='0.0.0.0' port=XXXXXXX)
Where you substitute XXXXXXX with the port that is randomly assigned to your custom app.
Hope that helps.
EDIT:
Please use Raben's Answer, this way should not to be used in Production.

Mod_python produces no output

Just installed and configured mod_python 3.2.8 on a CentOS 5 (Apache 2.2.3) server with Python 2.4.3. It is loaded fine by Apache.
I activated the mpinfo test page and it works. So I wrote a simple "Hello World" with the following code:
from mod_python import apache
def handler(req):
req.content_type = 'text/plain'
req.write("Hello World!")
req.flush()
return apache.OK
It outputs a blank page, with no text and no source. If I consciously create a syntax error I get the error output on the URL, for example (when I put a space before "def"):
Mod_python error: "PythonHandler mod_python.cgihandler"
Traceback (most recent call last):
File "/usr/lib/python2.4/site-packages/mod_python/apache.py", line 299, in HandlerDispatch
result = object(req)
File "/usr/lib/python2.4/site-packages/mod_python/cgihandler.py", line 96, in handler
imp.load_module(module_name, fd, path, desc)
File "/var/www/vhosts/localhost/httpdocs/mptest.py", line 3
def handler(req):
^
SyntaxError: invalid syntax
I have spent about five hours browsing different tutorials, faqs and trouble shooting guides but can't find a description of this exakt issue.
What do you think could be the issue/cause?
EDIT: Here is the Apache configuration for the site...
<Directory />
Options FollowSymLinks
AllowOverride None
AddHandler mod_python .py
PythonHandler mptest
PythonDebug On
</Directory>
EDIT 2: Ah, another thing I forgot to mention is that I intend to use mod_python to write Apache extensions. The application itself is written in PHP but I need to make some security tweeks on the server :)
Don't use mod_python.
A common mistake is to take mod_python as "mod_php, but for python" and that is not true. mod_python is more suited to writing apache extensions, not web applications.
The standartized protocol to use between python web applications and web servers (not only apache) is WSGI. Using it ensures that you can publish your application to any wsgi-compliant webserver (almost all modern web servers are wsgi-compliant)
On apache, use mod_wsgi instead.
Your example rewritten using the wsgi standard and mod_wsgi on apache:
mywebapp.py:
def application(environ, start_response):
start_response('200 OK', [('content-type', 'text/plain')])
return ['Hello World']
Apache configuration:
WSGIScriptAlias /myapp /usr/local/www/wsgi-scripts/mywebapp.py
<Directory /usr/local/www/wsgi-scripts>
Order allow,deny
Allow from all
</Directory>
Now just go to http://localhost/myapp and the script will run. Additionally, any access under this root (i.e. http://localhost/myapp/stuff/here) will be handled by this script.
It's a good idea to choose a web framework. CherryPy. Pylons. Django. They make things even easier.
A good website to look at is wsgi.org
Your original problem is that mod_python.cgihandler is being called to handle the request. This means your Python script file is being interpreted as a CGI script. Thus, no wonder it doesn't return anything.
You likely have conflicting definition in your Apache configuration which is enabling the mod_python.cgihandler.
I make a complete new answer for clarity...
I decided to install mod_wsgi instead. So I've set it up and when I go to my testfile I just see the page source. I haven't been spending any time on finding the issue yet, so I'll get back to you when I either solve the problem or decide that I need more help :)
Thank you :)

mod_wsgi force reload modules

Is there a way to have mod_wsgi reload all modules (maybe in a particular directory) on each load?
While working on the code, it's very annoying to restart apache every time something is changed. The only option I've found so far is to put modname = reload(modname) below every import.. but that's also really annoying since it means I'm going to have to go through and remove them all at a later date..
The link:
http://code.google.com/p/modwsgi/wiki/ReloadingSourceCode
should be emphasised. It also should be emphaised that on UNIX systems daemon mode of mod_wsgi must be used and you must implement the code monitor described in the documentation. The whole process reloading option will not work for embedded mode of mod_wsgi on UNIX systems. Even though on Windows systems the only option is embedded mode, it is possible through a bit of trickery to do the same thing by triggering an internal restart of Apache from the code monitoring script. This is also described in the documentation.
The following solution is aimed at Linux users only, and has been tested to work under Ubuntu Server 12.04.1
To run WSGI under daemon mode, you need to specify WSGIProcessGroup and WSGIDaemonProcess directives in your Apache configuration file, for example
WSGIProcessGroup my_wsgi_process
WSGIDaemonProcess my_wsgi_process threads=15
More details are available in http://code.google.com/p/modwsgi/wiki/ConfigurationDirectives
An added bonus is extra stability if you are running multiple WSGI sites under the same server, potentially with VirtualHost directives. Without using daemon processes, I found two Django sites conflicting with each other and turning up 500 Internal Server Error's alternatively.
At this point, your server is in fact already monitoring your WSGI site for changes, though it only watches the file you specified using WSGIScriptAlias, like
WSGIScriptAlias / /var/www/my_django_site/my_django_site/wsgi.py
This means that you can force the WSGI daemon process to reload by changing the WSGI script. Of course, you don't have to change its contents, but rather,
$ touch /var/www/my_django_site/my_django_site/wsgi.py
would do the trick.
By utilizing the method above, you can automatically reload a WSGI site in production environment without restarting/reloading the entire Apache server, or modifying your WSGI script to do production-unsafe code change monitoring.
This is particularly useful when you have automated deploy scripts, and don't want to restart the Apache server on deployment.
During development, you may use a filesystem changes watcher to invoke touch wsgi.py every time a module under your site changes, for example, pywatch
The mod_wsgi documentation on code reloading is your best bet for an answer.
I know it's an old thread but this might help someone. To kill your process when any file in a certain directory is written to, you can use something like this:
monitor.py
import os, sys, time, signal, threading, atexit
import inotify.adapters
def _monitor(path):
i = inotify.adapters.InotifyTree(path)
print "monitoring", path
while 1:
for event in i.event_gen():
if event is not None:
(header, type_names, watch_path, filename) = event
if 'IN_CLOSE_WRITE' in type_names:
prefix = 'monitor (pid=%d):' % os.getpid()
print "%s %s/%s changed," % (prefix, path, filename), 'restarting!'
os.kill(os.getpid(), signal.SIGKILL)
def start(path):
t = threading.Thread(target = _monitor, args = (path,))
t.setDaemon(True)
t.start()
print 'Started change monitor. (pid=%d)' % os.getpid()
In your server startup, call it like:
server.py
import monitor
monitor.start(<directory which contains your wsgi files>)
if your main server file is in the directory which contains all your files, you can go like:
monitor.start(os.path.dirname(__file__))
Adding other folders is left as an exercise...
You'll need to 'pip install inotify'
This was cribbed from the code here: https://code.google.com/archive/p/modwsgi/wikis/ReloadingSourceCode.wiki#Restarting_Daemon_Processes
This is an answer to my duplicate question here: WSGI process reload modules

Categories