def __init__(self, host, user=None, password=None, authenticator=None, base="", collapse_scope=True): """ Constructor for the API-Singleton. Use it once with parameters, and then the subsequent calls internal to the API will work. @type host: str @param host: the host to connect to, e.g. "api.soundcloud.com". If a port is needed, use "api.soundcloud.com:1234" @type user: str @param user: if given, the username for basic HTTP authentication @type password: str @param password: if the user is given, you have to give a password as well @type authenticator: OAuthAuthenticator | BasicAuthenticator @param authenticator: the authenticator to use, see L{scapi.authentication} """ self.host = host if authenticator is not None: self.authenticator = authenticator elif user is not None and password is not None: self.authenticator = BasicAuthenticator(user, password) self._base = base self.collapse_scope = collapse_scope
def __init__(self, host, user=None, password=None, authenticator=None, base="", collapse_scope=True): """ Constructor for the API-Singleton. Use it once with parameters, and then the subsequent calls internal to the API will work. @type host: str @param host: the host to connect to, e.g. "api.soundcloud.com". If a port is needed, use "api.soundcloud.com:1234" @type user: str @param user: if given, the username for basic HTTP authentication @type password: str @param password: if the user is given, you have to give a password as well @type authenticator: OAuthAuthenticator | BasicAuthenticator @param authenticator: the authenticator to use, see L{scapi.authentication} """ self.host = host self.host = self.host.replace("http://", "") if self.host[-1] == '/': # Remove a trailing slash, but leave other slashes alone self.host = self.host[0:-1] if authenticator is not None: self.authenticator = authenticator elif user is not None and password is not None: self.authenticator = BasicAuthenticator(user, password) self._base = base self.collapse_scope = collapse_scope
class ApiConnector(object): """ The ApiConnector holds all the data necessary to authenticate against the soundcloud-api. You can instantiate several connectors if you like, but usually one should be sufficient. """ """ SoundClound imposes a maximum on the number of returned items. This value is that maximum. """ LIST_LIMIT = 50 """ The query-parameter that is used to request results beginning from a certain offset. """ LIST_OFFSET_PARAMETER = 'offset' """ The query-parameter that is used to request results being limited to a certain amount. Currently this is of no use and just for completeness sake. """ LIST_LIMIT_PARAMETER = 'limit' def __init__(self, host, user=None, password=None, authenticator=None, base="", collapse_scope=True): """ Constructor for the API-Singleton. Use it once with parameters, and then the subsequent calls internal to the API will work. @type host: str @param host: the host to connect to, e.g. "api.soundcloud.com". If a port is needed, use "api.soundcloud.com:1234" @type user: str @param user: if given, the username for basic HTTP authentication @type password: str @param password: if the user is given, you have to give a password as well @type authenticator: OAuthAuthenticator | BasicAuthenticator @param authenticator: the authenticator to use, see L{scapi.authentication} """ self.host = host if authenticator is not None: self.authenticator = authenticator elif user is not None and password is not None: self.authenticator = BasicAuthenticator(user, password) self._base = base self.collapse_scope = collapse_scope def normalize_method(self, method): """ This method will take a method that has been part of a redirect of some sort and see if it's valid, which means that it's located beneath our base. If yes, we return it normalized without that very base. """ _, _, path, _, _, _ = urlparse.urlparse(method) if path.startswith("/"): path = path[1:] # if the base is "", we return the whole path, # otherwise normalize it away if self._base == "": return path if path.startswith(self._base): return path[len(self._base) - 1:] raise InvalidMethodException("Not a valid API method: %s" % method) def fetch_request_token(self, url=None): """ Helper-function for a registered consumer to obtain a request token, as used by oauth. Use it like this: >>> oauth_authenticator = scapi.authentication.OAuthAuthenticator(CONSUMER, CONSUMER_SECRET, None, None) >>> sca = scapi.ApiConnector(host=API_HOST, authenticator=oauth_authenticator) >>> token, secret = sca.fetch_request_token() >>> authorization_url = sca.get_request_token_authorization_url(token) Please note the None passed as token & secret to the authenticator. """ if url is None: url = REQUEST_TOKEN_URL req = urllib2.Request(url) self.authenticator.augment_request(req, None) handlers = [] if USE_PROXY: handlers.append(urllib2.ProxyHandler({'http': PROXY})) opener = urllib2.build_opener(*handlers) handle = opener.open(req, None) info = handle.info() content = handle.read() params = cgi.parse_qs(content, keep_blank_values=False) key = params['oauth_token'][0] secret = params['oauth_token_secret'][0] return key, secret def fetch_access_token(self): """ Helper-function for a registered consumer to exchange an access token for a request token. Use it like this: >>> oauth_authenticator = scapi.authentication.OAuthAuthenticator(CONSUMER, CONSUMER_SECRET, request_token, request_token_secret) >>> sca = scapi.ApiConnector(host=API_HOST, authenticator=oauth_authenticator) >>> token, secret = sca.fetch_access_token() Please note the values passed as token & secret to the authenticator. """ return self.fetch_request_token(ACCESS_TOKEN_URL) def get_request_token_authorization_url(self, token): """ Simple helper function to generate the url needed to ask a user for request token authorization. See also L{fetch_request_token}. Possible usage: >>> import webbrowser >>> sca = scapi.ApiConnector() >>> authorization_url = sca.get_request_token_authorization_url(token) >>> webbrowser.open(authorization_url) """ return "%s?oauth_token=%s" % (AUTHORIZATION_URL, token)
class ApiConnector(object): """ The ApiConnector holds all the data necessary to authenticate against the soundcloud-api. You can instantiate several connectors if you like, but usually one should be sufficient. """ """ SoundClound imposes a maximum on the number of returned items. This value is that maximum. """ LIST_LIMIT = 50 """ The query-parameter that is used to request results beginning from a certain offset. """ LIST_OFFSET_PARAMETER = 'offset' """ The query-parameter that is used to request results being limited to a certain amount. Currently this is of no use and just for completeness sake. """ LIST_LIMIT_PARAMETER = 'limit' def __init__(self, host, user=None, password=None, authenticator=None, base="", collapse_scope=True): """ Constructor for the API-Singleton. Use it once with parameters, and then the subsequent calls internal to the API will work. @type host: str @param host: the host to connect to, e.g. "api.soundcloud.com". If a port is needed, use "api.soundcloud.com:1234" @type user: str @param user: if given, the username for basic HTTP authentication @type password: str @param password: if the user is given, you have to give a password as well @type authenticator: OAuthAuthenticator | BasicAuthenticator @param authenticator: the authenticator to use, see L{scapi.authentication} """ self.host = host self.host = self.host.replace("http://", "") if self.host[-1] == '/': # Remove a trailing slash, but leave other slashes alone self.host = self.host[0:-1] if authenticator is not None: self.authenticator = authenticator elif user is not None and password is not None: self.authenticator = BasicAuthenticator(user, password) self._base = base self.collapse_scope = collapse_scope def normalize_method(self, method): """ This method will take a method that has been part of a redirect of some sort and see if it's valid, which means that it's located beneath our base. If yes, we return it normalized without that very base. """ _, _, path, _, _, _ = urlparse.urlparse(method) if path.startswith("/"): path = path[1:] # if the base is "", we return the whole path, # otherwise normalize it away if self._base == "": return path if path.startswith(self._base): return path[len(self._base)-1:] raise InvalidMethodException("Not a valid API method: %s" % method) def fetch_request_token(self, url=None, oauth_callback="oob", oauth_verifier=None): """ Helper-function for a registered consumer to obtain a request token, as used by oauth. Use it like this: >>> oauth_authenticator = scapi.authentication.OAuthAuthenticator(CONSUMER, CONSUMER_SECRET, None, None) >>> sca = scapi.ApiConnector(host=API_HOST, authenticator=oauth_authenticator) >>> token, secret = sca.fetch_request_token() >>> authorization_url = sca.get_request_token_authorization_url(token) Please note the None passed as token & secret to the authenticator. """ request_url = "http://" + self.host + "/oauth/request_token" if url is None: url = request_url req = urllib2.Request(url) self.authenticator.augment_request(req, None, oauth_callback=oauth_callback, oauth_verifier=oauth_verifier) handlers = [] if USE_PROXY: handlers.append(urllib2.ProxyHandler({'http' : PROXY})) opener = urllib2.build_opener(*handlers) handle = opener.open(req, None) info = handle.info() content = handle.read() params = cgi.parse_qs(content, keep_blank_values=False) key = params['oauth_token'][0] secret = params['oauth_token_secret'][0] return key, secret def fetch_access_token(self, oauth_verifier): """ Helper-function for a registered consumer to exchange an access token for a request token. Use it like this: >>> oauth_authenticator = scapi.authentication.OAuthAuthenticator(CONSUMER, CONSUMER_SECRET, request_token, request_token_secret) >>> sca = scapi.ApiConnector(host=API_HOST, authenticator=oauth_authenticator) >>> token, secret = sca.fetch_access_token() Please note the values passed as token & secret to the authenticator. """ access_token_url = "http://" + self.host + "/oauth/access_token" return self.fetch_request_token(access_token_url, oauth_verifier=oauth_verifier) def get_request_token_authorization_url(self, token): """ Simple helper function to generate the url needed to ask a user for request token authorization. See also L{fetch_request_token}. Possible usage: >>> import webbrowser >>> sca = scapi.ApiConnector() >>> authorization_url = sca.get_request_token_authorization_url(token) >>> webbrowser.open(authorization_url) """ auth_url = self.host.split("/")[0] auth_url = "http://" + auth_url + "/oauth/authorize" auth_url = auth_url.replace("api.", "") return "%s?oauth_token=%s" % (auth_url, token)