Sample Code (Python)

#!/usr/bin/python
	# -*- coding: utf-8 -*-

	import hmac, sha, time, urllib, urllib2

	from base64 import b64encode
	from audiomicro.utils.hash import SecurityUtils

	class AudiomicroAuthHandler(urllib2.HTTPHandler):
	""" Implemention of Authentication Header from API Doc
	Usage:
	        aa = AudiomicroAuthHandler()
	        aa.set_auth(access_key, secret_key)
	        opener = urllib2.build_opener(aa)

	        r = opener.open(URL)
	"""


	CanonicalizedResource = ('fileID', 'CategoryID', 'Q')

	def set_auth(self, access_key, secret_key):
	    """ Set authentication tokens """
	    self.access_key = access_key
	    self.secret_key = secret_key

	def http_request(self, request):
	    if hasattr(self, 'access_key'):
	        # Build StringToSign
	        string_to_sign = self.string_to_sign(request)
	        if self._debuglevel > 0: print string_to_sign

	        # Add authorization header
	        request.add_unredirected_header('Authorization', 'AUDIOMICRO '+ \
	                self.access_key +':'+ b64encode(self.sign(string_to_sign)) )
	        if self._debuglevel > 0: print request.get_header('Authorization')

	    return request
	https_request = http_request

	def sign(self, s):
	    return hmac.new(self.secret_key, msg=s, digestmod=sha).digest()

	def string_to_sign(self, request):
	    """ StringToSign builder """
	    # GET or POST
	    rv = request.get_method() +"\n"

	    # Content-MD5 if present should be added to StringToSign
	    if request.has_header('Content-MD5'):
	        rv += request.get_header('Content-MD5')
	    rv += "\n"

	    if request.has_header('Content-Type'):
	        rv += request.get_header('Content-Type')
	    rv += "\n"

	    # Date header should be exists in request
	    if not request.has_header('Date'):
	        request.add_unredirected_header('Date',
	                time.strftime("%a, %d %b %Y %H:%M:%S %z"))
	    rv += request.get_header('Date') + "\n"

	    # Get the URI part from URL
	    params = urllib.splitquery(request.get_selector())
	    query = [part.split('=', 1) for part in params[1].split('&')]

	    # .. and build CanonicalizedResource
	    canonicalized_resource = params[0][0] == '/' and params[0] or '/'+ params[0]
	    canonicalized_params = []

	    for q in query:
	        # Check if the URI part in CanonicalizedResource list
	        if q[0] in self.__class__.CanonicalizedResource:
	            canonicalized_params.append('='.join(q)) 
	    if canonicalized_params:
	        canonicalized_resource += '?' + '&'.join(canonicalized_params)

	    rv += canonicalized_resource

	    return rv
	    
	class AudiomicroAuthHandlerURL(AudiomicroAuthHandler):
	""" Implementon of Query String Authentication from API Doc
	Usage:
	        aa = AudiomicroAuthHandlerURL()
	        aa.set_auth(access_key, secret_key)
	        opener = urllib2.build_opener(aa)

	        r = opener.open(URL)
	"""

	def __init__(self, expire_delta=3600, debuglevel=0):
	    AudiomicroAuthHandler.__init__(self, debuglevel)
	    self.expire_delta=expire_delta

	def http_request(self, request):
	    if hasattr(self, 'access_key'):
	        string_to_sign, expires = self.string_to_sign(request)
	        if self._debuglevel > 0: print string_to_sign

	        
	        params = urllib.splitquery(request.get_selector())
	        if params[1]: # URL parameters is not empty
	            request._Request__r_host+= '&'
	            request._Request__original += '&'
	        else:
	            request._Request__r_host += '?'
	            request._Request__original += '?'

	        signature = b64encode(self.sign(string_to_sign))
	        if self._debuglevel > 0:
	            print urllib.urlencode({'Signature': signature}).split('=', 1)[1]

	        q_sign = 'AccessKeyId='+ self.access_key + '&Expires='+ expires + \
	                 '&'+ urllib.urlencode({'Signature': signature})

	        request._Request__r_host += q_sign
	        request._Request__original += q_sign

	    return request
	https_request = http_request

	def string_to_sign(self, request):
	    """ StringToSign builder. Only GET method may used in this handler
	    Function returned StringToSign and Expires
	    """
	    if request.has_data():
	        raise ValueError, "Only GET request may singed by this method"
	    else:
	        rv = "GET\n"

	    if request.has_header('Content-MD5'):
	        rv += request.get_header('Content-MD5')
	    rv += "\n"

	    if request.has_header('Content-Type'):
	        rv += request.get_header('Content-Type')
	    rv += "\n"

	    # Create Expires: now() + some time in secods (3600 by default)
	    Expires = str(int(time.time()) + self.expire_delta)
	    rv += Expires + "\n"

	    # Get the URI part from URL
	    params = urllib.splitquery(request.get_selector())
	    query = [part.split('=', 1) for part in params[1].split('&')]

	    # .. and build CanonicalizedResource
	    canonicalized_resource = params[0][0] == '/' and params[0] or '/'+ params[0]
	    canonicalized_params = []

	    for q in query:
	        # Check if the URI part in CanonicalizedResource list
	        if q[0] in self.__class__.CanonicalizedResource:
	            canonicalized_params.append('='.join(q)) 
	    if canonicalized_params:
	        canonicalized_resource += '?' + '&'.join(canonicalized_params)

	    rv += canonicalized_resource

	    return rv, Expires

	if __name__ == '__main__':
	PARAMS=urllib.urlencode({'CategoryID': '2'})
	URL = 'http://api.audiomicro.com/api/1.1/categories/browse/?%(params)s&PerPage=10' %{'params': PARAMS}

	access_key = '0PN5J17HBGZHT7JJ3X82'
	secret_key = 'uV3F3YluFJax1cknvbcGwgjvx4QpvB+leU8dUj2o'

	aa = AudiomicroAuthHandlerURL()
	aa.set_auth(access_key, secret_key)
	opener = urllib2.build_opener(aa)

	r = opener.open(URL)
	print r.read()
Our Clients Include: