Clients

At the heart of RestORM you have a Client. The client simply allows you to communicate with an API and the one RestORM uses is built on top of the excellent httplib2 library. However, you are free to use any HTTP client library as long as you add the RestORM mixins.

Create a client

Most RESTful API support the JSON format for their responses. A client that can handle JSON is therefore included in RestORM.

class restorm.clients.jsonclient.JSONClient(*args, **kwargs)

Client that handles JSON requests and responses.

from restorm.clients.jsonclient import JSONClient

client = JSONClient(root_uri='http://www.example.com/api/')

The JSONClient is actually a combination of the classes BaseClient and JSONClientMixin. The BaseClient is responsible for communicating with the API while the JSONClientMixin adds serialization and deserialization for JSON. JSONClient itself is a subclass of ClientMixin which exposes various convenience methods.

class restorm.clients.base.BaseClient(*args, **kwargs)

Simple RESTful client based on httplib2.Http.

request(uri, method='GET', body=None, headers=None, redirections=5, connection_type=None)

Creates a Request object by calling self.create_request(uri, method, body, headers) and performs the low level HTTP-request using this request object. A Response object is created with the data returned from the request, by calling self.create_response(response_headers, response_content, request) and is returned.

class restorm.clients.base.ClientMixin

This mixin contains the attribute MIME_TYPE which is None by default. Subclasses can set it to some mime-type that will be used as Content-Type and Accept header in requests.

If the MIME_TYPE is also found in the Content-Type response headers, the response contents will be deserialized.

serialize(data)

Produces a serialized version suitable for transfer over the wire.

Subclasses should override this function to implement their own serializing scheme. This implementation simply returns the data passed to this function.

Data from the serialize function passed to the deserialize function, and vice versa, should return the same value.

Parameters:data – Data.
Returns:Serialized data.
deserialize(data)

Deserialize the data from the raw data.

Subclasses should override this function to implement their own deserializing scheme. This implementation simply returns the data passed to this function.

Data from the serialize function passed to the deserialize function, and vice versa, should return the same value.

Parameters:data – Serialized data.
Returns:Data.
create_request(uri, method, body=None, headers=None)

Returns a Request object.

create_response(response_headers, response_content, request)

Returns a Response object.

get(uri)

Convenience method that performs a GET-request.

post(uri, data)

Convenience method that performs a POST-request.

put(uri, data)

Convenience method that performs a PUT-request.

delete(uri)

Convenience method that performs a DELETE-request.

Writing your own client

You can tweak almost everything about the client architecture but the minimum requirements to work with RestORM resources are:

  1. You use the ClientMixin in your client.
  2. Have a request function that returns a Response object.

A minimal implementation would be:

from restorm.clients.base import ClientMixin

class MyClient(ClientMixin):
    def request(self, uri, method, body=None, headers=None):
        # Create request.
        request = self.create_request(uri, method, body, headers)

        # My very own client doesn't need an internet connection!
        response_headers, response_content = {'Status': 200}, 'Hello world!'

        # Create response.
        return self.create_response(response_headers, response_content, request)

The above client doesn’t do much but it shows how to create your own client:

>>> client = MyClient()
>>> response = client.get('/hello/')
>>> response.content
'Hello world!'
>>> response.headers
{'Status': 200}
>>> response.request.uri
'/hello/'

You can override any of the ClientMixin functions to add custom behaviour:

class MyClient(ClientMixin):
    # ...

    def create_request(uri, method, body=None, headers=None):
        """
        Make sure the URI is absolute.
        """
        if not uri.startswith('/'):
            uri = '/%s' % uri
        return super(MyClient, self).create_request(uri, method, body, headers)

    def create_response(response_headers, response_content, request):
        """
        Let everone know that it was MyClient that processed the response.
        """
        response_headers.update({
            'X-Response-Updated-By': 'MyClient'
        })
        return super(MyClient, self).create_response(response_headers, response_content, request)
>>> client = MyClient()
>>> response = client.get('hello/')
>>> response.content
'Hello world!'
>>> response.headers
{'Status': 200, 'X-Response-Updated-By': 'MyClient'}
>>> response.request.uri
'/hello/'

RestORM can handle JSON as response format from RESTful API’s. Implementing your own format requires you to override the serialize and deserialize function in your own client class.

Using different HTTP client libraries

There are lots of different client libraries. RestORM chose for httplib2 as default HTTP client library because it’s an active project with built-in caching and overall has the best performance.

Do not let the above stop you from using your own preferred HTTP client library like requests, oauth2, or even the standard library httplib

Example: OAuth

Many API’s use OAuth, an open standard for authorization. It’s quite simple to incorporate the oauth2 library in combination with one of the client mixins, for example the JSONClientMixin and override the request method to make a request using OAuth:

import oauth2 as oauth
from restorm.clients.jsonclient import JSONClientMixin

class OauthClient(oauth.Client, JSONClientMixin):
    def request(self, uri, method='GET', body=None, headers=None, *args, **kwargs):
        # Create request.
        request = self.create_request(uri, method, body, headers)

        # Perform request.
        response_headers, response_content = super(OauthClient, self).request(request.uri, request.method, request.body, request, *args, **kwargs)

        # Create response.
        return self.create_response(response_headers, response_content, request)

Once we have this, we can do:

>>> consumer = oauth.Consumer(key='YOUR_KEY', secret='YOUR_SECRET')
>>> token = oauth.Token(key='YOUR_TOKEN', secret='YOUR_TOKEN_SECRET')
>>> client = OauthClient(consumer, token)

Project Versions

Table Of Contents

Previous topic

Tutorial

Next topic

Resources

This Page