Note: WSGIKit has been renamed as Python Paste
Well, I tried to explain WSGIKit, but I'm not entirely sure how successful that was. People asked for diagrams, but I don't think in terms of diagrams (even if I appreciate that it's very useful for other people), so I'm not sure what one would look like. I made a couple diagrams for my WSGIKit PyCon presentation, which may or may not help.
But anyway, I want to write about what WSGIKit can do for you, the framework developer. To do this, I want to explain Webware's relation to WSGIKit, which is a concrete example of how this stuff can fit together.
Webware has a package (wsgikit.webkit) that implements the Webware API. It's included with WSGIKit because it's a reimplementation of Webware. If you didn't want to reimplement your framework, or you wanted to do all your framework development in your repository, you wouldn't necessarily add a subpackage, you'd just use your normal distribution.
The Webware package turns Servlets into WSGI applications. While this effects a whole bunch of stuff, in a lot of ways it's actually pretty simple. If you look at wsgikit.webkit.wkservlet.Servlet, the core WSGI application logic is in __call__ (though, I suppose, spread out over Response and Transaction as well).
This may or may not be feasible for other projects. Servlet happened to not be using __call__, so I could add that method. wsgikit.urlparser.URLParser uses some simple rules to construct WSGI applications -- it loads modules, then looks for the symbol application, which is a ready-made WSGI application, or a symbol matching the module name, which is a factory for WSGI applications. The Webware Servlet subclass is a factory for Servlet instances, which are themselves WSGI applications.
Some frameworks would be able to use this, or maybe offer modifications of this, while other frameworks will have to implement new URL parsers.
So far just one application template is included, wsgikit/app_templates/webkit_zpt. This is used by app_setup to create a blank application file layout (the tutorial makes use of this). Frameworks can have multiple templates (e.g., someone could write a webkit_cheetah template), and the application templates can provide new commands. So sometime I'm planning to add a app-setup servlet <servlet_name> command to webkit_zpt that will create a new blank servlet and template. None of the application template stuff is required, but I think it's a very helpful aid to new users (and convenient for experienced users too).
There's a function in wsgikit.server that when it sees a webkit_dir configuration value, loads up the wsgikit.webkit.wsgwebkit.webkit() stack of middleware, that provides all the functions Webware provides. I want to make this kind of configuration and application assembly pluggable, but for now it'd probably mean hardcoding something for each framework in there. Actually, I plan to rename webkit_dir to something like publish_dir, as there's nothing Webware-specific about it, just file-publishing-specific. But I'm very reluctant to turn configuration into something complicated, so right now I'm expecting to code many use cases into server instead of making configuration more generic or general.
OK, so if you set up your framework to work with WSGIKit, what would you get out of it?
I also think the test and documentation framework is heading in a good direction.
You don't have to use all of this to pick features and code out of WSGIKit if you wish. A lot of what I'm looking to provide with WSGIKit is a good experience for users, both new and experienced, and part of what that means is having other people put things together in intelligent ways instead of leaving it up to each developer to do so. Wouldn't it be great to tell someone evaluating Python web programming to download one (maybe big) hunk of code, run app-setup list to see a dozen available Python frameworks, app-setup list -v to get extended descriptions, app-setup --template=X create ~/test_X; cd ~/test_X; wsgi-server to get a demo of any of the frameworks set up? That's not the end-all-be-all of resolving issues with Python web development, but I think it's an accessible goal right now, and worth doing.
when you say it detects stale code, how deep does the detection reach?
let's say I have a servlet script A. inside A it says ... import foo ...
does wsgikit detect changes to foo?
WSGIKit looks through all the modules in sys.modules and restarts the entire server if one of them changes. It is not initiated by a request, but rather runs in a separate thread and polls the files regularly. You can also make it look at extra files, like a configuration file, and restart when those change too. It doesn't reload modules, which is much more challenging to do correctly, though at some point I'll probably have it look at modules and see if some are explicitly marked to be reloadable. E.g., Webware servlet files (but not the files they import) can generally be reloaded.
Yeah, restarting is the easy way out. No shame in taking the easy way sometimes! That is what Spyce has to do for anything it doesn't compile itself.
BTW, to accomodate pathnames with spaces in them (common on Windows) you may want your reloader code to do something like this
args = ['"' + re.sub('"', r'"', i) + '"' for i in args]
before spawning the subprocess.
I also like to run python -u (if the speed hit matters they shouldn't have the modules checker turned on).
eh, your wiki nuked the backslash in that sub() call.
What happens if you use literal block text, like so:\bleh
Yep. Seems to work.
Your pycon presentation is exactly what i needed to understand wsgi and wsgikit ! thanks# anonymous
Given the current state of Python web programming I would say that WSGI is a good standard to leverage, but I don't think that "thin glue" accurately describes a real-world WSGI implementation. Even if WSGI is the most efficient way to bring the plethora of ideas into focus, it's really more like "thick glue" or "mortar". Fitting some of this stuff together is more like building with rocks than bricks. If this analogy is good, then the goal is not to chip every piece into a new shape, but to knock off the protruding edges so that they can be fitted.