Friday, October 2, 2009

New release candidate for mod_wsgi 3.0 is now available.

Version 3.0c5 of mod_wsgi is now available. This is the 5th release candidate for mod_wsgi version 3.0. The process of developing and releasing version 3.0 of mod_wsgi has dragged on for quite a long time now because of the uncertainties over how Python 3.X support should work. So much so that a lot of the fixes and changes were back ported to mod_wsgi 2.X and released in mod_wsgi 2.4.

Version 3.0 of mod_wsgi will support both Python 2.X and Python 3.X. So, the big question at this point is what is being done about Python 3.X support.

For starters, Python 3.0 will not be supported, you will need to at least be using Python 3.1 if you want to use Python 3.X at all. This is in part because I am assuming the PSF itself would prefer people not to use Python 3.0, but also because am relying on 'surrogateescape' mechanisms from PEP 383 in some of the ways that unicode strings representing file system paths are dealt with where they are passed to WSGI applications under Python 3.X and this was only added in Python 3.1.

As to the whole argument about whether bytes or unicode strings should be passed for values in WSGI environment, and if unicode what encoding should be used, I am effectively sticking with the original proposal put up by PJE about this. This is the same definition that mod_wsgi 3.0 development code has implemented all along and which people have been using already. That no one has complained that how it was implemented was causing problems for them very much suggests for me that it is a reasonable compromise for how it should work.

Just so we are clear on what this definition is, I include it below. This was labelled Definition #3 in my post about WSGI roadmap.

1. The application is passed an instance of a Python dictionary containing what is referred to as the WSGI environment. All keys in this dictionary are native strings. For CGI variables, all names are going to be ISO-8859-1 and so where native strings are unicode strings, that encoding is used for the names of CGI variables.

2. For the WSGI variable 'wsgi.url_scheme' contained in the WSGI environment, the value of the variable should be a native string.

3. For the CGI variables contained in the WSGI environment, the values of the variables are native strings. Where native strings are unicode strings, ISO-8859-1 encoding would be used such that the original character data is preserved and as necessary the unicode string can be converted back to bytes and thence decoded to unicode again using a different encoding.

4. The WSGI input stream 'wsgi.input' contained in the WSGI environment and from which request content is read, should yield byte strings.

5. The status line specified by the WSGI application should be a byte string. Where native strings are unicode strings, the native string type can also be returned in which case it would be encoded as ISO-8859-1.

6. The list of response headers specified by the WSGI application should contain tuples consisting of two values, where each value is a byte string. Where native strings are unicode strings, the native string type can also be returned in which case it would be encoded as ISO-8859-1.

7. The iterable returned by the application and from which response content is derived, should yield byte strings. Where native strings are unicode strings, the native string type can also be returned in which case it would be encoded as ISO-8859-1.

FWIW, this is also the same definition as the 'wsgiref' library in Python 3.X has been using, albeit that how it was implemented in Python 3.0 was somewhat broken.

Up until now, even in the absence of a definition of what WSGI should be for Python 3.X, the mod_wsgi implementation and the 'wsgiref' implementation have been carrying the 'wsgi.version' tag in WSGI environment of '(1,0)'. As such, this has already more or less become the defacto standard of what WSGI 1.0 is on Python 3.X.

Going forward though I am no longer going to set 'wsgi.version' to '(1,0)', instead I am going to label it as '(1,1)'. That is, WSGI 1.1. This will also apply to WSGI as implemented for Python 2.X in mod_wsgi version 3.0.

The reason for calling it WSGI 1.1 for both Python 2.X and Python 3.X is to make it clear that the implementation supports the amendments I previously described for WSGI 1.0. Actually, mod_wsgi has always been implemented inline with those amendments but has more or less been impossible for WSGI developers to rely on things working that way. Thus, using the WSGI 1.1 moniker is to give some certainty about what is actually implemented.

I fully realise that I am making my own decision here to use WSGI 1.1 name and not defer to the Python WEB-SIG to agree on something and some may complain I have no right to do so. Given though that the discussions on the Python WEB-SIG was moving to any more significant update beyond the definition above being called WSGI 2.0, even if it retained 'start_response()', I believe it is a reasonable call on my part and at least gives some short term certainty for developers about what to expect.

If people want to vehemently complain about it being called WSGI 1.1, then I guess I will just need to call it something other than WSGI from now on.

As to all the other discussions about WSGI 2.0 and WSGI 3.0 on the Python WEB-SIG, if anything does come of that, I will not be implementing them in mod_wsgi itself.

This doesn't mean that one wouldn't be able to use WSGI 2.0 or WSGI 3.0, whatever they may turn out to be, with mod_wsgi, it just means that you will need to use an adapter to bridge between what mod_wsgi implements and the latter versions.

Part of the reason for taking this approach is that it has to be understood that mod_wsgi has no Python code in it, it is actually all C code. Thus, the proposal such as put forward by Ian Bicking is actually a PITA when it comes to implementing them in mod_wsgi.

Don't get me wrong, I am not saying anything against the proposal as it is as reasonable as some of the others, just that for mod_wsgi and how it is implemented as C code it isn't necessarily as trivial to implement as for pure Python web servers. There is as such some sense to taking a layered approach for mod_wsgi with it only implementing the current WSGI specification and deferring anything else to higher level provided by way of a separate package implemented as Python code.

So that it isn't too painful to try and use any newer version of the specification, and in pursuit of making mod_wsgi even easier to use than it is, I am though working on a separate deployment interface for mod_wsgi. Take this is a blending of ideas from Paste and buildout.

The intention would be to have a Paste or buildout style WSGI deployment description file in place of the current WSGI script file, with what version of WSGI being used and how one adapts a specific WSGI application and setup virtual environments being specified by way of plug and play recipes.

The end result would be that instead of having to construct your own WSGI script file, you would just use pre canned recipes that do all the hard work for you. You would just need to, as per the requirements of the recipe, specify such things as where your WSGI application instance is located etc.

Anyway, that is what is happening with Python 3.X support. As to what else mod_wsgi 3.0 contains, you can find the details in the CHANGES file for now. I'll be making other posts about some changes as I need to solicit some feedback so can determine what default behaviour should be for some changes.

So, please go forth and see what issues you can find in this release candidate. Because the process has been long, it is actually appearing to be very stable already, even with Python 3.X. Hopefully I can wrap everything up in the next few weeks and finally release something. Then I can look more at this new deployment mechanism and so maybe once again the discussion around WSGI 2.0 and WSGI 3.0.


gahooa said...

Hi Graham,

Thanks for the RC release. It was up only 3 days before I went hunting for Python 3.1 support. I got it to compile just fine, and have a test server running it.

Thanks for everything!


Jason Garber
AppCove, Inc.

ex_o said...

Hello Graham,

I'd like your mod_wsgi. Now, I want to translate your wiki tutorial on into Indonesian Language.

Are you allow it ?

Best Regards,

Infinity, Inc.

Graham Dumpleton said...

Not keen on translations at this point since the material is a moving target. You would perhaps also be better off working on introductory material on WSGI itself rather than the nitty gritty of mod_wsgi.

ex_o said...

Ok.. Thank you.