Python FastCGI

From DreamHost
Jump to: navigation, search

Bootstrap

The following is a quick procedure for establishing a sanity-test FCGI application running Python.

  1. On the panel configure your site for "Fast CGI Support?" found under (Domains->Manage Domains)->(yourdomain.com->Edit)->PHP Support
  2. Download the Allan Saddi's fcgi.py, placing it somewhere in your PYTHONPATH
  3. Create your default page handler, dispatch.fcgi (You must use dispatch.fcgi or you will find that the process is killed in the middle of execution. This is explained here) You will need #!/home/username/bin/python not #!/usr/bin/env python for use with Pylons
    #!/usr/bin/env python
    
    def myapp(environ, start_response):
        start_response('200 OK', [('Content-Type', 'text/plain')])
        return ['Hello World!\n']
    
    if __name__ == '__main__':
        from fcgi import WSGIServer
        WSGIServer(myapp).run()
    
  4. Make dispatch.fcgi executable. Be sure that it is not group-writable, or you may get a 500 Internal Error.
    chmod 755 dispatch.fcgi
    
  5. Create an .htaccess file to point to redirect all requests to this script
    RewriteEngine On
    RewriteBase /
    RewriteRule ^dispatch\.fcgi/ - [L]
    RewriteRule ^(.*)$ dispatch.fcgi/$1 [L]
    
  6. Wait for the magical dreamhost refresh daemon to notice all your updates (try 'touch dispatch.fcgi')
  7. Load the page

Quirks

I had a few problems getting FCGI and Python to work together, so here's what I did.

I downloaded Virtual Python...

wget http://peak.telecommunity.com/dist/virtual-python.py
NB: virtualenv is preferred to virtual-python - it automates a lot of this process. See Python#Virtualenv for details.

then I created a directory called "packages" to install things into.

mkdir ~/packages

Next I added the folowing code to my ~/.bashrc and ~/.bash_profile:

export PYTHONPATH="$HOME/packages/lib/python2.3/site-packages"
export LD_LIBRARY_PATH="$HOME/packages/lib"
export PATH="$HOME/packages/bin:$PATH"

I then ran virtual python's installer and told it to install into "packages" rather than my home directory.

python virtual-python.py --prefix packages/

Optional: To install easy_install I ran:

wget http://peak.telecommunity.com/dist/ez_setup.py
python ez_setup.py

Lastly, I downloaded Allan Saddi's fcgi.py and placed it in ~/packages/lib/python2.3/site-packages. You can alternately use Flup, as shown below.

Warning: fcgi.py serves full Python Tracebacks in HTML by default, which is a security issue. You must override the [WSGI]Server.error() method.

To test my virtual python and fcgi installation I loosely followed some instructions from Django: I saved the following code in a file called dispatch.fcgi on ~/yourdomain.com

#!/home/my-username/packages/bin/python
from fcgi import WSGIServer
def test_app(environ, start_response):
    start_response('200 OK', [('Content-Type', 'text/plain')])
    yield 'Hello, world!\n'

WSGIServer(test_app).run()

Then I made it executable and created a .htaccess file in the same directory as dispatch.fcgi:

chmod a+x ~/yourdomain.com/dispatch.fcgi

.htaccess

RewriteEngine On
RewriteBase /
RewriteRule ^dispatch\.fcgi/ - [L]
RewriteRule ^(.*)$ dispatch.fcgi/$1 [L]

Finally, I waited a few minutes, and tried http://www.mydomain.com/dispatch.fcgi and it worked! --CPUFreak91

Using Flup

As an alternate to using fcgi.py, you can rely on Flup to use FastCGI on DreamHost. If you choose to do so (and this was the only way Python worked for me), you don't need to download or install fcgi.py. Simply install Flup with easy_install.

easy_install Flup

If you are planning on using a locally installed version of Python 3, then use the version of Flup that is compatible with Python 3. Simply use Mercurial to fetch the source.

hg clone http://hg.saddi.com/flup-py3.0
cd flup-py3.0
# make sure setup.py is executed by your local version of Python
python setup.py install

I also found that you need to add import sys to your dispatch file. You new dispatch.fcgi file should look like below

#!/home/my-username/packages/bin/python

import sys

from flup.server.fcgi_fork import WSGIServer

def test_app(environ, start_response):
    start_response('200 OK', [('Content-Type', 'text/plain')])
    yield 'Hello, world!\n'

WSGIServer(test_app).run()

No changes are required to your .htaccess file or anything else. Once your Hello World works, you're ready to start using Python. Simply install what you need via easy_install and away you go.

NOTE This is just what worked for me. I have no idea if there are any side effects from including the import sys line or using Flup. --Skeezer65134

Troubleshooting

You can diagnose a lot of errors by running dispatch.fcgi from the commandline:

./dispatch.fcgi

You can ignore "WSGIServer: missing FastCGI param" errors.


If you are getting a 500 Internal Error, try changing the permissions so that dispatch.fcgi is not group-writable. Something like this will work:

chmod 755 dispatch.fcgi


See Also