Client
~~~~~~

.. warning::
   The client depends on `HTTPEncode
   <http://pythonpaste.org/httpencode>`_ which itself still has some
   significant refactoring in its future (in part to make it more like
   OHM).  

The client looks somewhat similar (if you've looked at the `server
<server.html`>_)::

    from ohm import client
    from formencode import validators

    class MyRemote(object):

        def __init__(self, base_uri):
            self.base_uri = base_uri

        simple_attr = client.remote('simple_attr')
        unicode_attr = client.remote('simple_attr', unicode=True)
        typed_attr = client.remote('typed_attr', content_type='text/plain')
        special_path_attr = client.remote('special-place.txt')
        json_attr = client.json_remote('json_attr')
        int_attr = client.remote('int_attr', validator=validators.AsInt())


Unlike ``server.ApplicationWrapper`` ``client.remote`` does not pick
up the attribute names automatically.  (This may be changed in the
future, or it may not.)  ``client.remote`` requires the object it is
attached to to have an attribute ``obj.base_uri`` (this is the
container that holds all the sub-resources).  The attributes are
simple `descriptors
<http://users.rcn.com/python/download/Descriptor.htm>`_ and thus can
be attached to any new-style class (be sure you subclass from
``object``!)

You can then use the object like::

    my_remote = MyRemote('http://localhost:8080/myobj')
    print my_remote.int_attr # etc...

To extend the SQLObject example from above, here's how you might
implement the client side of that::

    from ohm import client
    from formencode import validators

    class Article(object):
        container_uri = 'http://localhost:8080/article/%(id)s'
        def __init__(self, base_uri):
            self.base_uri = base_uri
        @classmethod
        def get(cls, id):
            base_uri = cls.container_uri % dict(id=id)
            return cls(base_uri)
        created = client.remote('created', 
                                validator=validators.DateConverter())
        title = client.remote('title')
        body = client.remote('body', unicode=True)
        render = client.remote('article.html', 
                               content_type='text/html')

    a = Article.get(1)
    print a.title

This mimics the SQLObject API, but all the methods turn into HTTP
calls, fetching the respective resources from the server.


