Source

qwerlypylib / __init__.py

import os
import httplib2
from urllib import urlencode
try:
    # python 2.6 and greater
    import json
except ImportError:
    try:
        # python 2.5
        import simplejson
        json = simplejson
    except ImportError:
        # if we're in django or Google AppEngine land
        # use this as a last resort
        from django.utils import simplejson
        json = simplejson
        
import types


API_BASE_URL = "http://api.qwerly.com/v1/"
DEFAULT_USER_AGENT = "QwerlyPyLib"

class QwerlylibError(Exception):
    pass

class HTTPBackend(object):
    """
    Abstracts out an HTTP backend, but defaults to httplib2

    @FIXME: Build in support for supplying arbitrary backends
    """
    def __init__(self, api_key, agent, as_xml=False, timeout=None, test=False):
        """
        Creates an HTTPBackend object, which abstracts out some of the
        library specific HTTP stuff.
        """
        self.base_url = API_BASE_URL

        #TODO investigate httplib2 caching and if it is necessary
        self.http = httplib2.Http(timeout=timeout)
        self.as_xml = as_xml
        self.api_key = api_key
        self.test = test

        self.headers = {'Content-Type': 'application/json',
                            'Accepts': 'application/json',
                            'User-Agent:': agent}

    def encode(self, data):
        """
        Encodes data as either JSON or XML, so that it can be passed onto
        the Zencoder API
        """
        if not self.as_xml:
            return json.dumps(data)
        else:
            raise NotImplementedError('Encoding as XML is not supported.')

    def decode(self, raw_body):
        """
        Returns the raw_body as json (the default) or XML
        """
        if not self.as_xml:
            # only parse json when it exists, else just return None
            if not raw_body or raw_body == ' ':
                return None
            else:
                return json.loads(raw_body)
        else:
            raise NotImplementedError('Decoding as XML is not supported.')

    def get(self, url, data=None):
        """
        Executes an HTTP GET request for the given URL

        data should be a dictionary of url parameters
        """
        if data:
            params = urlencode(data)
            url = '?'.join([url, params])

        response, content = self.http.request(url, method="GET",
                                              headers=self.headers)
        return self.process(response, content)

    def post(self, url, body=None):
        """
        Executes an HTTP POST request for the given URL
        """
        response, content = self.http.request(url, method="POST",
                                              body=body,
                                              headers=self.headers)

        return self.process(response, content)

    def process(self, http_response, content):
        """
        Returns HTTP backend agnostic Response data
        """
        code = http_response.status
        body = self.decode(content)
        response = Response(code, body, content, http_response)
        return response

    
class Qwerly():

    def __init__(self, api_key=None, agent=None):
        if api_key:
            self._api_key = api_key
        else:
            try:
                from django.conf import settings
                self._api_key = settings.QWERLY_API_KEY
            except:
                raise QwerlylibError("Error Obtaining Qwerly Api Key")

        if agent:
            self._user_agent = agent
        else:
            try:
                from django.conf import settings
                self._user_agent = settings.QWERLY_USER_AGENT
            except:
                self._user_agent = DEFAULT_USER_AGENT

        self.profile = Profile(self._api_key, self._user_agent)
        self.services = Profile(self._api_key, self._user_agent, True)

            

class Response(object):
    """
    The Response object stores the details of an API request in an XML/JSON
    agnostic way.
    """
    def __init__(self, code, body, raw_body, raw_response):
        self.code = code
        self.body = body
        self.raw_body = raw_body
        self.raw_response = raw_response


class Profile(HTTPBackend):
    """ Gets information regarding profile """
    def __init__(self, api_key, agent, services_only=False, as_xml=False, timeout=None):
        self._services_only = services_only
        super(Profile, self).__init__(api_key, agent, as_xml, timeout=timeout)

    def retrieve(self, type, value, request_id=None, services_only=False):
        data = {'api_key': self.api_key } 
        if request_id:
            data["request_id"] = request_id
        services = "/services" if self._services_only else ""
        return self.get('%s/%s/%s%s' % (self.base_url, type, value, services), data=data)

    def get_by_twitter(self, twitter_username, request_id=None):
        return self.retrieve(types.TWITTER, twitter_username, request_id)

    def get_by_facebook_id(self, facebook_id, request_id=None):
        return self.retrieve(types.FACEBOOK_ID, facebook_id, request_id)

    def get_by_facebook_username(self, facebook_username, request_id=None):
        return self.retrieve(types.FACEBOOK_USERNAME, facebook_username, request_id)

    def get_by_email(self, email, request_id=None):
        return self.retrieve(types.EMAIL, email, request_id)