apibee

A dynamic api client


License
BSD-3-Clause
Install
pip install apibee==0.2.2

Documentation

ApiBee

ApiBee is a dynamic rest client built on top of the excellent restkit library.

It aims to be able to handle any uris for any apis.

How it work ?

Let's say we want to fetch the json API of the great service http://www.example.com. Their api is served from http://api.example.com/1.0/:

>>> from apibee import Client
>>> api = Client('http://api.example.com/1.0/')

Now we want to get the result from http://api.example.com/1.0/users/search?q=Timy:

>>> results = api.users.search(q='Timy')

That's it !

Going further

Getting json result

Here:

class ExampleClient(Client):
    def process_result(self, result):
        return json.loads(result)

Now the result is a python type:

>>> api = ExampleClient("http://api.example.com/1.0/")
>>> result = api.user.search(q="timy")

Adding query automatically

Sometimes some api are a bit tricky. And we need to build a custom client to match thoses.

Previously, the version of the api was part of the resource but what if we have to specify it for each request:

http://api.example.com/user/search?v=1.0&q=Timy

We can specify one or more params which will be automatically add to the query:

class ExampleClient(Client):
    def set_persistent_query(**args):
        self._persistent_query = args

    def build_query(self, response, query):
        query.update(self._persistent_query)
        return response, query

>>> api = ExampleClient('http://api.example.com')
>>> api.set_persistent_query(v="1.0")

Customize resources

Some apis like Twitter add .json after the resource but before the query : https://api.twitter.com/1/search.json&q=Timy. We can do it like this:

class TwitterClient(Client):
    def set_format(self, f):
        self._format = f

    def build_query(self, response, query):
        response = "%s.%s" % (response, self._format)
        return response, query

>>> api = TwitterClient('https://api.twitter.com/1', end_resource='.json')
>>> results = api.search(q='Timy')

Raising errors

Sometimes you may have to clean up the result before send it back. You can do it by overloading the Client.process_result method.

Example:

Google's web service won't send an http error 400 if the request failed. Instead, it will send a custom result:

http://ajax.googleapis.com/ajax/services/search/web?q=Earth%20Day

will send back:

{"responseData": null, "responseDetails": "invalid version", "responseStatus": 400}

Let's say we want to catch the error and raise an RequestFailed exception with a custom message which is in the "responseDetails" field:

class GoogleClient(Client):
    def process_result(self, result):
        if result["responseStatus"] == 400:
            raise RequestFailed(result['responseDetails'])
        return result

That's it ! Don't forget to return the result at the end of the process_result method.

>>> api = GoogleClient('http://ajax.googleapis.com/ajax/services')
>>> api.search.web(q="toto")
Traceback (most recent call last):
...
RequestFailed: invalid version