Wareweb
Introduction
Wareweb is a rethinking of the ideas behind Webware. Webware is a fairly old framework, written back in the days of Python 1.5.2, and some of the API decisions behind it now show their age. Also, many of the abstractions in Webware didn't turn out to be useful, while some other abstractions are missing.
Wareweb tries to keep the basic model of Webware, while simplifying many portions and adding some new techniques. It's not backward compatible, but it doesn't require major revamping to apply to a Webware application.
Wareweb also requires Python 2.4; as long as we're updating the API, I want to make it as modern as possible. Decorators in particular are widely used in the framework.
Status
Wareweb was an experiment in framework design. It's a fairly stable piece of software, and some code is build upon it, but further development is not planned. The author recommends looking at other WSGI-based frameworks, like Pylons.
Configuration
A simple paste.deploy configuration for a Wareweb application named MyPackage looks like:
[app:main] use = egg:Wareweb app_name = mypackage package_name = mypackage debug = true
You can create a basic package with paster like:
paster create --template=basic_package MyPackage
You'll have to create a mypackage.web package after. An example that hasn't been updated recently, but may be helpful, is available in the repository.
Interface
See paste/wareweb/interfaces.py for a description of the IServlet interface; the online documentation for IServlet is a good description.
Components and Events
There are a couple fairly simple metaprogramming techniques added to Servlet to make it easier to add functionality.
Active Attributes
When you create a class, attributes can be "active". That is, simply assigning the attribute can cause changes to the class.
This is implemented by looking for a special method __addtoclass__ in all new attributes. The dispatchers, for instance, add themselves as "event listeners," so that simply by putting a dispatcher in your class definition somewhere you'll have changed the functionality of the class.
Events
Many methods throw events (with paste.wareweb.event.raise_event). An event is sent to each listener on the object, and the handler can do nothing (returning event.Continue) or can override or respond to the event in some way.
Dispatching objects listen for the end_awake event (called at the end of awake()), and may call an extra method on the servlet based on some criteria (like _awake_ or path_info).
Templating systems can use an event to write a template. ZPTKit overrides start_respond to write the template.
Unpacking Methods
On a per-method basis you can use the algorithms in paste.wareweb.unpack to unpack your request. E.g., something like:
dispatch = MethodDispatch()
@public
@unpack
def edit_item(self, item_id_int_path, name):
Item.get(id=item_id_int_path).name = name
This unpacks a request like servlet_name/edit_item/1?name=new_name into the function call. Note that MethodDispatch makes /edit_item call the edit_item() method. @public declares that the method is actually available to the public. @unpack uses the method signature to identify the parts -- item_id_int_path ends with _path, and so will be taken from path_info; and has _int and so will be coerced into an integer.
Automatic Properties
Methods that end with __get, __set and __del will automatically be turned into properties. Subclasses can selectively replace just one of these implementations, while leaving the others in place.
Differences from Webware
This is a rough summary of the differences from Webware. There's lots of little things that are just plain gone; this doesn't enumerate all of them.
No Request And Response
There are no longer request and response objects. There is only the servlet. The servlet contains all the useful methods from these objects.
From the response, several methods:
- set_cookie
- set_header
- add_header
- write
- redirect
From the request, several attributes (note: no methods):
- environ
- config
- request_method
- app_url
- path_info
- path_parts
- fields
For more exact details, see paste.wareweb.interfaces.IServlet
Only One Servlet Class
There's one Servlet for everyone -- no Servlet, HTTPServlet, and Page. All servlets instances are not threadsafe, because they contain information about the request and response in their instance variables. In practice no Webware servlets were threadsafe, nor was there anything to be gained by that.
Also, reusable functionality is not meant to be added with subclasses of Servlet. Subclassing is for the end-developer to add application-specific functionality; there's other techniques for adding reusable functionality.
No _action_ by default
URL dispatching is handled more generically; several dispatchers are available, one which implements the _action_ parsing of Webware. Dispatchers for XML-RPC and JSON-RPC are also possible, and they have their own built-in methods of indicating methods. Other forms of URL parsing are also implemented.

