import functools from .framework_integration import FrameworkIntegration __all__ = ['BaseOAuth'] OAUTH_CLIENT_PARAMS = ( 'client_id', 'client_secret', 'request_token_url', 'request_token_params', 'access_token_url', 'access_token_params', 'refresh_token_url', 'refresh_token_params', 'authorize_url', 'authorize_params', 'api_base_url', 'client_kwargs', 'server_metadata_url', ) class BaseOAuth(object): """Registry for oauth clients. Create an instance for registry:: oauth = OAuth() """ framework_client_cls = None framework_integration_cls = FrameworkIntegration def __init__(self, fetch_token=None, update_token=None): self._registry = {} self._clients = {} self.fetch_token = fetch_token self.update_token = update_token def create_client(self, name): """Create or get the given named OAuth client. For instance, the OAuth registry has ``.register`` a twitter client, developers may access the client with:: client = oauth.create_client('twitter') :param: name: Name of the remote application :return: OAuth remote app """ if name in self._clients: return self._clients[name] if name not in self._registry: return None overwrite, config = self._registry[name] client_cls = config.pop('client_cls', self.framework_client_cls) if client_cls.OAUTH_APP_CONFIG: kwargs = client_cls.OAUTH_APP_CONFIG kwargs.update(config) else: kwargs = config kwargs = self.generate_client_kwargs(name, overwrite, **kwargs) client = client_cls(self.framework_integration_cls(name), name, **kwargs) self._clients[name] = client return client def register(self, name, overwrite=False, **kwargs): """Registers a new remote application. :param name: Name of the remote application. :param overwrite: Overwrite existing config with framework settings. :param kwargs: Parameters for :class:`RemoteApp`. Find parameters for the given remote app class. When a remote app is registered, it can be accessed with *named* attribute:: oauth.register('twitter', client_id='', ...) oauth.twitter.get('timeline') """ self._registry[name] = (overwrite, kwargs) return self.create_client(name) def generate_client_kwargs(self, name, overwrite, **kwargs): fetch_token = kwargs.pop('fetch_token', None) update_token = kwargs.pop('update_token', None) config = self.load_config(name, OAUTH_CLIENT_PARAMS) if config: kwargs = _config_client(config, kwargs, overwrite) if not fetch_token and self.fetch_token: fetch_token = functools.partial(self.fetch_token, name) kwargs['fetch_token'] = fetch_token if not kwargs.get('request_token_url'): if not update_token and self.update_token: update_token = functools.partial(self.update_token, name) kwargs['update_token'] = update_token return kwargs def load_config(self, name, params): return self.framework_integration_cls.load_config(self, name, params) def __getattr__(self, key): try: return object.__getattribute__(self, key) except AttributeError: if key in self._registry: return self.create_client(key) raise AttributeError('No such client: %s' % key) def _config_client(config, kwargs, overwrite): for k in OAUTH_CLIENT_PARAMS: v = config.get(k, None) if k not in kwargs: kwargs[k] = v elif overwrite and v: if isinstance(kwargs[k], dict): kwargs[k].update(v) else: kwargs[k] = v return kwargs