diff --git a/docs/start.md b/docs/start.md index 414e85fcedb..3d9cb244469 100644 --- a/docs/start.md +++ b/docs/start.md @@ -65,16 +65,7 @@ with build('drive', 'v3') as service: # ... ``` -**Note**: Under the hood, the `build()` function retrieves a discovery artifact in order to construct the service object. If the `cache_discovery` argument of `build()` is set to `True`, the library will attempt to retrieve the discovery artifact from the legacy cache which is only supported with `oauth2client<4.0`. If the artifact is not available in the legacy cache and the `static_discovery` argument of `build()` is set to `True`, the library will attempt to retieve the discovery artifact from the static copy of the discovery artifacts that are shipped with the library. As a last resort if the discovery artifact is not on disk, the discovery artifact will be retrieved from the internet. The maintainers recommend keeping `static_discovery=True`, which is the default, in order to avoid reliability issues related to transient network errors. The library currently does not detect breaking changes of discovery artifacts, and as a result, user code is not guaranteed to continue to succeed or fail with different versions of `google-api-python-client`. Users can set `static_discovery=False` as workaround if there is an incompatible discovery artifact shipped with the library. In addition, users may roll back the version of `google-api-python-client` if there is a breaking change in a discovery artifact. The maintainers of `google-api-python-client` encourage users to report issues with discovery artifacts so that the discovery artifacts can be corrected. - -In the below example, the discovery artifact for `'drive'` version `'v3'` will only be retrieved from the internet if it is not available in the legacy cache and it is not one of the static discovery artifacts shipped with the library. - -```python -from googleapiclient.discovery import build - -with build('drive', 'v3', cache_discovery=True, static_discovery=True): - # ... -``` +**Note**: Under the hood, the `build()` function retrieves a discovery artifact in order to construct the service object. If the `cache_discovery` argument of `build()` is set to `True`, the library will attempt to retrieve the discovery artifact from the legacy cache which is only supported with `oauth2client<4.0`. If the artifact is not available in the legacy cache and the `static_discovery` argument of `build()` is set to `True`, the library will attempt to retieve the discovery artifact from the static copy of the discovery artifacts that are shipped with the library. The maintainers recommend keeping `static_discovery=True`, which is the default, in order to avoid reliability issues related to transient network errors. The library currently does not detect breaking changes of discovery artifacts, and as a result, user code is not guaranteed to continue to succeed or fail with different versions of `google-api-python-client`. Users can set `static_discovery=False` as workaround if there is an incompatible discovery artifact shipped with the library. In addition, users may roll back the version of `google-api-python-client` if there is a breaking change in a discovery artifact. The maintainers of `google-api-python-client` encourage users to report issues with discovery artifacts so that the discovery artifacts can be corrected. ### Collections diff --git a/googleapiclient/discovery.py b/googleapiclient/discovery.py index ee75ca46ba8..44473dc3cbd 100644 --- a/googleapiclient/discovery.py +++ b/googleapiclient/discovery.py @@ -248,8 +248,7 @@ def build( num_retries: Integer, number of times to retry discovery with randomized exponential backoff in case of intermittent/connection issues. static_discovery: Boolean, whether or not to use the static discovery docs - included in the package when the discovery doc is not available in the - cache. + included in the library. Returns: A Resource object with methods for interacting with the service. @@ -363,16 +362,13 @@ def _retrieve_discovery_doc( num_retries: Integer, number of times to retry discovery with randomized exponential backoff in case of intermittent/connection issues. static_discovery: Boolean, whether or not to use the static discovery docs - included in the package when the discovery doc is not available in the - cache. + included in the library. Returns: A unicode string representation of the discovery document. """ from . import discovery_cache - content = None - if cache_discovery: if cache is None: cache = discovery_cache.autodetect() @@ -381,31 +377,30 @@ def _retrieve_discovery_doc( if content: return content - # At this point, the discovery document was not found in the cache so - # we can attempt to retreive the static discovery document from the library. + # When `static_discovery=True`, use static discovery artifacts included + # with the library if static_discovery: content = discovery_cache.get_static_doc(serviceName, version) if content: return content - - # If the content is None, retrieve the discovery doc from the internet - # because it is not in the cache or the static doc directory. - if content is None: - actual_url = url - # REMOTE_ADDR is defined by the CGI spec [RFC3875] as the environment - # variable that contains the network address of the client sending the - # request. If it exists then add that to the request for the discovery - # document to avoid exceeding the quota on discovery requests. - if "REMOTE_ADDR" in os.environ: - actual_url = _add_query_parameter(url, "userIp", os.environ["REMOTE_ADDR"]) - if developerKey: - actual_url = _add_query_parameter(url, "key", developerKey) - logger.debug("URL being requested: GET %s", actual_url) - - # Execute this request with retries build into HttpRequest - # Note that it will already raise an error if we don't get a 2xx response - req = HttpRequest(http, HttpRequest.null_postproc, actual_url) - resp, content = req.execute(num_retries=num_retries) + else: + raise UnknownApiNameOrVersion("name: %s version: %s" % (serviceName, version)) + + actual_url = url + # REMOTE_ADDR is defined by the CGI spec [RFC3875] as the environment + # variable that contains the network address of the client sending the + # request. If it exists then add that to the request for the discovery + # document to avoid exceeding the quota on discovery requests. + if "REMOTE_ADDR" in os.environ: + actual_url = _add_query_parameter(url, "userIp", os.environ["REMOTE_ADDR"]) + if developerKey: + actual_url = _add_query_parameter(url, "key", developerKey) + logger.debug("URL being requested: GET %s", actual_url) + + # Execute this request with retries build into HttpRequest + # Note that it will already raise an error if we don't get a 2xx response + req = HttpRequest(http, HttpRequest.null_postproc, actual_url) + resp, content = req.execute(num_retries=num_retries) try: content = content.decode("utf-8") diff --git a/tests/test_discovery.py b/tests/test_discovery.py index 227b6a030c5..49bb51a0a29 100644 --- a/tests/test_discovery.py +++ b/tests/test_discovery.py @@ -1162,10 +1162,9 @@ def test_retrieve_from_internet_when_static_discovery_false(self): build("drive", "v3", http=http, cache_discovery=False, static_discovery=False) - def test_retrieve_from_internet_when_static_doc_does_not_exist(self): - http = HttpMockSequence([({"status": "400"}, "")]) - with self.assertRaises(HttpError): - build("doesnotexist", "v3", http=http, cache_discovery=False, + def test_unknown_api_when_static_discovery_true(self): + with self.assertRaises(UnknownApiNameOrVersion): + build("doesnotexist", "v3", cache_discovery=False, static_discovery=True)