def testCanImportEveryModule(self): for api_name in apis_internal._GetApiNames(): for api_version in apis_internal._GetVersions(api_name): collections = list( apis_internal._GetApiCollections(api_name, api_version)) for collection in collections: self.assertEqual(api_name, collection.api_name)
def GetVersions(api_name): """Return available versions for given api. Args: api_name: str, The API name (or the command surface name, if different). Raises: UnknownAPIError: If api_name does not exist in the APIs map. Returns: list, of version names. """ # pylint:disable=protected-access return apis_internal._GetVersions(api_name)
def GetVersions(api_name): """Return available versions for given api. Args: api_name: str, The API name (or the command surface name, if different). Raises: UnknownAPIError: If api_name does not exist in the APIs map. Returns: list, of version names. """ # pylint:disable=protected-access return apis_internal._GetVersions(api_name)
def ParseURL(self, url): """Parse a URL into a Resource. This method does not yet handle "api.google.com" in place of "www.googleapis.com/api/version". Searches self.parsers_by_url to find a _ResourceParser. The parsers_by_url attribute is a deeply nested dictionary, where each key corresponds to a URL segment. The first segment is an API's base URL (eg. "https://www.googleapis.com/compute/v1/"), and after that it's each remaining token in the URL, split on '/'. Then a path down the tree is followed, keyed by the extracted pieces of the provided URL. If the key in the tree is a literal string, like "project" in .../project/{project}/..., the token from the URL must match exactly. If it's a parameter, like "{project}", then any token can match it, and that token is stored in a dict of params to with the associated key ("project" in this case). If there are no URL tokens left, and one of the keys at the current level is None, the None points to a _ResourceParser that can turn the collected params into a Resource. Args: url: str, The URL of the resource. Returns: Resource, The resource indicated by the provided URL. Raises: InvalidResourceException: If the provided URL could not be turned into a cloud resource. """ match = _URL_RE.match(url) if not match: raise InvalidResourceException(url, reason='unknown API host') # pylint:disable=protected-access default_enpoint_url = apis_internal._GetDefaultEndpointUrl(url) api_name, api_version, resource_path = ( resource_util.SplitDefaultEndpointUrl(default_enpoint_url)) # Force hyphenated API names to use underscores to conform with apitools # generated clients api_name = api_name.replace('-', '_') if not url.startswith(default_enpoint_url): # Use last registered api version in case of override. api_version = self.registered_apis.get(api_name, [api_version])[-1] try: versions = apis_internal._GetVersions(api_name) except apis_util.UnknownAPIError: raise InvalidResourceException(url, 'unknown api {}'.format(api_name)) if api_version not in versions: raise InvalidResourceException( url, 'unknown api version {}'.format(api_version)) tokens = [api_name, api_version] + resource_path.split('/') endpoint = url[:-len(resource_path)] # Register relevant API if necessary and possible try: self.RegisterApiByName(api_name, api_version=api_version) except apis_util.UnknownAPIError: raise InvalidResourceException(url, 'unknown api {}'.format(api_name)) except apis_util.UnknownVersionError: raise InvalidResourceException( url, 'unknown api version {}'.format(api_version)) params = [] cur_level = self.parsers_by_url for i, token in enumerate(tokens): if token in cur_level: # If the literal token is already here, follow it down. cur_level = cur_level[token] continue # If the literal token is not here, see if this can be a parameter. param, next_level = '', {} # Predefine these to silence linter. for param, next_level in six.iteritems(cur_level): if param == '{}': break else: raise InvalidResourceException( url, reason='Could not parse at [{}]'.format(token)) if len(next_level) == 1 and None in next_level: # This is the last parameter so we can combine the remaining tokens. token = '/'.join(tokens[i:]) params.append(urllib.parse.unquote(token)) cur_level = next_level break # Clean up the provided value params.append(urllib.parse.unquote(token)) # Keep digging down. cur_level = next_level # No more tokens, so look for a parser. if None not in cur_level: raise InvalidResourceException(url, 'Url too short.') subcollection, parser = cur_level[None] params = dict(zip(parser.collection_info.GetParams(subcollection), params)) return parser.ParseResourceId( None, params, base_url=endpoint, subcollection=subcollection)
def ParseURL(self, url): """Parse a URL into a Resource. This method does not yet handle "api.google.com" in place of "www.googleapis.com/api/version". Searches self.parsers_by_url to find a _ResourceParser. The parsers_by_url attribute is a deeply nested dictionary, where each key corresponds to a URL segment. The first segment is an API's base URL (eg. "https://www.googleapis.com/compute/v1/"), and after that it's each remaining token in the URL, split on '/'. Then a path down the tree is followed, keyed by the extracted pieces of the provided URL. If the key in the tree is a literal string, like "project" in .../project/{project}/..., the token from the URL must match exactly. If it's a parameter, like "{project}", then any token can match it, and that token is stored in a dict of params to with the associated key ("project" in this case). If there are no URL tokens left, and one of the keys at the current level is None, the None points to a _ResourceParser that can turn the collected params into a Resource. Args: url: str, The URL of the resource. Returns: Resource, The resource indicated by the provided URL. Raises: InvalidResourceException: If the provided URL could not be turned into a cloud resource. """ match = _URL_RE.match(url) if not match: raise InvalidResourceException('unknown API host: [{0}]'.format(url)) # pylint:disable=protected-access default_enpoint_url = apis_internal._GetDefaultEndpointUrl(url) api_name, api_version, resource_path = ( resource_util.SplitDefaultEndpointUrl(default_enpoint_url)) if not url.startswith(default_enpoint_url): # Use last registered api version in case of override. api_version = self.registered_apis.get(api_name, [api_version])[-1] try: versions = apis_internal._GetVersions(api_name) except apis_util.UnknownAPIError: raise InvalidResourceException(url) if api_version not in versions: raise InvalidResourceException(url) tokens = [api_name, api_version] + resource_path.split('/') endpoint = url[:-len(resource_path)] # Register relevant API if necessary and possible try: self.RegisterApiByName(api_name, api_version=api_version) except (apis_util.UnknownAPIError, apis_util.UnknownVersionError): # The caught InvalidResourceException has a less detailed message. raise InvalidResourceException(url) params = [] cur_level = self.parsers_by_url for i, token in enumerate(tokens): if token in cur_level: # If the literal token is already here, follow it down. cur_level = cur_level[token] elif len(cur_level) == 1: # If the literal token is not here, and there is only one key, it must # be a parameter that will be added to the params dict. param, next_level = next(cur_level.iteritems()) if param != '{}': raise InvalidResourceException(url) if len(next_level) == 1 and None in next_level: # This is the last parameter so we can combine the remaining tokens. token = '/'.join(tokens[i:]) params.append(urllib.unquote(token)) cur_level = next_level break # Clean up the provided value params.append(urllib.unquote(token)) # Keep digging down. cur_level = next_level else: # If the token we want isn't here, and there isn't a single parameter, # the URL we've been given doesn't match anything we know about. raise InvalidResourceException(url) # Note: This will break if there are multiple parameters that could be # specified at a given level. As far as I can tell, this never happens and # never should happen. But in theory it's possible so we'll keep an eye # out for this issue. # No more tokens, so look for a parser. if None not in cur_level: raise InvalidResourceException(url) subcollection, parser = cur_level[None] params = dict(zip(parser.collection_info.GetParams(subcollection), params)) return parser.ParseResourceId( None, params, base_url=endpoint, subcollection=subcollection)
def ParseURL(self, url): """Parse a URL into a Resource. This method does not yet handle "api.google.com" in place of "www.googleapis.com/api/version". Searches self.parsers_by_url to find a _ResourceParser. The parsers_by_url attribute is a deeply nested dictionary, where each key corresponds to a URL segment. The first segment is an API's base URL (eg. "https://www.googleapis.com/compute/v1/"), and after that it's each remaining token in the URL, split on '/'. Then a path down the tree is followed, keyed by the extracted pieces of the provided URL. If the key in the tree is a literal string, like "project" in .../project/{project}/..., the token from the URL must match exactly. If it's a parameter, like "{project}", then any token can match it, and that token is stored in a dict of params to with the associated key ("project" in this case). If there are no URL tokens left, and one of the keys at the current level is None, the None points to a _ResourceParser that can turn the collected params into a Resource. Args: url: str, The URL of the resource. Returns: Resource, The resource indicated by the provided URL. Raises: InvalidResourceException: If the provided URL could not be turned into a cloud resource. """ match = _URL_RE.match(url) if not match: raise InvalidResourceException(url, reason='unknown API host') # pylint:disable=protected-access default_enpoint_url = apis_internal._GetDefaultEndpointUrl(url) api_name, api_version, resource_path = ( resource_util.SplitDefaultEndpointUrl(default_enpoint_url)) # Force hyphenated API names to use underscores to conform with apitools # generated clients api_name = api_name.replace('-', '_') if not url.startswith(default_enpoint_url): # Use last registered api version in case of override. api_version = self.registered_apis.get(api_name, [api_version])[-1] try: versions = apis_internal._GetVersions(api_name) except apis_util.UnknownAPIError: raise InvalidResourceException(url, 'unknown api {}'.format(api_name)) if api_version not in versions: raise InvalidResourceException( url, 'unknown api version {}'.format(api_version)) tokens = [api_name, api_version] + resource_path.split('/') endpoint = url[:-len(resource_path)] # Register relevant API if necessary and possible try: self.RegisterApiByName(api_name, api_version=api_version) except apis_util.UnknownAPIError: raise InvalidResourceException(url, 'unknown api {}'.format(api_name)) except apis_util.UnknownVersionError: raise InvalidResourceException( url, 'unknown api version {}'.format(api_version)) params = [] cur_level = self.parsers_by_url for i, token in enumerate(tokens): if token in cur_level: # If the literal token is already here, follow it down. cur_level = cur_level[token] continue # If the literal token is not here, see if this can be a parameter. param, next_level = '', {} # Predefine these to silence linter. for param, next_level in six.iteritems(cur_level): if param == '{}': break else: raise InvalidResourceException( url, reason='Could not parse at [{}]'.format(token)) if len(next_level) == 1 and None in next_level: # This is the last parameter so we can combine the remaining tokens. token = '/'.join(tokens[i:]) params.append(urllib.parse.unquote(token)) cur_level = next_level break # Clean up the provided value params.append(urllib.parse.unquote(token)) # Keep digging down. cur_level = next_level # No more tokens, so look for a parser. if None not in cur_level: raise InvalidResourceException(url, 'Url too short.') subcollection, parser = cur_level[None] params = dict(zip(parser.collection_info.GetParams(subcollection), params)) return parser.ParseResourceId( None, params, base_url=endpoint, subcollection=subcollection)