Skip to content


Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
branch: master

This branch is 67 commits behind balanced:master

Fetching latest commit…

Cannot retrieve the latest commit at this time

Failed to load latest commit information.



To write a friendly client for a RESTful API you typically end up doing the following:

  • Write HTTP client commands for communicating with the server. These commands do things like marshal payloads, convert errors, invoke request hooks, etc.
  • Turn responses deserialized by your client into resource objects (i.e. objectify the response).
  • Build up queries (e.g. filter, sort) to access resources matching some criteria in perhaps a particular order.

In the ideal case the client gives your users something approximating an ORM for your resources. This library is intended to assist you in writing such a client provided the API you are consuming complies with some basic expectations:

  • Uses HTTP properly.
  • Identifies resources using URIs.
  • Names nested resources consistently.



$ pip install wac

or if you prefer:

$ easy_install wac



Lets work through an example. The code for this example is in

  • First you import wac:

    import wac
  • Next define the version of your client:

    __version__ = '1.0'
  • Also define the configuration which all Clients will use by default:

    default_config = wac.Config(None)
  • Now be nice and define a function for updating the configuration(s):

    def configure(root_url, **kwargs):
        default = kwargs.pop('default', True)
        kwargs['client_agent'] = 'example-client/' + __version__
        if 'headers' not in kwargs:
            kwargs['headers'] = {}
        kwargs['headers']['Accept-Type'] = 'application/json'
        if default:
            default_config.reset(root_url, **kwargs)
            Client.config = wac.Config(root_url, **kwargs
  • Now the big one, define your Client which is what will be used to talk to a server:

    class Client(wac.Client):
        config = default_config
        def _serialize(self, data):
            data = json.dumps(data, default=self._default_serialize)
            return 'application/json', data
        def _deserialize(self, response):
            if response.headers['Content-Type'] != 'application/json':
                raise Exception("Unsupported content-type '{}'"
            data = json.loads(response.content)
            return data
  • Then define your base Resource:

    class Resource(wac.Resource):
        client = Client()
        registry = wac.ResourceRegistry()
  • And finally your actual resources:

    class Playlist(Resource):
        uri_spec = wac.URISpec('playlists', 'guid', root='/v1')
    class Song(Resource):
        uri_spec = wac.URISpec('songs', 'guid')
  • Done! Now you can do crazy stuff like this:

    import example
    example.configure('', auth=('user', 'passwd'))
    q = (example.Playlist.query()
    for playlist in q:
        song = playlist.songs.create(
            tags=['nuti', 'fluti'])
        song.length += 101


Yes please.

Something went wrong with that request. Please try again.