Tornado API Client Framework¶
The tornado_rest_client
framework provides a quick and easy way to build
generic API clients for JSON REST-based APIs. The framework provides robust
and reliable retry mechanisms, error handling and exception raising all within
a simple to use class structure.
The basic purpose of the api
package is to
provide you with a few simple inheritable classes where all you need to do is
fill in a few variables to get back a usable API client.
Every API client you build will be a combination of two objects – a
RestClient
and a
RestConsumer
.
RestClient¶
A RestClient
object is a very simple object
that exposes one public fetch()
method (that’s wrapped in the coroutine()
wrapper) used to
fire off HTTP calls through a tornado.httpclient.AsyncHTTPClient
object.
RestConsumer¶
The RestConsumer
class does the real leg
work. At the root of it, the object self-configures itself with a supplied
CONFIG
dictionary that defines
http_methods
, path
and possible attrs
. The http_methods
and path
work
together to tell the object exactly what path it will call out to, and what
methods it supports. The attrs
provide links to nested methods that return
other RestConsumer
objects.
If you consider an API that may have the following endpoints:
You can define your CONFIG
dict
like this:
class CatAPI(api.RestConsumer):
ENDPOINT = 'http://my_cat_service'
CONFIG = {
# Handles GET /
'path': '/',
'http_methods': {'get': {}},
# Creates a series of methods that return other RestConsumers
'attrs': {
# Handles GET /cats, POST /cats
'cat_api': {
'path': '/cats',
'new': True,
'http_methods': {
'get': {},
'post': {},
},
# Now, handles the random cat endpoint
'attrs': {
'random': {
'path': '/cats/random',
'new': True,
'http_methods': {
'get': {}
}
},
'get': {
'path': '/cats/%id%',
'http_methods': {
'get': {}
}
}
}
}
}
}
Now, instantiating this object would provide methods that look like this:
>>> cats = CatAPI()
>>> cats
CatAPI(/)
>>> cats.cat_api
CatAPI(/cats)
>>> cats.cat_api.random
CatAPI(/cats/random)
>>> cats.cat_api.random.http_get()
<tornado.concurrent.Future object at 0x101f9e390>
>>> yield cats.cat_api.random().http_get()
'Bob Marley!'
>>> yield cats.cat_api.http_post(cat_name='Skippy')
{ "status": "ok" }
>>> yield cats.cat_api.get(id='Bobby').http_get()
{ "cat": "Bobby" }
There are more details available inside the various doc modules below...