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.
Installation
Simply:
$ pip install wac
or if you prefer:
$ easy_install wac
Usage
Lets work through an example. The code for this example is in example.py.
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) else: 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 '{}'" .format(response.headers['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('https://api.example.com', auth=('user', 'passwd')) q = (example.Playlist.query() .filter(Playlist.f.tags.contains('nuti')) .filter(~Playlist.f.tags.contains('sober')) .sort(Playlist.f.created_at.desc())) for playlist in q: song = playlist.songs.create( name='Flutes', length=1234, tags=['nuti', 'fluti']) song.length += 101 song.save()
Contributing
- Fork it
- Create your feature branch (git checkout -b my-new-feature)
- Write your code and tests
- Ensure all tests still pass (nosetests -svx tests)
- Commit your changes (git commit -am ‘Add some feature’)
- Push to the branch (git push origin my-new-feature)
- Create new pull request
History
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!
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Filename, size | File type | Python version | Upload date | Hashes |
---|---|---|---|---|
Filename, size mawac-0.1.tar.gz (15.2 kB) | File type Source | Python version None | Upload date | Hashes View |