Thursday, November 20, 2008

NWSGI on Window Azure

I have had a couple of people ask about NWSGI on Windows Azure. Architecturally (as far as NWSGI is concerned), Azure is just IIS7 running in medium trust. You have to use xcopy deployment, which makes me glad I went to the effort of supporting it.

NWSGI 0.6 actually supports medium trust. I only discovered after the release that the error I was hitting was a bug in Cassini; it works fine in medium trust on IIS7. With that hurdle out of the way, there's no reason NWSGI shouldn't work on Azure.

And, what do you know, it works just fine: NWSGI "Hello, World" for Windows Azure. You'll need the Azure SDK and the Visual Studio tools to run it.

The big downside is that every NWSGI app would have to include its entire framework and the Python standard library (or whatever subset that it uses).

Tuesday, November 11, 2008

Integrating Django and ASP.NET

Using NWSGI to run Django on IronPython opens up some interesting possibilities, such as using ASP.NET's caching, session, or authentication systems for Django. I imagine any ASP.NET shop spent time configuring their ASP.NET providers for those systems, and I thought it would be interesting to see if that effort could be used for Django apps as well, and it certainly looks like they can.

A demo version of django-aspnet is now available. I'll expand on the details later, but for now: set the *_BACKEND variables in settings.py to point to these modules (they must be on the Python path). All other configuration settings for the Django apps are ignored; you must use Web.config to configure them, like any ASP.NET app.

Some parts are still missing, but the basic functionality seems to work.

Sunday, November 2, 2008

NWSGI 0.6 Released

NWSGI 0.6 has been released on Codeplex. This release has some possibly breaking changes and a whole host of new features. There is also an installer available along with the zip archive. The HelloWorld example has been rolled into the zip file.

There is one minor feature addition: wsgi.file_wrapper is now supported for faster file transfers. It uses HttpResponse.TransmitFile to send the file directly.

The major new feature is IIS7 management integration, including a UI editor. This is a huge addition and one I'm quite proud of. It makes configuring NWSGI a breeze from the command line (appcmd) or from the UI. The IIS7 integration is only available through the installer.

The changes are in the configuration system to support the IIS7 management system. Unfortunately, IIS7 doesn't use System.Configuration; instead, it has its own assembly, Microsoft.Web.Administration. This caused some complications for configuration. There are now three possible usage scenarios (IIS6, IIS7 xcopy, and IIS7 installed) that require slightly different web.config settings; I will detail these in an upcoming post.

Monday, October 27, 2008

Installing IIS7 UI Extensions With WiX

IIS7 includes a new set of APIs for building extensions for its UI configuration manager, inetmgr. Following the Understanding UI Extension Authoring guide on iis.net results in a pair of assemblies to be added to the GAC, a configuration schema, and some entries to be added to applicationHost.config and administration.config. This is basically a WiX-ification of the deployment guide available here.

All of these files are in %systemroot%\system32\inetsrv\config.

WiX XmlConfig

The XmlConfig element is what is used to edit existing XML files (XmlFile is used to edit files that are installed with your program). It's ugly and a pain to use correctly, but it does the trick. The reference that comes with WiX is decent, but it doesn't really show you how to use the thing.

The use of XmlConfig follows a basic pattern - create the element, add any attributes or sub-elements, and finally an XmlConfig to handle uninstallation.

applicationHost.config

The applicationHost.config file needs to be edited so that IIS7 can find the custom config section described by the schema file. This amounts to adding a <section name="wsgi" overrideMode="Deny" /> element to the configSections element.

<util:XmlConfig Id="appHostEntry"
                File="[IIS7LOCATION]\config\applicationHost.config"
                Action="create"
                ElementPath="//configuration/configSections/sectionGroup[\[]@name='system.webServer'[\]]"
                Name="section"
                Node="element"
                Sequence="1"
                On="install" />

<util:XmlConfig Id="appHostEntryName"
                File="[IIS7LOCATION]\config\applicationHost.config"
                ElementPath="appHostEntry"
                Name="name"
                Value="wsgi"
                Sequence="2" />

<util:XmlConfig Id="appHostEntryOverrideMode"
                File="[IIS7LOCATION]\config\applicationHost.config"
                ElementPath="appHostEntry"
                Name="overrideModeDefault"
                Value="Deny"
                Sequence="3" />

<util:XmlConfig Id ="removeAppHostEntry"
                File="[IIS7LOCATION]\config\applicationHost.config"
                Action="delete"
                ElementPath="//configuration/configSections/sectionGroup[\[]@name='system.webServer'[\]]"
                Node="element"
                VerifyPath="section[\[]@name='wsgi'[\]]"
                On="uninstall"
                Sequence="1" />

The first XmlConfig entry creates the section element under configSections. The next two add the attributes that I want. Note that the latter entries have their ElementPath pointing to the Id of the first entry. The final XmlConfig is used on uninstallation to remove the element.

administration.config

The entries in administration.config are used by inetmgr to find the admin modules. These follow the same basic pattern as the previous XmlConfig entries. These need to be added in two different spots, so the elements look similar for both cases.

Under moduleProviders:

<util:XmlConfig Id="adminModuleProvider" 
                File="[IIS7LOCATION]\config\administration.config" 
                Action="create" 
                ElementPath="//configuration/moduleProviders" 
                Name="add" 
                Node="element" 
                Sequence="1" 
                On="install" />

<util:XmlConfig Id="adminModuleProviderName" 
                File="[IIS7LOCATION]\config\administration.config" 
                ElementPath="adminModuleProvider" 
                Name="name" 
                Value="NWSGI" 
                Sequence="2" />

<util:XmlConfig Id="adminModuleProviderType" 
                File="[IIS7LOCATION]\config\administration.config" 
                ElementPath="adminModuleProvider" 
                Name="type" 
                Value="NWSGI.Management.NwsgiModuleProvider, NWSGI.Management, Version=0.6.0.0, Culture=neutral, PublicKeyToken=41e64ddc1bf1fc86" 
                Sequence="3" />

<util:XmlConfig Id ="removeAdminModuleProvider" 
                File="[IIS7LOCATION]\config\administration.config" 
                Action="delete" 
                ElementPath="//configuration/moduleProviders" 
                Node="element" 
                VerifyPath="add[\[]@name='NWSGI'[\]]" 
                On="uninstall" 
                Sequence="1" />

Under location:

<util:XmlConfig Id="adminModule"
                File="[IIS7LOCATION]\config\administration.config"
                Action="create"
                ElementPath="//configuration/location[\[]@path='.'[\]]/modules"
                Name="add"
                Node="element"
                Sequence="1"
                On="install" />

<util:XmlConfig Id="adminModuleName"
                File="[IIS7LOCATION]\config\administration.config"
                ElementPath="adminModule"
                Name="name"
                Value="NWSGI"
                Sequence="2" />

<util:XmlConfig Id ="removeAdminModule"
                File="[IIS7LOCATION]\config\administration.config"
                Action="delete"
                ElementPath="//configuration/location[\[]@path='.'[\]]/modules"
                Node="element"
                VerifyPath="add[\[]@name='NWSGI'[\]]"
                On="uninstall"
                Sequence="1" />

schema.xml

Installing the schema.xml file is done with a File element, just like any other file.

Monday, September 22, 2008

NWSGI 0.5 Released

The latest version of NWSGI, built for IronPython 2.0 Beta 5, has been posted. There are a couple of changes in this version: one breaking change and one new feature.

Configuraton Changes

To fit with convention, the configuration elements now start with lowercase letters - i.e. Wsgi => wsgi, OSEnviron => osEnviron, etc. This has a consequence because XML is case-sensitive, so the old configuration elements will not be picked up and the defaults will be used instead.

Script Mappings

Script mappings can be used to create a virtual .wsgi file that points to a file elsewhere on the filesystem. For example:

<scriptmappings>
    <scriptmapping scriptname="dispatch.wsgi" physicalpath="C:\myapp\dispatch.wsgi">
</scriptmappings>

Rather than copy the dispatch.wsgi file into the web aplication directory, any request to dispatch.wsgi will be mapped to c:\myapp\dispatch.wsgi instead. This example is a bit trivial, as an IIS virtual directory could probably be used, but it could be useful for any application that ships a .wsgi file.

Future Directions

I'm working on building an IIS7 admin interface for all of this; it's a bit of a mess right now because the advanced UI tricks aren't really documented that well. I'm hoping to have the IIS7 admin and the installer ready by the time IronPython goes 2.0.