Wareweb ======= .. contents:: 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.