Web.py

I've just prepared this step-by-step guide to get you going quickly with http://webpy.org/

= Setting up web.py =

CGI
Setting up CGI is the easiest thing to do, if you could make sure all the pieces are matched together correctly. In the example code, replace example.com with your domain name hosted at DreamHost. This might also be the best choice as DreamHost limits FCGI-processes to 100MB.

1. Beginning
Enter your home directory and create a new directory called py_libs: cd ~ mkdir py_libs

2. Install web.py and flups
Download web.py using wget then extract the archive: wget http://webpy.org/static/web.py-0.33.tar.gz tar -xf web.py-0.33.tar.gz

Now, move the web.py library into ~/py_libs: mv ~/web.py-0.33/web ~/py_libs/web

Get rid of the extraneous files: rm ~/web.py-0.33.tar.gz rm -r ~/web.py-0.33

Use wget to download fcgi.py and then move it into the py_libs directory: wget http://svn.saddi.com/py-lib/trunk/fcgi.py mv ~/fcgi.py ~/py_libs/fcgi.py

Modify web.py's wsgi.py file: nano ~/py_libs/web/wsgi.py

Replace the import and return value of the runfcgi method to use fcgi instead of flups: --- wsgi.py    (revision 130) +++ wsgi.py    (working copy) @@ -13,8 +13,8 @@ def runfcgi(func, addr=('localhost', 8000)): """Runs a WSGI function as a FastCGI server.""" -   import flup.server.fcgi as flups -   return flups.WSGIServer(func, multiplexed=True, bindAddress=addr).run +   import fcgi as flups +   return flups.WSGIServer(func, multiplexed=False, bindAddress=addr).run

3. Set up a web.py application
Enter your main web directory: cd ~/example.com

Create a new file called index.py in this directory and paste the following code into it, substituting your username for on line 3: import sys sys.path.append('/home/ /py_libs/')
 * 1) !/usr/bin/env python2.5

import web urls = ("/(.*)", "Hello") class Hello: def GET(self, path=None): return 'Hello, world!' app = web.application(urls, globals)

if __name__ == "__main__": app.run

Now make index.py executable, since it's a CGI script. chmod +x index.py

4. Serve it via Apache
Edit your main web directory's .htaccess file to enable CGI: nano ~/example.com/.htaccess

Assuming you want the root of your site to use web.py, add: Options +ExecCGI AddHandler cgi-script .py DirectoryIndex index.py/   RewriteEngine on   RewriteBase / RewriteCond %{REQUEST_URI} !^/favicon.ico$ RewriteCond %{REQUEST_URI} !^/static/(.*)$ RewriteCond %{REQUEST_URI} !^(/.*)+index.py/ RewriteRule ^(.*)$ /index.py/$1 [PT] 

If you would prefer a specific folder to use web.py, simply edit the RewriteBase line as follows: RewriteBase /path/to/webpy/folder/

The beginning and ending forward-slashes are important. Do not leave them out.

5. Check and trouble shooting
Launch Python and ensure that you can import web.py and fcgi: python >>> import web >>> import fcgi

If either import statement raises an error, go back to step 1 and make sure you modified your PYTHONPATH correctly and that everything is in its proper place (web.py and fcgi inside ~/py_libs).

Visit your domain and you should be able to see the welcome greeting. If you run into a 500 Internal Error, check the error log file at ~/logs/example.com/http/error.log

FCGI
See the instructions here: http://thefire.us/archives/261

I can't recommend developing on your Dreamhost shell as once the FastCGI processes are running, they're painful to kill and restart them. Develop locally with web.reloader so your changes are immediately reflected in your Web application.

Benchmarking
ab is from the apache2-utils Debian package.

/usr/sbin/ab -c 4 -n 300 http://todo.dabase.com/

4 concurrent connections pushing out 300 requests. If you find it too slow, considering running lighttpd on a dedicated server.

Restarting FASTCGI processes
You probably need to do this also for new code to take effect.

This sometimes works:

killall python2.4

Passenger
Before going further into this section, please read Passenger WSGI first. Here is a sample passenger_wsgi.py file:

import sys, os sys.path.append(os.getcwd) import web urls = ("/", "index") class index: def GET(self): web.header('Content-type', 'text/plain') return 'It works!' app = web.application(urls, globals, autoreload=False) application = app.wsgifunc

This is assuming that the "web" directory of web.py resides in the same directory as passenger_wsgi.py