1. Mariusz Kryński
  2. filmaster-api-sample


filmaster-api-sample / filmaster_auth.py

import time
from oauth import oauth
import urllib2, urlparse, cgi
import json

import logging
logger = logging.getLogger(__name__)

class FilmasterOAuthClient(object):
    This class implements filmaster client for making API requests 
    authenticated with OAuth1 protocol

    If you don't have access token yet:
      1. create instance of this class using CONSUMER_KEY and CONSUMER_SECRET
         (obtained at http://filmaster.com/settings/application/)

         client = FilmasterOAuthClient(CONSUMER_KEY, CONSUMER_SECRET)

      2. fetch request token and temporary store it in session / db:

         request_token = client.fetch_request_token()

      3. obtain authorize_url:

         authorize_url = client.get_authorize_url(request_token, callback_url=CALLBACK_URL)

      4. redirect user's browser to authorize_url - user authenticates
         on filmaster, authorizes access of your app and is redirected back
         to CALLBACK_URL (of your app) provided earlier

      5. in CALLBACK_URL handler fetch oauth_verifier parameter from
         request GET parameters and retrieve request_token stored earlier.
         Call fetch_access_token method to retrieve access_token

         access_token = client.fetch_access_token(request_token, oauth_verifier)

      6. store access_token in db for making subsequent, authenticated API requests

    If you have access_token already, pass it to FilmasterOAuthClient constructor:

    client = FilmasterOAuthClient(CONSUMER_KEY, CONSUMER_SECRET, access_token)

    or invoke set_access_token method:


    make api requests using get, post, put or delete methods:

    reply = client.get('/1.1/profile/')


    API_BASE_URL = "https://api.filmaster.com"
    BASE_URL = 'https://filmaster.com'

    # API_BASE_URL = "http://api.filmaster.pl"
    # BASE_URL = 'http://filmaster.pl'

    # API_BASE_URL = "http://localhost.pl:8000/api"
    # BASE_URL = "http://localhost.pl:8000"

    REQUEST_TOKEN_URL = BASE_URL + '/oauth/request/token/'
    ACCESS_TOKEN_URL = BASE_URL + '/oauth/access/token/'

    AUTHORIZATION_URL = BASE_URL + '/oauth/authorize/'
    FB_AUTHORIZATION_URL = BASE_URL + '/oauth/authorize/fb/'

    def __init__(self, key, secret, access_token=None):
        key, secret - key and secret of your app, to register app visit http://filmaster.com/settings/application/
        access_token - optional, may be set later using set_access_token method
        self.consumer = oauth.OAuthConsumer(key, secret)
        self.signature_method = oauth.OAuthSignatureMethod_HMAC_SHA1()
        # self.signature_method = oauth.OAuthSignatureMethod_PLAINTEXT()

    def fetch_request_token(self):
        fetches and return request token
        return self.get_token(self.REQUEST_TOKEN_URL)

    def get_authorize_fb_url(self, token, fb_access_token, callback_url=None):
        creates authorize url for facebook authentication
        token = self._parse_token(token)
        return self.get_authorize_url(
                params={'access_token': fb_access_token},

    def get_authorize_url(self, token, authorization_url=None, params=None, callback_url=None):
        token = self._parse_token(token)
        oauth_request = oauth.OAuthRequest.from_token_and_callback(
                http_url=authorization_url or self.AUTHORIZATION_URL,
        return oauth_request.to_url()

    def fetch_access_token(self, request_token, verifier):
        request_token = self._parse_token(request_token)
        access_token = self.get_token(
        return access_token

    def get_token(self, token_url, request_token=None, verifier=None):
        request_token = self._parse_token(request_token)
        oauth_request = oauth.OAuthRequest.from_consumer_and_token(
        oauth_request.sign_request(self.signature_method, self.consumer, request_token)
        headers = oauth_request.to_header()
        response=self.fetchurl(oauth_request.http_method, token_url, None, headers)
        return oauth.OAuthToken.from_string(response)

    def set_access_token(self, access_token):
        self.access_token = access_token and self._parse_token(access_token)

    def facebook_login(self, fb_access_token):
        request_token = self.fetch_request_token()
        authorize_url = self.get_authorize_fb_url(request_token, fb_access_token)
        response = self.fetchurl('GET', authorize_url)
        verifier = dict(cgi.parse_qsl(response)).get('oauth_verifier')
        return self.fetch_access_token(request_token, verifier)

    def do_request(self, method, url, data=None, headers = None):
        if not self.access_token:
            raise Exception('access token not set')

        if url.startswith('/'):
            url = self.API_BASE_URL + url

        headers = headers or {}
        if data is not None:
            data = json.dumps(data)
            headers['Content-Type'] = 'application/json'
            headers['Content-Length'] = str(len(data))

        params = {}
        if '?' in url:

        content_type = headers.get('Content-Type')
        if content_type in [None, 'application/x-www-form-urlencoded'] and data:

        oauth_request = oauth.OAuthRequest.from_consumer_and_token(
             token = self.access_token,
             http_method = method,
             http_url = url,
             parameters = params)
        oauth_request.sign_request(self.signature_method, self.consumer, token = self.access_token)

        return json.loads(self.fetchurl(method, url, data, headers))

        # test for sending oauth data in url:
        # return json.loads(self.fetchurl(method, oauth_request.to_url(), data, headers))

    def fetchurl(self, method, url, data=None, headers=None):
        request = _Request(method, url, data, headers)
        logger.debug("%r", request)
        response = urllib2.urlopen(request).read()
        logger.debug("response: %r", response)
        return response

    def get(self, url):
        submits GET request
        returns parsed json data (python object)
        return self.do_request('GET', url)

    def put(self, url, data):
        submits PUT request
        data: request parameters (python object, instance of dict usually)
        returns parsed json data (python object)
        return self.do_request('PUT', url, data)

    def post(self, url, data):
        submits POST request
        data: request parameters (python object, instance of dict usually)
        returns parsed json data (python object)
        return self.do_request('POST', url, data)

    def delete(self, url):
        submits DELETE request
        returns parsed json data (python object)
        return self.do_request('DELETE', url)

    def _parse_token(cls, token):
        if isinstance(token, basestring):
            return oauth.OAuthToken.from_string(token)
        return token

class _OAuthHandler(urllib2.BaseHandler):
    urllib2 opener handler for signing requests using provided consumer and access_token
    def __init__(self, consumer, access_token):
        self.consumer = consumer
        self.access_token = access_token

    def http_request(self, request):
        params = {}
        url = request.get_full_url()
        if '?' in url:
            qs = url.split('?',1)[1]
        content_type = request.headers.get('Content-Type')
        if content_type in [None, 'application/x-www-form-urlencoded'] and request.data:
        oauth_request = oauth.OAuthRequest.from_consumer_and_token(
             token = self.access_token,
             http_method = request.get_method().upper(), 
             http_url = url, 
             parameters = params)
        oauth_request.sign_request(self.signature_method, self.consumer, token = self.access_token)
        oauth_headers = oauth_request.to_header()
        logger.debug('request: %s', request)
        return request

    def http_response(self, request, response):
        return response

    https_request = http_request
    https_response = http_response

class _Request(urllib2.Request):
    def __init__(self, method, url, *args, **kw):
        self.method = method
        self.url = url
        urllib2.Request.__init__(self, url, *args, **kw)

    def get_method(self):
        return self.method

    def __repr__(self):
        return "<Request %s: %s, headers: %r>" % (self.method, self.url, self.headers)