diff --git a/googleapiclient/discovery.py b/googleapiclient/discovery.py index c7981157f22..7244c5bd610 100644 --- a/googleapiclient/discovery.py +++ b/googleapiclient/discovery.py @@ -29,7 +29,7 @@ # Standard library imports import copy - +from collections import OrderedDict try: from email.generator import BytesGenerator except ImportError: @@ -241,7 +241,8 @@ def build( else: discovery_http = http - for discovery_url in (discoveryServiceUrl, V2_DISCOVERY_URI): + for discovery_url in \ + _discovery_service_uri_options(discoveryServiceUrl, version): requested_url = uritemplate.expand(discovery_url, params) try: @@ -270,6 +271,29 @@ def build( raise UnknownApiNameOrVersion("name: %s version: %s" % (serviceName, version)) +def _discovery_service_uri_options(discoveryServiceUrl, version): + """ + Returns Discovery URIs to be used for attemnting to build the API Resource. + + Args: + discoveryServiceUrl: + string, the Original Discovery Service URL preferred by the customer. + version: + string, API Version requested + + Returns: + A list of URIs to be tried for the Service Discovery, in order. + """ + + urls = [discoveryServiceUrl, V2_DISCOVERY_URI] + # V1 Discovery won't work if the requested version is None + if discoveryServiceUrl == V1_DISCOVERY_URI and version is None: + logger.warning( + "Discovery V1 does not support empty versions. Defaulting to V2...") + urls.pop(0) + return list(OrderedDict.fromkeys(urls)) + + def _retrieve_discovery_doc(url, http, cache_discovery, cache=None, developerKey=None, num_retries=1): """Retrieves the discovery_doc from cache or the internet. diff --git a/tests/test_discovery.py b/tests/test_discovery.py index f59ea151df5..87cc8ed0d4c 100644 --- a/tests/test_discovery.py +++ b/tests/test_discovery.py @@ -837,6 +837,37 @@ def test_api_endpoint_override_from_client_options_dict(self): ) self.assertEqual(zoo._baseUrl, api_endpoint) + def test_discovery_with_empty_version_uses_v2(self): + http = HttpMockSequence( + [ + ({"status": "200"}, read_datafile("zoo.json", "rb")), + ] + ) + build("zoo", version=None, http=http, cache_discovery=False) + validate_discovery_requests(self, http, "zoo", None, V2_DISCOVERY_URI) + + def test_discovery_with_empty_version_preserves_custom_uri(self): + http = HttpMockSequence( + [ + ({"status": "200"}, read_datafile("zoo.json", "rb")), + ] + ) + custom_discovery_uri = "https://foo.bar/$discovery" + build( + "zoo", version=None, http=http, + cache_discovery=False, discoveryServiceUrl=custom_discovery_uri) + validate_discovery_requests( + self, http, "zoo", None, custom_discovery_uri) + + def test_discovery_with_valid_version_uses_v1(self): + http = HttpMockSequence( + [ + ({"status": "200"}, read_datafile("zoo.json", "rb")), + ] + ) + build("zoo", version="v123", http=http, cache_discovery=False) + validate_discovery_requests(self, http, "zoo", "v123", V1_DISCOVERY_URI) + class DiscoveryRetryFromHttp(unittest.TestCase): def test_repeated_500_retries_and_fails(self):