Skip to main content
This is a pre-production deployment of Warehouse. Changes made here affect the production instance of PyPI (
Help us improve Python packaging - Donate today!

Writing RESTful API clients.

Project Description

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


  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Write your code and tests
  4. Ensure all tests still pass (nosetests -svx tests)
  5. Commit your changes (git commit -am 'Add some feature')
  6. Push to the branch (git push origin my-new-feature)
  7. Create new pull request


0.14 (2013-01-29)

  • Pin requests version to less than 1.0 until we test it with requests > 1.0

0.12 (2012-10-02)

  • Fix ResourceCollection.filter.
  • Add like and ilike filters.
  • Minor pep8/formatting changes.

0.11 (2012-09-11)

  • Fix config copy.

0.10 (2012-07-27)

  • Python 2.6 compatibility.

0.9 (2012-07-25)

  • Save serialization fix.

0.8 (2012-07-25)

  • Pagination fixes.

0.7 (2012-07-20)

  • Misc fixes.

0.3 (2012-05-28)

  • Hope you like it.

0.2 (2012-05-01)

  • Growing pains.

0.1 (2012-04-01)

  • Its alive!

Release History

This version
History Node


Download Files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Filename, Size & Hash SHA256 Hash Help File Type Python Version Upload Date
(15.2 kB) Copy SHA256 Hash SHA256
Source None Mar 6, 2013

Supported By

Elastic Elastic Search Pingdom Pingdom Monitoring Dyn Dyn DNS Sentry Sentry Error Logging CloudAMQP CloudAMQP RabbitMQ Heroku Heroku PaaS Kabu Creative Kabu Creative UX & Design Fastly Fastly CDN DigiCert DigiCert EV Certificate Google Google Cloud Servers DreamHost DreamHost Log Hosting