PEP 333 specifies WSGI, the Python Web Server Gateway Interface v1.0; it's written by Phillip Eby who put a lot of effort in it to make it acceptable to very diverse web frameworks. The PEP has been well received by web framework makers and users. As a supplement to the PEP, Phillip has written a reference implementation, "wsgiref". I don't know how many people have used wsgiref; I'm using it myself for an intranet webserver and am very happy with it. (I'm asking Phillip to post the URL for the current source; searching for it produces multiple repositories.) I believe that it would be a good idea to add wsgiref to the stdlib, after some minor cleanups such as removing the extra blank lines that Phillip puts in his code. Having standard library support will remove the last reason web framework developers might have to resist adopting WSGI, and the resulting standardization will help web framework users. Last time this was brought up there were feature requests and discussion on how "industrial strength" the webserver in wsgiref ought to be but nothing like the flamefest that setuptools caused (no comments please). I'm inviting people to discuss the addition of wsgiref to the standard library. I'd like the discussion to be finished before a3 goes out; technically it can go in up till the b1 code freeze, but I don't really want to push it that close. I'd like the focus of the discussion to be "what are the risks of adding wsgiref to the stdlib"; not "what could we think of that's even better". Achieving a perfect decision is not the goal; having general consensus that adding it would be better than not adding is would be good. Pointing out specific bugs in wsgiref and suggesting how they ought to be fixed is also welcome. -- --Guido van Rossum (home page: http://www.python.org/~guido/)
I'm inviting people to discuss the addition of wsgiref to the standard library. I'd like the discussion to be finished before a3 goes out;
+1. I think it's faily low-risk. WSGI has been discussed and implemented for well over a year; there are many working implementations of the spec. Adding wsgiref to the stdlib would help other implementors of the spec. I think there should be a better server implementation in the stdlib, but I think that can be added separately. (Personally, I'd like to find the time to (a) make Medusa thread-safe, and (b) add WSGI to it. If anyone would like to help with that, send me mail.) Bill
Guido van Rossum wrote:
PEP 333 specifies WSGI, the Python Web Server Gateway Interface v1.0; it's written by Phillip Eby who put a lot of effort in it to make it acceptable to very diverse web frameworks. The PEP has been well received by web framework makers and users.
As a supplement to the PEP, Phillip has written a reference implementation, "wsgiref". I don't know how many people have used wsgiref; I'm using it myself for an intranet webserver and am very happy with it. (I'm asking Phillip to post the URL for the current source; searching for it produces multiple repositories.)
I believe that it would be a good idea to add wsgiref to the stdlib, after some minor cleanups such as removing the extra blank lines that Phillip puts in his code. Having standard library support will remove the last reason web framework developers might have to resist adopting WSGI, and the resulting standardization will help web framework users.
I'd like to include paste.lint with that as well (as wsgiref.lint or whatever). Since the last discussion I enumerated in the docstring all the checks it does. There's still some outstanding issues, mostly where I'm not sure if it is too restrictive (marked with @@ in the source). It's at: http://svn.pythonpaste.org/Paste/trunk/paste/lint.py I think another useful addition would be some prefix-based dispatcher, similar to paste.urlmap (but probably a bit simpler): http://svn.pythonpaste.org/Paste/trunk/paste/urlmap.py The motivation there is to give people the basic tools to simple multi-application hosting, and in the process implicitly suggest how other dispatching can be done. I think this is something that doesn't occur to people naturally, and they see it as a flaw in the server (that the server doesn't have a dispatching feature), and the result is either frustration, griping, or bad kludges. By including a basic implementation of WSGI-based dispatching the standard library can lead people in the right direction for more sophisticated dispatching. And prefix dispatching is also quite useful on its own, it's not just educational.
Last time this was brought up there were feature requests and discussion on how "industrial strength" the webserver in wsgiref ought to be but nothing like the flamefest that setuptools caused (no comments please).
No one disagreed with the basic premise though, just some questions about the particulars of the server. I think there were at least a couple small suggestions for the wsgiref server; in particular maybe a slight refactoring to make it easier to use with https. -- Ian Bicking / ianb@colorstudy.com / http://blog.ianbicking.org
On 4/28/06, Ian Bicking <ianb@colorstudy.com> wrote:
I'd like to include paste.lint with that as well (as wsgiref.lint or whatever). Since the last discussion I enumerated in the docstring all the checks it does. There's still some outstanding issues, mostly where I'm not sure if it is too restrictive (marked with @@ in the source). It's at:
That looks fine to me; I'm not in this business full-time so I'll await others' responses.
I think another useful addition would be some prefix-based dispatcher, similar to paste.urlmap (but probably a bit simpler): http://svn.pythonpaste.org/Paste/trunk/paste/urlmap.py
IMO this is getting into framework design. Perhaps something like this could be added in 2.6? -- --Guido van Rossum (home page: http://www.python.org/~guido/)
Guido van Rossum wrote:
I think another useful addition would be some prefix-based dispatcher, similar to paste.urlmap (but probably a bit simpler): http://svn.pythonpaste.org/Paste/trunk/paste/urlmap.py
IMO this is getting into framework design. Perhaps something like this could be added in 2.6?
I don't think it's frameworky. It could be used to build a very primitive framework, but even then it's not a particularly useful starting point. In Paste this would generally be used below any framework (or above I guess, depending on which side is "up"). You'd pass /blog to a blog app, /cms to a cms app, etc. WSGI already is very specific about what needs to be done when doing this dispatching (adjusting SCRIPT_NAME and PATH_INFO), and that's all that the dispatching needs to do. The applications themselves are written in some framework with internal notions of URL dispatching, but this doesn't infringe upon those. (Unless the framework doesn't respect SCRIPT_NAME and PATH_INFO; but that's their problem, as the dispatcher is just using what's already allowed for in the WSGI spec.) It also doesn't overlap with frameworks, as prefix-based dispatching isn't really that useful in a framework. The basic implementation is: class PrefixDispatch(object): def __init__(self): self.applications = {} def add_application(self, prefix, app): self.applications[prefix] = app def __call__(self, environ, start_response): apps = sorted(self.applications.items(), key=lambda x: -len(x[0])) path_info = environ.get('PATH_INFO', '') for prefix, app in apps: if not path_info.startswith(prefix): continue environ['SCRIPT_NAME'] = environ.get('SCRIPT_NAME', '')+prefix environ['PATH_INFO'] = environ.get('PATH_INFO', '')[len(prefix):] return app(environ, start_response) start_response('404 Not Found', [('Content-type', 'text/html')]) return ['<html><body><h1>Not Found</h1></body></html>'] There's a bunch of checks that should take place (most related to /'s), and the not found response should be configurable (probably as an application that can be passed in as an argument). But that's most of what it should do. -- Ian Bicking / ianb@colorstudy.com / http://blog.ianbicking.org
It still looks like an application of WSGI, not part of a reference implementation. Multiple apps looks like an advanced topic to me; more something that the infrastructure (Apache server or whatever) ought to take care of. I don't expect you to agree with me. But I don't expect you to be able to convince me either. Maybe you can convince Phillip; I'm going to try to sit on my hands now. --Guido On 4/28/06, Ian Bicking <ianb@colorstudy.com> wrote:
Guido van Rossum wrote:
I think another useful addition would be some prefix-based dispatcher, similar to paste.urlmap (but probably a bit simpler): http://svn.pythonpaste.org/Paste/trunk/paste/urlmap.py
IMO this is getting into framework design. Perhaps something like this could be added in 2.6?
I don't think it's frameworky. It could be used to build a very primitive framework, but even then it's not a particularly useful starting point.
In Paste this would generally be used below any framework (or above I guess, depending on which side is "up"). You'd pass /blog to a blog app, /cms to a cms app, etc. WSGI already is very specific about what needs to be done when doing this dispatching (adjusting SCRIPT_NAME and PATH_INFO), and that's all that the dispatching needs to do.
The applications themselves are written in some framework with internal notions of URL dispatching, but this doesn't infringe upon those. (Unless the framework doesn't respect SCRIPT_NAME and PATH_INFO; but that's their problem, as the dispatcher is just using what's already allowed for in the WSGI spec.) It also doesn't overlap with frameworks, as prefix-based dispatching isn't really that useful in a framework.
The basic implementation is:
class PrefixDispatch(object): def __init__(self): self.applications = {} def add_application(self, prefix, app): self.applications[prefix] = app def __call__(self, environ, start_response): apps = sorted(self.applications.items(), key=lambda x: -len(x[0])) path_info = environ.get('PATH_INFO', '') for prefix, app in apps: if not path_info.startswith(prefix): continue environ['SCRIPT_NAME'] = environ.get('SCRIPT_NAME', '')+prefix environ['PATH_INFO'] = environ.get('PATH_INFO', '')[len(prefix):] return app(environ, start_response) start_response('404 Not Found', [('Content-type', 'text/html')]) return ['<html><body><h1>Not Found</h1></body></html>']
There's a bunch of checks that should take place (most related to /'s), and the not found response should be configurable (probably as an application that can be passed in as an argument). But that's most of what it should do.
-- Ian Bicking / ianb@colorstudy.com / http://blog.ianbicking.org
-- --Guido van Rossum (home page: http://www.python.org/~guido/)
Guido van Rossum wrote:
It still looks like an application of WSGI, not part of a reference implementation. Multiple apps looks like an advanced topic to me; more something that the infrastructure (Apache server or whatever) ought to take care of.
I don't understand the distinction between "application of WSGI" and "reference implementation". The reference implementation *is* an application of WSGI... using the reference implementation doesn't make something more or less WSGI. Also, wsgiref *is* infrastructure. When using the HTTP server, there is no other infrastructure, there is nothing else that will do this prefix dispatching for you. Apache and other web servers also provides this functionality, and with the right configuration it will provide the identical environment as a prefix dispatcher. To me that's a positive. I've seen cases where other people have done the same prefix dispatching in Python *without* matching the interface of anybody else's code or environment; that's the sort of thing a reference implementation is meant to keep people from doing. -- Ian Bicking / ianb@colorstudy.com / http://blog.ianbicking.org
It still looks like an application of WSGI, not part of a reference implementation.
It seems to me that canonical exemplars are part of what a "reference" implementation should include. Otherwise it would be a "standard" implementation, which is considerably different. Bill
At 02:32 PM 4/28/2006 -0500, Ian Bicking wrote:
Guido van Rossum wrote:
PEP 333 specifies WSGI, the Python Web Server Gateway Interface v1.0; it's written by Phillip Eby who put a lot of effort in it to make it acceptable to very diverse web frameworks. The PEP has been well received by web framework makers and users.
As a supplement to the PEP, Phillip has written a reference implementation, "wsgiref". I don't know how many people have used wsgiref; I'm using it myself for an intranet webserver and am very happy with it. (I'm asking Phillip to post the URL for the current source; searching for it produces multiple repositories.)
I believe that it would be a good idea to add wsgiref to the stdlib, after some minor cleanups such as removing the extra blank lines that Phillip puts in his code. Having standard library support will remove the last reason web framework developers might have to resist adopting WSGI, and the resulting standardization will help web framework users.
I'd like to include paste.lint with that as well (as wsgiref.lint or whatever). Since the last discussion I enumerated in the docstring all the checks it does. There's still some outstanding issues, mostly where I'm not sure if it is too restrictive (marked with @@ in the source). It's at:
+1, but lose the unused 'global_conf' parameter and 'make_middleware' functions.
I think another useful addition would be some prefix-based dispatcher, similar to paste.urlmap (but probably a bit simpler): http://svn.pythonpaste.org/Paste/trunk/paste/urlmap.py
I'd rather see something a *lot* simpler - something that just takes a dictionary mapping names to application objects, and parses path segments using wsgiref functions. That way, its usefulness as an example wouldn't be obscured by having too many features. Such a thing would still be quite useful, and would illustrate how to do more sophisticated dispatching. Something more or less like: from wsgiref.util import shift_path_info # usage: # main_app = AppMap(foo=part_one, bar=part_two, ...) class AppMap: def __init__(self, **apps): self.apps = apps def __call__(self, environ, start_response): name = shift_path_info(environ) if name is None: return self.default(environ, start_response) elif name in self.apps: return self.apps[name](environ,start_response) return self.not_found(environ, start_response) def default(self, environ, start_response): self.not_found(environ, start_response) def not_found(self, environ, start_response): # code to generate a 404 response here This should be short enough to highlight the concept, while still providing a few hooks for subclassing.
Phillip J. Eby wrote:
I'd like to include paste.lint with that as well (as wsgiref.lint or whatever). Since the last discussion I enumerated in the docstring all the checks it does. There's still some outstanding issues, mostly where I'm not sure if it is too restrictive (marked with @@ in the source). It's at:
+1, but lose the unused 'global_conf' parameter and 'make_middleware' functions.
Yeah, those are just related to Paste Deploy and wouldn't go in.
I think another useful addition would be some prefix-based dispatcher, similar to paste.urlmap (but probably a bit simpler): http://svn.pythonpaste.org/Paste/trunk/paste/urlmap.py
I'd rather see something a *lot* simpler - something that just takes a dictionary mapping names to application objects, and parses path segments using wsgiref functions. That way, its usefulness as an example wouldn't be obscured by having too many features. Such a thing would still be quite useful, and would illustrate how to do more sophisticated dispatching. Something more or less like:
from wsgiref.util import shift_path_info
# usage: # main_app = AppMap(foo=part_one, bar=part_two, ...)
class AppMap: def __init__(self, **apps): self.apps = apps
def __call__(self, environ, start_response): name = shift_path_info(environ) if name is None: return self.default(environ, start_response) elif name in self.apps: return self.apps[name](environ,start_response) return self.not_found(environ, start_response)
def default(self, environ, start_response): self.not_found(environ, start_response)
def not_found(self, environ, start_response): # code to generate a 404 response here
This should be short enough to highlight the concept, while still providing a few hooks for subclassing.
That's mostly what I was thinking, though using a full prefix (instead of just a single path segment), and the default is the application at '', like in my other email. paste.urlmap has several features I wouldn't propose (like domain and port matching, more Paste Deploy stuff, and a proxy object that I should probably just delete); I probably should have been more specific. URLMap's dictionary interface isn't that useful either. Another feature that the example in my other email doesn't have is / handling, specifically redirecting /something-that-matches to /something-that-matches/ (something Apache's Alias doesn't do but should). Host and port matching is pretty easy to do at the same time, and in my experience can be useful to do at the same time, but I don't really care if that feature goes in. -- Ian Bicking / ianb@colorstudy.com / http://blog.ianbicking.org
At 02:32 PM 4/28/2006 -0500, Ian Bicking wrote:
I'd like to include paste.lint with that as well (as wsgiref.lint or whatever). Since the last discussion I enumerated in the docstring all the checks it does. There's still some outstanding issues, mostly where I'm not sure if it is too restrictive (marked with @@ in the source). It's at:
Ian, I see this is under the MIT license. Do you also have a PSF contributor agreement (to license under AFL/ASF)? If not, can you place a copy of this under a compatible license so that I can add this to the version of wsgiref that gets checked into the stdlib? (And if any PSF folks can chime in with easier ways to handle this, please do.)
Phillip J. Eby wrote:
At 02:32 PM 4/28/2006 -0500, Ian Bicking wrote:
I'd like to include paste.lint with that as well (as wsgiref.lint or whatever). Since the last discussion I enumerated in the docstring all the checks it does. There's still some outstanding issues, mostly where I'm not sure if it is too restrictive (marked with @@ in the source). It's at:
Ian, I see this is under the MIT license. Do you also have a PSF contributor agreement (to license under AFL/ASF)? If not, can you place a copy of this under a compatible license so that I can add this to the version of wsgiref that gets checked into the stdlib?
I don't have a contributor agreement. I can change the license in place, or sign an agreement, or whatever; someone should just tell me what to do. -- Ian Bicking | ianb@colorstudy.com | http://blog.ianbicking.org
This explains what to do, and which license to use: http://www.python.org/psf/contrib/ --Guido On 5/22/06, Ian Bicking <ianb@colorstudy.com> wrote:
Phillip J. Eby wrote:
At 02:32 PM 4/28/2006 -0500, Ian Bicking wrote:
I'd like to include paste.lint with that as well (as wsgiref.lint or whatever). Since the last discussion I enumerated in the docstring all the checks it does. There's still some outstanding issues, mostly where I'm not sure if it is too restrictive (marked with @@ in the source). It's at:
Ian, I see this is under the MIT license. Do you also have a PSF contributor agreement (to license under AFL/ASF)? If not, can you place a copy of this under a compatible license so that I can add this to the version of wsgiref that gets checked into the stdlib?
I don't have a contributor agreement. I can change the license in place, or sign an agreement, or whatever; someone should just tell me what to do.
-- Ian Bicking | ianb@colorstudy.com | http://blog.ianbicking.org _______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/guido%40python.org
-- --Guido van Rossum (home page: http://www.python.org/~guido/)
Ian Bicking wrote:
Phillip J. Eby wrote:
At 02:32 PM 4/28/2006 -0500, Ian Bicking wrote:
I'd like to include paste.lint with that as well (as wsgiref.lint or whatever). Since the last discussion I enumerated in the docstring all the checks it does. There's still some outstanding issues, mostly where I'm not sure if it is too restrictive (marked with @@ in the source). It's at:
Ian, I see this is under the MIT license. Do you also have a PSF contributor agreement (to license under AFL/ASF)? If not, can you place a copy of this under a compatible license so that I can add this to the version of wsgiref that gets checked into the stdlib?
I don't have a contributor agreement. I can change the license in place, or sign an agreement, or whatever; someone should just tell me what to do.
I faxed in a contributor aggreement, and added this to the comment header of the file: # Also licenced under the Apache License, 2.0: http://opensource.org/licenses/apache2.0.php # Licensed to PSF under a Contributor Agreement
participants (4)
-
Bill Janssen
-
Guido van Rossum
-
Ian Bicking
-
Phillip J. Eby