Wednesday, October 13, 2010

Python: Django on IIS

Because I only have easy access to IIS servers, installing open source software is often an exercise in total masochism. PHP is invariably an unnecessary amount of pain. Anything that then uses PHP then adds more pain (MySQL is surprisingly pain free actually - it just works, even more so than SQL Server).

because I am now used to the level of pain that PHP on IIS creates, I decided to up the ante and try Django out.

(The trick with PHP is FastCGI. I had lots of legacy PHP sites using the deprecated ISAPI extension; with FastCGI everything just works.)

Back to Django. Frankly, I don't know anything about it. However, I have been playing with Python, and really liking it, so I thought I needed a web framework as well. And a challenge.

The technology / versions I am using are:

  • Windows Server 2003 / IIS 6.
  • Python 2.6 (more on this later).
  • PyISAPIe 1.1.0-rc4 as the ISAPI magic connect to Django doobrie.
  • Django 1.2.3.
  • SQL Server 2005 (this is not yet set up with Django - that will be a later post).
  • Test site installed as new web site NOT a virtual directory in IIS (set up on a new port rather than with a host header, but that shouldn't matter)

Most of the installation can be done by following the PyISAPIe instructions, but there are a few gotchas, and a few things that glosses over, so here they are, hopefully in a Google friendly fashion, because I found nothing on most of them.

1. Using Python 2.7 with PyISAPIe

You can't. At least not with the available binaries, as far as I can tell. When I installed Python, I chose the 2.x branch as the most widely supported, and 2.7 as the most recent version. After following the steps in the link above, up to the bit about running Info.py as a test, I went to the website and got the error Specified module could not be loaded.

To cut a long story short, this is a Windows error; it cannot load a DLL referenced by the ISAPI filter. This is because the RC4 release of PyISAPIe looks for python26.dll, and Python 2.7 has, you guessed it, python27.dll.

The solution for this is to install Python 2.6 instead; after that Info.py works perfectly.

There are a couple of posts out there that allude to using PyISAPIe with Python 2.7; unless I am missing something then you cannot do this with the binaries; you would have to download and compile the Visual Studio project, which was more than I was willing to do for a test environment.

2. Installing PyISAPIe

There is an import omission in the instructions, that if you do not know about it will result in the test script working fine, but every Django request later returning Virtual Directory listing denied.

In the section Setting Up Files, it says "Go to c:\pyisapie\source\PyISAPIe\Python\ and copy the entire Http folder to c:\python25\lib\site-packages". What you ACTUALLY want to do is either MOVE the folder, or copy it then rename the original; the reason being is that the Python module Http supplied will be loaded by preference from the same folder as the PyISAPIe DLL, meaning that if you have copied everything nicely into the Python directory and made configuration changes there, sod all will happen.

3. Installing Django

This is pretty straightforward; a few things to mention that aren't immediately apparent if you are used to the Microsoft way:

  • The tarred Django directory should be placed in a sensible place BEFORE you run python setup.py install; you still need it after the install script has run - it is not analogous to an .msi file.
  • The PyISAPIe instructions set up a test project in C:\test - it might bear mentioning that this will become the Django project directory so I put mine in a more sensible place, with all the other web applications on the server. Note however that you want to be careful with permissions here - you don't want the web server to have direct access to the source files, so don't put it in a subdirectory of an Inetpub or similar folder.

4. Getting Django working with PyISAPIe

First of all, ensure that you have followed the PyISAPIE instructions, and also that the original Http folder in the PyISAPIe folder is renamed / deleted.

The next thing to do is ignore the Examples\Django folder completely; this is implied, but I don't think it was implied strongly enough. Or maybe I'm just dense. What you want is the Examples\WSGI folder; copy Isapi.py out of that into the Http folder in your Python install.

Next, add the sys.path related lines and alter the os.environ["DJANGO_SETTINGS_MODULE"] as in the instructions. Note that the sys.path line points to the parent folder of your Django project, NOT actually the project folder.

This then gave various weird errors:

Could not initialize interpreter

Traceback (most recent call last):
  File "C:\Python26\Lib\site-packages\Http\Isapi.py", line 29, in 
    from md5 import md5
  File "C:\Python26\Lib\md5.py", line 8, in 
    DeprecationWarning, 2)
  File "C:\Python26\Lib\warnings.py", line 29, in _show_warning
    file.write(formatwarning(message, category, filename, lineno, line))
Exception: Not currently processing a request

So far, I have fixed this by commented out the from md5 import md5 line; I am not using the RunScript stuff, so it is fine.

This then gave me:

Could not initialize interpreter

Traceback (most recent call last):
  File "C:\Python26\Lib\site-packages\Http\Isapi.py", line 54, in 
    from trac.web.main import dispatch_request as TracHandler
ImportError: No module named trac.web.main

I'm definitely not using Trac, so I commented out the Trac related lines.

This then gave me Hello World! and a working Django install.

Now I just have to figure out what the hell it is, what the hell it does, and how to make it do it. Oh, and connect it to SQL Server.

Just to recap, here are the major fuzzy bits I found in the PyISAPIe documentation:

  • Make sure your PyISAPIe version matches your Python version.
  • If you copy the Http folder into your Python install as suggested, make sure you rename the original.
  • Make sure you use the PyISAPIe Isapi.py from Examples\WSGI, NOT Examples\Django.
  • Remove references in Isapi.py to anything you don't have, and either fix or comment out the MD5 import so you don't get the deprecation warning.

Or I suppose you could run it on Apache, but where's the fun in that?

2 comments:

  1. If you where using IIS 7, then you could easily install Django with Helicon Zoo - http://www.helicontech.com/zoo/
    Unfortunately IIS 6 is not currently supported by this product.

    ReplyDelete
  2. Thanks for the blog. Unfortunately I finally gave up on Python/Django on IIS. Back to PHP...

    ReplyDelete