google-api-core 2.24.2__tar.gz → 2.25.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {google_api_core-2.24.2/google_api_core.egg-info → google_api_core-2.25.0}/PKG-INFO +8 -8
- {google_api_core-2.24.2 → google_api_core-2.25.0}/google/api_core/bidi.py +2 -1
- {google_api_core-2.24.2 → google_api_core-2.25.0}/google/api_core/client_info.py +6 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/google/api_core/gapic_v1/client_info.py +1 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/google/api_core/retry/retry_base.py +13 -4
- {google_api_core-2.24.2 → google_api_core-2.25.0}/google/api_core/retry/retry_streaming.py +7 -6
- {google_api_core-2.24.2 → google_api_core-2.25.0}/google/api_core/retry/retry_streaming_async.py +8 -5
- {google_api_core-2.24.2 → google_api_core-2.25.0}/google/api_core/retry/retry_unary.py +7 -6
- {google_api_core-2.24.2 → google_api_core-2.25.0}/google/api_core/retry/retry_unary_async.py +7 -6
- {google_api_core-2.24.2 → google_api_core-2.25.0}/google/api_core/version.py +1 -1
- {google_api_core-2.24.2 → google_api_core-2.25.0/google_api_core.egg-info}/PKG-INFO +8 -8
- {google_api_core-2.24.2 → google_api_core-2.25.0}/google_api_core.egg-info/requires.txt +7 -7
- {google_api_core-2.24.2 → google_api_core-2.25.0}/pyproject.toml +7 -7
- {google_api_core-2.24.2 → google_api_core-2.25.0}/tests/asyncio/gapic/test_method_async.py +1 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/tests/asyncio/retry/test_retry_streaming_async.py +32 -3
- {google_api_core-2.24.2 → google_api_core-2.25.0}/tests/asyncio/retry/test_retry_unary_async.py +26 -1
- {google_api_core-2.24.2 → google_api_core-2.25.0}/tests/unit/gapic/test_method.py +1 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/tests/unit/retry/test_retry_streaming.py +32 -3
- {google_api_core-2.24.2 → google_api_core-2.25.0}/tests/unit/retry/test_retry_unary.py +27 -1
- {google_api_core-2.24.2 → google_api_core-2.25.0}/tests/unit/test_bidi.py +24 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/tests/unit/test_client_info.py +8 -2
- {google_api_core-2.24.2 → google_api_core-2.25.0}/LICENSE +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/MANIFEST.in +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/README.rst +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/google/api_core/__init__.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/google/api_core/_rest_streaming_base.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/google/api_core/client_logging.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/google/api_core/client_options.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/google/api_core/datetime_helpers.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/google/api_core/exceptions.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/google/api_core/extended_operation.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/google/api_core/future/__init__.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/google/api_core/future/_helpers.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/google/api_core/future/async_future.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/google/api_core/future/base.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/google/api_core/future/polling.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/google/api_core/gapic_v1/__init__.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/google/api_core/gapic_v1/config.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/google/api_core/gapic_v1/config_async.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/google/api_core/gapic_v1/method.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/google/api_core/gapic_v1/method_async.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/google/api_core/gapic_v1/routing_header.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/google/api_core/general_helpers.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/google/api_core/grpc_helpers.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/google/api_core/grpc_helpers_async.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/google/api_core/iam.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/google/api_core/operation.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/google/api_core/operation_async.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/google/api_core/operations_v1/__init__.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/google/api_core/operations_v1/abstract_operations_base_client.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/google/api_core/operations_v1/abstract_operations_client.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/google/api_core/operations_v1/operations_async_client.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/google/api_core/operations_v1/operations_client.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/google/api_core/operations_v1/operations_client_config.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/google/api_core/operations_v1/operations_rest_client_async.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/google/api_core/operations_v1/pagers.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/google/api_core/operations_v1/pagers_async.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/google/api_core/operations_v1/pagers_base.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/google/api_core/operations_v1/transports/__init__.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/google/api_core/operations_v1/transports/base.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/google/api_core/operations_v1/transports/rest.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/google/api_core/operations_v1/transports/rest_asyncio.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/google/api_core/page_iterator.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/google/api_core/page_iterator_async.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/google/api_core/path_template.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/google/api_core/protobuf_helpers.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/google/api_core/py.typed +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/google/api_core/rest_helpers.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/google/api_core/rest_streaming.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/google/api_core/rest_streaming_async.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/google/api_core/retry/__init__.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/google/api_core/retry_async.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/google/api_core/timeout.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/google/api_core/universe.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/google/api_core/version_header.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/google_api_core.egg-info/SOURCES.txt +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/google_api_core.egg-info/dependency_links.txt +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/google_api_core.egg-info/top_level.txt +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/setup.cfg +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/setup.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/tests/__init__.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/tests/asyncio/__init__.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/tests/asyncio/future/__init__.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/tests/asyncio/future/test_async_future.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/tests/asyncio/gapic/test_config_async.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/tests/asyncio/operations_v1/__init__.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/tests/asyncio/operations_v1/test_operations_async_client.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/tests/asyncio/retry/__init__.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/tests/asyncio/test_grpc_helpers_async.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/tests/asyncio/test_operation_async.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/tests/asyncio/test_page_iterator_async.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/tests/asyncio/test_rest_streaming_async.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/tests/helpers.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/tests/unit/__init__.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/tests/unit/future/__init__.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/tests/unit/future/test__helpers.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/tests/unit/future/test_polling.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/tests/unit/gapic/test_client_info.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/tests/unit/gapic/test_config.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/tests/unit/gapic/test_routing_header.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/tests/unit/operations_v1/__init__.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/tests/unit/operations_v1/test_operations_client.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/tests/unit/operations_v1/test_operations_rest_client.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/tests/unit/retry/__init__.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/tests/unit/retry/test_retry_base.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/tests/unit/retry/test_retry_imports.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/tests/unit/test_client_logging.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/tests/unit/test_client_options.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/tests/unit/test_datetime_helpers.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/tests/unit/test_exceptions.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/tests/unit/test_extended_operation.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/tests/unit/test_grpc_helpers.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/tests/unit/test_iam.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/tests/unit/test_operation.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/tests/unit/test_packaging.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/tests/unit/test_page_iterator.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/tests/unit/test_path_template.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/tests/unit/test_protobuf_helpers.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/tests/unit/test_rest_helpers.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/tests/unit/test_rest_streaming.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/tests/unit/test_timeout.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/tests/unit/test_universe.py +0 -0
- {google_api_core-2.24.2 → google_api_core-2.25.0}/tests/unit/test_version_header.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: google-api-core
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.25.0
|
|
4
4
|
Summary: Google API client core library
|
|
5
5
|
Author-email: Google LLC <googleapis-packages@google.com>
|
|
6
6
|
License: Apache 2.0
|
|
@@ -30,16 +30,16 @@ Requires-Dist: proto-plus<2.0.0,>=1.25.0; python_version >= "3.13"
|
|
|
30
30
|
Requires-Dist: google-auth<3.0.0,>=2.14.1
|
|
31
31
|
Requires-Dist: requests<3.0.0,>=2.18.0
|
|
32
32
|
Provides-Extra: async-rest
|
|
33
|
-
Requires-Dist: google-auth[aiohttp]<3.0.
|
|
33
|
+
Requires-Dist: google-auth[aiohttp]<3.0.0,>=2.35.0; extra == "async-rest"
|
|
34
34
|
Provides-Extra: grpc
|
|
35
|
-
Requires-Dist: grpcio<2.
|
|
36
|
-
Requires-Dist: grpcio<2.
|
|
37
|
-
Requires-Dist: grpcio-status<2.0.
|
|
38
|
-
Requires-Dist: grpcio-status<2.0.
|
|
35
|
+
Requires-Dist: grpcio<2.0.0,>=1.33.2; extra == "grpc"
|
|
36
|
+
Requires-Dist: grpcio<2.0.0,>=1.49.1; python_version >= "3.11" and extra == "grpc"
|
|
37
|
+
Requires-Dist: grpcio-status<2.0.0,>=1.33.2; extra == "grpc"
|
|
38
|
+
Requires-Dist: grpcio-status<2.0.0,>=1.49.1; python_version >= "3.11" and extra == "grpc"
|
|
39
39
|
Provides-Extra: grpcgcp
|
|
40
|
-
Requires-Dist: grpcio-gcp<1.0.
|
|
40
|
+
Requires-Dist: grpcio-gcp<1.0.0,>=0.2.2; extra == "grpcgcp"
|
|
41
41
|
Provides-Extra: grpcio-gcp
|
|
42
|
-
Requires-Dist: grpcio-gcp<1.0.
|
|
42
|
+
Requires-Dist: grpcio-gcp<1.0.0,>=0.2.2; extra == "grpcio-gcp"
|
|
43
43
|
|
|
44
44
|
Core Library for Google Client Libraries
|
|
45
45
|
========================================
|
|
@@ -664,7 +664,8 @@ class BackgroundConsumer(object):
|
|
|
664
664
|
_LOGGER.debug("waiting for recv.")
|
|
665
665
|
response = self._bidi_rpc.recv()
|
|
666
666
|
_LOGGER.debug("recved response.")
|
|
667
|
-
self._on_response
|
|
667
|
+
if self._on_response is not None:
|
|
668
|
+
self._on_response(response)
|
|
668
669
|
|
|
669
670
|
except exceptions.GoogleAPICallError as exc:
|
|
670
671
|
_LOGGER.debug(
|
|
@@ -59,6 +59,7 @@ class ClientInfo(object):
|
|
|
59
59
|
Recommended format: ``application-or-tool-ID/major.minor.version``.
|
|
60
60
|
rest_version (Optional[str]): A string with labeled versions of the
|
|
61
61
|
dependencies used for REST transport.
|
|
62
|
+
protobuf_runtime_version (Optional[str]): The protobuf runtime version.
|
|
62
63
|
"""
|
|
63
64
|
|
|
64
65
|
def __init__(
|
|
@@ -70,6 +71,7 @@ class ClientInfo(object):
|
|
|
70
71
|
client_library_version=None,
|
|
71
72
|
user_agent=None,
|
|
72
73
|
rest_version=None,
|
|
74
|
+
protobuf_runtime_version=None,
|
|
73
75
|
):
|
|
74
76
|
self.python_version = python_version
|
|
75
77
|
self.grpc_version = grpc_version
|
|
@@ -78,6 +80,7 @@ class ClientInfo(object):
|
|
|
78
80
|
self.client_library_version = client_library_version
|
|
79
81
|
self.user_agent = user_agent
|
|
80
82
|
self.rest_version = rest_version
|
|
83
|
+
self.protobuf_runtime_version = protobuf_runtime_version
|
|
81
84
|
|
|
82
85
|
def to_user_agent(self):
|
|
83
86
|
"""Returns the user-agent string for this client info."""
|
|
@@ -105,4 +108,7 @@ class ClientInfo(object):
|
|
|
105
108
|
if self.client_library_version is not None:
|
|
106
109
|
ua += "gccl/{client_library_version} "
|
|
107
110
|
|
|
111
|
+
if self.protobuf_runtime_version is not None:
|
|
112
|
+
ua += "pb/{protobuf_runtime_version} "
|
|
113
|
+
|
|
108
114
|
return ua.format(**self.__dict__).strip()
|
|
@@ -47,6 +47,7 @@ class ClientInfo(client_info.ClientInfo):
|
|
|
47
47
|
Recommended format: ``application-or-tool-ID/major.minor.version``.
|
|
48
48
|
rest_version (Optional[str]): A string with labeled versions of the
|
|
49
49
|
dependencies used for REST transport.
|
|
50
|
+
protobuf_runtime_version (Optional[str]): The protobuf runtime version.
|
|
50
51
|
"""
|
|
51
52
|
|
|
52
53
|
def to_grpc_metadata(self):
|
|
@@ -25,7 +25,7 @@ import random
|
|
|
25
25
|
import time
|
|
26
26
|
|
|
27
27
|
from enum import Enum
|
|
28
|
-
from typing import Any, Callable, Optional, TYPE_CHECKING
|
|
28
|
+
from typing import Any, Callable, Optional, Iterator, TYPE_CHECKING
|
|
29
29
|
|
|
30
30
|
import requests.exceptions
|
|
31
31
|
|
|
@@ -174,7 +174,7 @@ def build_retry_error(
|
|
|
174
174
|
def _retry_error_helper(
|
|
175
175
|
exc: Exception,
|
|
176
176
|
deadline: float | None,
|
|
177
|
-
|
|
177
|
+
sleep_iterator: Iterator[float],
|
|
178
178
|
error_list: list[Exception],
|
|
179
179
|
predicate_fn: Callable[[Exception], bool],
|
|
180
180
|
on_error_fn: Callable[[Exception], None] | None,
|
|
@@ -183,7 +183,7 @@ def _retry_error_helper(
|
|
|
183
183
|
tuple[Exception, Exception | None],
|
|
184
184
|
],
|
|
185
185
|
original_timeout: float | None,
|
|
186
|
-
):
|
|
186
|
+
) -> float:
|
|
187
187
|
"""
|
|
188
188
|
Shared logic for handling an error for all retry implementations
|
|
189
189
|
|
|
@@ -194,13 +194,15 @@ def _retry_error_helper(
|
|
|
194
194
|
Args:
|
|
195
195
|
- exc: the exception that was raised
|
|
196
196
|
- deadline: the deadline for the retry, calculated as a diff from time.monotonic()
|
|
197
|
-
-
|
|
197
|
+
- sleep_iterator: iterator to draw the next backoff value from
|
|
198
198
|
- error_list: the list of exceptions that have been raised so far
|
|
199
199
|
- predicate_fn: takes `exc` and returns true if the operation should be retried
|
|
200
200
|
- on_error_fn: callback to execute when a retryable error occurs
|
|
201
201
|
- exc_factory_fn: callback used to build the exception to be raised on terminal failure
|
|
202
202
|
- original_timeout_val: the original timeout value for the retry (in seconds),
|
|
203
203
|
to be passed to the exception factory for building an error message
|
|
204
|
+
Returns:
|
|
205
|
+
- the sleep value chosen before the next attempt
|
|
204
206
|
"""
|
|
205
207
|
error_list.append(exc)
|
|
206
208
|
if not predicate_fn(exc):
|
|
@@ -212,6 +214,12 @@ def _retry_error_helper(
|
|
|
212
214
|
raise final_exc from source_exc
|
|
213
215
|
if on_error_fn is not None:
|
|
214
216
|
on_error_fn(exc)
|
|
217
|
+
# next_sleep is fetched after the on_error callback, to allow clients
|
|
218
|
+
# to update sleep_iterator values dynamically in response to errors
|
|
219
|
+
try:
|
|
220
|
+
next_sleep = next(sleep_iterator)
|
|
221
|
+
except StopIteration:
|
|
222
|
+
raise ValueError("Sleep generator stopped yielding sleep values.") from exc
|
|
215
223
|
if deadline is not None and time.monotonic() + next_sleep > deadline:
|
|
216
224
|
final_exc, source_exc = exc_factory_fn(
|
|
217
225
|
error_list,
|
|
@@ -222,6 +230,7 @@ def _retry_error_helper(
|
|
|
222
230
|
_LOGGER.debug(
|
|
223
231
|
"Retrying due to {}, sleeping {:.1f}s ...".format(error_list[-1], next_sleep)
|
|
224
232
|
)
|
|
233
|
+
return next_sleep
|
|
225
234
|
|
|
226
235
|
|
|
227
236
|
class _BaseRetry(object):
|
|
@@ -107,8 +107,11 @@ def retry_target_stream(
|
|
|
107
107
|
time.monotonic() + timeout if timeout is not None else None
|
|
108
108
|
)
|
|
109
109
|
error_list: list[Exception] = []
|
|
110
|
+
sleep_iter = iter(sleep_generator)
|
|
110
111
|
|
|
111
|
-
|
|
112
|
+
# continue trying until an attempt completes, or a terminal exception is raised in _retry_error_helper
|
|
113
|
+
# TODO: support max_attempts argument: https://github.com/googleapis/python-api-core/issues/535
|
|
114
|
+
while True:
|
|
112
115
|
# Start a new retry loop
|
|
113
116
|
try:
|
|
114
117
|
# Note: in the future, we can add a ResumptionStrategy object
|
|
@@ -121,10 +124,10 @@ def retry_target_stream(
|
|
|
121
124
|
# This function explicitly must deal with broad exceptions.
|
|
122
125
|
except Exception as exc:
|
|
123
126
|
# defer to shared logic for handling errors
|
|
124
|
-
_retry_error_helper(
|
|
127
|
+
next_sleep = _retry_error_helper(
|
|
125
128
|
exc,
|
|
126
129
|
deadline,
|
|
127
|
-
|
|
130
|
+
sleep_iter,
|
|
128
131
|
error_list,
|
|
129
132
|
predicate,
|
|
130
133
|
on_error,
|
|
@@ -132,9 +135,7 @@ def retry_target_stream(
|
|
|
132
135
|
timeout,
|
|
133
136
|
)
|
|
134
137
|
# if exception not raised, sleep before next attempt
|
|
135
|
-
time.sleep(
|
|
136
|
-
|
|
137
|
-
raise ValueError("Sleep generator stopped yielding sleep values.")
|
|
138
|
+
time.sleep(next_sleep)
|
|
138
139
|
|
|
139
140
|
|
|
140
141
|
class StreamingRetry(_BaseRetry):
|
{google_api_core-2.24.2 → google_api_core-2.25.0}/google/api_core/retry/retry_streaming_async.py
RENAMED
|
@@ -109,9 +109,12 @@ async def retry_target_stream(
|
|
|
109
109
|
deadline = time.monotonic() + timeout if timeout else None
|
|
110
110
|
# keep track of retryable exceptions we encounter to pass in to exception_factory
|
|
111
111
|
error_list: list[Exception] = []
|
|
112
|
+
sleep_iter = iter(sleep_generator)
|
|
112
113
|
target_is_generator: bool | None = None
|
|
113
114
|
|
|
114
|
-
|
|
115
|
+
# continue trying until an attempt completes, or a terminal exception is raised in _retry_error_helper
|
|
116
|
+
# TODO: support max_attempts argument: https://github.com/googleapis/python-api-core/issues/535
|
|
117
|
+
while True:
|
|
115
118
|
# Start a new retry loop
|
|
116
119
|
try:
|
|
117
120
|
# Note: in the future, we can add a ResumptionStrategy object
|
|
@@ -174,10 +177,10 @@ async def retry_target_stream(
|
|
|
174
177
|
# This function explicitly must deal with broad exceptions.
|
|
175
178
|
except Exception as exc:
|
|
176
179
|
# defer to shared logic for handling errors
|
|
177
|
-
_retry_error_helper(
|
|
180
|
+
next_sleep = _retry_error_helper(
|
|
178
181
|
exc,
|
|
179
182
|
deadline,
|
|
180
|
-
|
|
183
|
+
sleep_iter,
|
|
181
184
|
error_list,
|
|
182
185
|
predicate,
|
|
183
186
|
on_error,
|
|
@@ -185,11 +188,11 @@ async def retry_target_stream(
|
|
|
185
188
|
timeout,
|
|
186
189
|
)
|
|
187
190
|
# if exception not raised, sleep before next attempt
|
|
188
|
-
await asyncio.sleep(
|
|
191
|
+
await asyncio.sleep(next_sleep)
|
|
192
|
+
|
|
189
193
|
finally:
|
|
190
194
|
if target_is_generator and target_iterator is not None:
|
|
191
195
|
await cast(AsyncGenerator["_Y", None], target_iterator).aclose()
|
|
192
|
-
raise ValueError("Sleep generator stopped yielding sleep values.")
|
|
193
196
|
|
|
194
197
|
|
|
195
198
|
class AsyncStreamingRetry(_BaseRetry):
|
|
@@ -138,8 +138,11 @@ def retry_target(
|
|
|
138
138
|
|
|
139
139
|
deadline = time.monotonic() + timeout if timeout is not None else None
|
|
140
140
|
error_list: list[Exception] = []
|
|
141
|
+
sleep_iter = iter(sleep_generator)
|
|
141
142
|
|
|
142
|
-
|
|
143
|
+
# continue trying until an attempt completes, or a terminal exception is raised in _retry_error_helper
|
|
144
|
+
# TODO: support max_attempts argument: https://github.com/googleapis/python-api-core/issues/535
|
|
145
|
+
while True:
|
|
143
146
|
try:
|
|
144
147
|
result = target()
|
|
145
148
|
if inspect.isawaitable(result):
|
|
@@ -150,10 +153,10 @@ def retry_target(
|
|
|
150
153
|
# This function explicitly must deal with broad exceptions.
|
|
151
154
|
except Exception as exc:
|
|
152
155
|
# defer to shared logic for handling errors
|
|
153
|
-
_retry_error_helper(
|
|
156
|
+
next_sleep = _retry_error_helper(
|
|
154
157
|
exc,
|
|
155
158
|
deadline,
|
|
156
|
-
|
|
159
|
+
sleep_iter,
|
|
157
160
|
error_list,
|
|
158
161
|
predicate,
|
|
159
162
|
on_error,
|
|
@@ -161,9 +164,7 @@ def retry_target(
|
|
|
161
164
|
timeout,
|
|
162
165
|
)
|
|
163
166
|
# if exception not raised, sleep before next attempt
|
|
164
|
-
time.sleep(
|
|
165
|
-
|
|
166
|
-
raise ValueError("Sleep generator stopped yielding sleep values.")
|
|
167
|
+
time.sleep(next_sleep)
|
|
167
168
|
|
|
168
169
|
|
|
169
170
|
class Retry(_BaseRetry):
|
{google_api_core-2.24.2 → google_api_core-2.25.0}/google/api_core/retry/retry_unary_async.py
RENAMED
|
@@ -149,18 +149,21 @@ async def retry_target(
|
|
|
149
149
|
|
|
150
150
|
deadline = time.monotonic() + timeout if timeout is not None else None
|
|
151
151
|
error_list: list[Exception] = []
|
|
152
|
+
sleep_iter = iter(sleep_generator)
|
|
152
153
|
|
|
153
|
-
|
|
154
|
+
# continue trying until an attempt completes, or a terminal exception is raised in _retry_error_helper
|
|
155
|
+
# TODO: support max_attempts argument: https://github.com/googleapis/python-api-core/issues/535
|
|
156
|
+
while True:
|
|
154
157
|
try:
|
|
155
158
|
return await target()
|
|
156
159
|
# pylint: disable=broad-except
|
|
157
160
|
# This function explicitly must deal with broad exceptions.
|
|
158
161
|
except Exception as exc:
|
|
159
162
|
# defer to shared logic for handling errors
|
|
160
|
-
_retry_error_helper(
|
|
163
|
+
next_sleep = _retry_error_helper(
|
|
161
164
|
exc,
|
|
162
165
|
deadline,
|
|
163
|
-
|
|
166
|
+
sleep_iter,
|
|
164
167
|
error_list,
|
|
165
168
|
predicate,
|
|
166
169
|
on_error,
|
|
@@ -168,9 +171,7 @@ async def retry_target(
|
|
|
168
171
|
timeout,
|
|
169
172
|
)
|
|
170
173
|
# if exception not raised, sleep before next attempt
|
|
171
|
-
await asyncio.sleep(
|
|
172
|
-
|
|
173
|
-
raise ValueError("Sleep generator stopped yielding sleep values.")
|
|
174
|
+
await asyncio.sleep(next_sleep)
|
|
174
175
|
|
|
175
176
|
|
|
176
177
|
class AsyncRetry(_BaseRetry):
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: google-api-core
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.25.0
|
|
4
4
|
Summary: Google API client core library
|
|
5
5
|
Author-email: Google LLC <googleapis-packages@google.com>
|
|
6
6
|
License: Apache 2.0
|
|
@@ -30,16 +30,16 @@ Requires-Dist: proto-plus<2.0.0,>=1.25.0; python_version >= "3.13"
|
|
|
30
30
|
Requires-Dist: google-auth<3.0.0,>=2.14.1
|
|
31
31
|
Requires-Dist: requests<3.0.0,>=2.18.0
|
|
32
32
|
Provides-Extra: async-rest
|
|
33
|
-
Requires-Dist: google-auth[aiohttp]<3.0.
|
|
33
|
+
Requires-Dist: google-auth[aiohttp]<3.0.0,>=2.35.0; extra == "async-rest"
|
|
34
34
|
Provides-Extra: grpc
|
|
35
|
-
Requires-Dist: grpcio<2.
|
|
36
|
-
Requires-Dist: grpcio<2.
|
|
37
|
-
Requires-Dist: grpcio-status<2.0.
|
|
38
|
-
Requires-Dist: grpcio-status<2.0.
|
|
35
|
+
Requires-Dist: grpcio<2.0.0,>=1.33.2; extra == "grpc"
|
|
36
|
+
Requires-Dist: grpcio<2.0.0,>=1.49.1; python_version >= "3.11" and extra == "grpc"
|
|
37
|
+
Requires-Dist: grpcio-status<2.0.0,>=1.33.2; extra == "grpc"
|
|
38
|
+
Requires-Dist: grpcio-status<2.0.0,>=1.49.1; python_version >= "3.11" and extra == "grpc"
|
|
39
39
|
Provides-Extra: grpcgcp
|
|
40
|
-
Requires-Dist: grpcio-gcp<1.0.
|
|
40
|
+
Requires-Dist: grpcio-gcp<1.0.0,>=0.2.2; extra == "grpcgcp"
|
|
41
41
|
Provides-Extra: grpcio-gcp
|
|
42
|
-
Requires-Dist: grpcio-gcp<1.0.
|
|
42
|
+
Requires-Dist: grpcio-gcp<1.0.0,>=0.2.2; extra == "grpcio-gcp"
|
|
43
43
|
|
|
44
44
|
Core Library for Google Client Libraries
|
|
45
45
|
========================================
|
|
@@ -8,18 +8,18 @@ requests<3.0.0,>=2.18.0
|
|
|
8
8
|
proto-plus<2.0.0,>=1.25.0
|
|
9
9
|
|
|
10
10
|
[async_rest]
|
|
11
|
-
google-auth[aiohttp]<3.0.
|
|
11
|
+
google-auth[aiohttp]<3.0.0,>=2.35.0
|
|
12
12
|
|
|
13
13
|
[grpc]
|
|
14
|
-
grpcio<2.
|
|
15
|
-
grpcio-status<2.0.
|
|
14
|
+
grpcio<2.0.0,>=1.33.2
|
|
15
|
+
grpcio-status<2.0.0,>=1.33.2
|
|
16
16
|
|
|
17
17
|
[grpc:python_version >= "3.11"]
|
|
18
|
-
grpcio<2.
|
|
19
|
-
grpcio-status<2.0.
|
|
18
|
+
grpcio<2.0.0,>=1.49.1
|
|
19
|
+
grpcio-status<2.0.0,>=1.49.1
|
|
20
20
|
|
|
21
21
|
[grpcgcp]
|
|
22
|
-
grpcio-gcp<1.0.
|
|
22
|
+
grpcio-gcp<1.0.0,>=0.2.2
|
|
23
23
|
|
|
24
24
|
[grpcio-gcp]
|
|
25
|
-
grpcio-gcp<1.0.
|
|
25
|
+
grpcio-gcp<1.0.0,>=0.2.2
|
|
@@ -58,15 +58,15 @@ Documentation = "https://googleapis.dev/python/google-api-core/latest/"
|
|
|
58
58
|
Repository = "https://github.com/googleapis/python-api-core"
|
|
59
59
|
|
|
60
60
|
[project.optional-dependencies]
|
|
61
|
-
async_rest = ["google-auth[aiohttp] >= 2.35.0, < 3.0.
|
|
61
|
+
async_rest = ["google-auth[aiohttp] >= 2.35.0, < 3.0.0"]
|
|
62
62
|
grpc = [
|
|
63
|
-
"grpcio >= 1.33.2, < 2.
|
|
64
|
-
"grpcio >= 1.49.1, < 2.
|
|
65
|
-
"grpcio-status >= 1.33.2, < 2.0.
|
|
66
|
-
"grpcio-status >= 1.49.1, < 2.0.
|
|
63
|
+
"grpcio >= 1.33.2, < 2.0.0",
|
|
64
|
+
"grpcio >= 1.49.1, < 2.0.0; python_version >= '3.11'",
|
|
65
|
+
"grpcio-status >= 1.33.2, < 2.0.0",
|
|
66
|
+
"grpcio-status >= 1.49.1, < 2.0.0; python_version >= '3.11'",
|
|
67
67
|
]
|
|
68
|
-
grpcgcp = ["grpcio-gcp >= 0.2.2, < 1.0.
|
|
69
|
-
grpcio-gcp = ["grpcio-gcp >= 0.2.2, < 1.0.
|
|
68
|
+
grpcgcp = ["grpcio-gcp >= 0.2.2, < 1.0.0"]
|
|
69
|
+
grpcio-gcp = ["grpcio-gcp >= 0.2.2, < 1.0.0"]
|
|
70
70
|
|
|
71
71
|
[tool.setuptools.dynamic]
|
|
72
72
|
version = { attr = "google.api_core.version.__version__" }
|
|
@@ -81,6 +81,7 @@ async def test_wrap_method_with_custom_client_info():
|
|
|
81
81
|
api_core_version=3,
|
|
82
82
|
gapic_version=4,
|
|
83
83
|
client_library_version=5,
|
|
84
|
+
protobuf_runtime_version=6,
|
|
84
85
|
)
|
|
85
86
|
fake_call = grpc_helpers_async.FakeUnaryUnaryCall()
|
|
86
87
|
method = mock.Mock(spec=aio.UnaryUnaryMultiCallable, return_value=fake_call)
|
{google_api_core-2.24.2 → google_api_core-2.25.0}/tests/asyncio/retry/test_retry_streaming_async.py
RENAMED
|
@@ -36,7 +36,36 @@ async def test_retry_streaming_target_bad_sleep_generator():
|
|
|
36
36
|
from google.api_core.retry.retry_streaming_async import retry_target_stream
|
|
37
37
|
|
|
38
38
|
with pytest.raises(ValueError, match="Sleep generator"):
|
|
39
|
-
await retry_target_stream(None,
|
|
39
|
+
await retry_target_stream(None, lambda x: True, [], None).__anext__()
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
@mock.patch("asyncio.sleep", autospec=True)
|
|
43
|
+
@pytest.mark.asyncio
|
|
44
|
+
async def test_retry_streaming_target_dynamic_backoff(sleep):
|
|
45
|
+
"""
|
|
46
|
+
sleep_generator should be iterated after on_error, to support dynamic backoff
|
|
47
|
+
"""
|
|
48
|
+
from functools import partial
|
|
49
|
+
from google.api_core.retry.retry_streaming_async import retry_target_stream
|
|
50
|
+
|
|
51
|
+
sleep.side_effect = RuntimeError("stop after sleep")
|
|
52
|
+
# start with empty sleep generator; values are added after exception in push_sleep_value
|
|
53
|
+
sleep_values = []
|
|
54
|
+
error_target = partial(TestAsyncStreamingRetry._generator_mock, error_on=0)
|
|
55
|
+
inserted_sleep = 99
|
|
56
|
+
|
|
57
|
+
def push_sleep_value(err):
|
|
58
|
+
sleep_values.append(inserted_sleep)
|
|
59
|
+
|
|
60
|
+
with pytest.raises(RuntimeError):
|
|
61
|
+
await retry_target_stream(
|
|
62
|
+
error_target,
|
|
63
|
+
predicate=lambda x: True,
|
|
64
|
+
sleep_generator=sleep_values,
|
|
65
|
+
on_error=push_sleep_value,
|
|
66
|
+
).__anext__()
|
|
67
|
+
assert sleep.call_count == 1
|
|
68
|
+
sleep.assert_called_once_with(inserted_sleep)
|
|
40
69
|
|
|
41
70
|
|
|
42
71
|
class TestAsyncStreamingRetry(Test_BaseRetry):
|
|
@@ -66,8 +95,8 @@ class TestAsyncStreamingRetry(Test_BaseRetry):
|
|
|
66
95
|
str(retry_),
|
|
67
96
|
)
|
|
68
97
|
|
|
98
|
+
@staticmethod
|
|
69
99
|
async def _generator_mock(
|
|
70
|
-
self,
|
|
71
100
|
num=5,
|
|
72
101
|
error_on=None,
|
|
73
102
|
exceptions_seen=None,
|
|
@@ -87,7 +116,7 @@ class TestAsyncStreamingRetry(Test_BaseRetry):
|
|
|
87
116
|
for i in range(num):
|
|
88
117
|
if sleep_time:
|
|
89
118
|
await asyncio.sleep(sleep_time)
|
|
90
|
-
if error_on and i == error_on:
|
|
119
|
+
if error_on is not None and i == error_on:
|
|
91
120
|
raise ValueError("generator mock error")
|
|
92
121
|
yield i
|
|
93
122
|
except (Exception, BaseException, GeneratorExit) as e:
|
{google_api_core-2.24.2 → google_api_core-2.25.0}/tests/asyncio/retry/test_retry_unary_async.py
RENAMED
|
@@ -136,9 +136,34 @@ async def test_retry_target_timeout_exceeded(monotonic, sleep, use_deadline_arg)
|
|
|
136
136
|
@pytest.mark.asyncio
|
|
137
137
|
async def test_retry_target_bad_sleep_generator():
|
|
138
138
|
with pytest.raises(ValueError, match="Sleep generator"):
|
|
139
|
+
await retry_async.retry_target(mock.sentinel.target, lambda x: True, [], None)
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
@mock.patch("asyncio.sleep", autospec=True)
|
|
143
|
+
@pytest.mark.asyncio
|
|
144
|
+
async def test_retry_target_dynamic_backoff(sleep):
|
|
145
|
+
"""
|
|
146
|
+
sleep_generator should be iterated after on_error, to support dynamic backoff
|
|
147
|
+
"""
|
|
148
|
+
sleep.side_effect = RuntimeError("stop after sleep")
|
|
149
|
+
# start with empty sleep generator; values are added after exception in push_sleep_value
|
|
150
|
+
sleep_values = []
|
|
151
|
+
exception = ValueError("trigger retry")
|
|
152
|
+
error_target = mock.Mock(side_effect=exception)
|
|
153
|
+
inserted_sleep = 99
|
|
154
|
+
|
|
155
|
+
def push_sleep_value(err):
|
|
156
|
+
sleep_values.append(inserted_sleep)
|
|
157
|
+
|
|
158
|
+
with pytest.raises(RuntimeError):
|
|
139
159
|
await retry_async.retry_target(
|
|
140
|
-
|
|
160
|
+
error_target,
|
|
161
|
+
predicate=lambda x: True,
|
|
162
|
+
sleep_generator=sleep_values,
|
|
163
|
+
on_error=push_sleep_value,
|
|
141
164
|
)
|
|
165
|
+
assert sleep.call_count == 1
|
|
166
|
+
sleep.assert_called_once_with(inserted_sleep)
|
|
142
167
|
|
|
143
168
|
|
|
144
169
|
class TestAsyncRetry(Test_BaseRetry):
|
|
@@ -33,7 +33,36 @@ def test_retry_streaming_target_bad_sleep_generator():
|
|
|
33
33
|
with pytest.raises(
|
|
34
34
|
ValueError, match="Sleep generator stopped yielding sleep values"
|
|
35
35
|
):
|
|
36
|
-
next(retry_streaming.retry_target_stream(None,
|
|
36
|
+
next(retry_streaming.retry_target_stream(None, lambda x: True, [], None))
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
@mock.patch("time.sleep", autospec=True)
|
|
40
|
+
def test_retry_streaming_target_dynamic_backoff(sleep):
|
|
41
|
+
"""
|
|
42
|
+
sleep_generator should be iterated after on_error, to support dynamic backoff
|
|
43
|
+
"""
|
|
44
|
+
from functools import partial
|
|
45
|
+
|
|
46
|
+
sleep.side_effect = RuntimeError("stop after sleep")
|
|
47
|
+
# start with empty sleep generator; values are added after exception in push_sleep_value
|
|
48
|
+
sleep_values = []
|
|
49
|
+
error_target = partial(TestStreamingRetry._generator_mock, error_on=0)
|
|
50
|
+
inserted_sleep = 99
|
|
51
|
+
|
|
52
|
+
def push_sleep_value(err):
|
|
53
|
+
sleep_values.append(inserted_sleep)
|
|
54
|
+
|
|
55
|
+
with pytest.raises(RuntimeError):
|
|
56
|
+
next(
|
|
57
|
+
retry_streaming.retry_target_stream(
|
|
58
|
+
error_target,
|
|
59
|
+
predicate=lambda x: True,
|
|
60
|
+
sleep_generator=sleep_values,
|
|
61
|
+
on_error=push_sleep_value,
|
|
62
|
+
)
|
|
63
|
+
)
|
|
64
|
+
assert sleep.call_count == 1
|
|
65
|
+
sleep.assert_called_once_with(inserted_sleep)
|
|
37
66
|
|
|
38
67
|
|
|
39
68
|
class TestStreamingRetry(Test_BaseRetry):
|
|
@@ -63,8 +92,8 @@ class TestStreamingRetry(Test_BaseRetry):
|
|
|
63
92
|
str(retry_),
|
|
64
93
|
)
|
|
65
94
|
|
|
95
|
+
@staticmethod
|
|
66
96
|
def _generator_mock(
|
|
67
|
-
self,
|
|
68
97
|
num=5,
|
|
69
98
|
error_on=None,
|
|
70
99
|
return_val=None,
|
|
@@ -82,7 +111,7 @@ class TestStreamingRetry(Test_BaseRetry):
|
|
|
82
111
|
"""
|
|
83
112
|
try:
|
|
84
113
|
for i in range(num):
|
|
85
|
-
if error_on and i == error_on:
|
|
114
|
+
if error_on is not None and i == error_on:
|
|
86
115
|
raise ValueError("generator mock error")
|
|
87
116
|
yield i
|
|
88
117
|
return return_val
|
|
@@ -146,7 +146,33 @@ def test_retry_target_timeout_exceeded(monotonic, sleep, use_deadline_arg):
|
|
|
146
146
|
|
|
147
147
|
def test_retry_target_bad_sleep_generator():
|
|
148
148
|
with pytest.raises(ValueError, match="Sleep generator"):
|
|
149
|
-
retry.retry_target(mock.sentinel.target,
|
|
149
|
+
retry.retry_target(mock.sentinel.target, lambda x: True, [], None)
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
@mock.patch("time.sleep", autospec=True)
|
|
153
|
+
def test_retry_target_dynamic_backoff(sleep):
|
|
154
|
+
"""
|
|
155
|
+
sleep_generator should be iterated after on_error, to support dynamic backoff
|
|
156
|
+
"""
|
|
157
|
+
sleep.side_effect = RuntimeError("stop after sleep")
|
|
158
|
+
# start with empty sleep generator; values are added after exception in push_sleep_value
|
|
159
|
+
sleep_values = []
|
|
160
|
+
exception = ValueError("trigger retry")
|
|
161
|
+
error_target = mock.Mock(side_effect=exception)
|
|
162
|
+
inserted_sleep = 99
|
|
163
|
+
|
|
164
|
+
def push_sleep_value(err):
|
|
165
|
+
sleep_values.append(inserted_sleep)
|
|
166
|
+
|
|
167
|
+
with pytest.raises(RuntimeError):
|
|
168
|
+
retry.retry_target(
|
|
169
|
+
error_target,
|
|
170
|
+
predicate=lambda x: True,
|
|
171
|
+
sleep_generator=sleep_values,
|
|
172
|
+
on_error=push_sleep_value,
|
|
173
|
+
)
|
|
174
|
+
assert sleep.call_count == 1
|
|
175
|
+
sleep.assert_called_once_with(inserted_sleep)
|
|
150
176
|
|
|
151
177
|
|
|
152
178
|
class TestRetry(Test_BaseRetry):
|
|
@@ -16,6 +16,7 @@ import datetime
|
|
|
16
16
|
import logging
|
|
17
17
|
import queue
|
|
18
18
|
import threading
|
|
19
|
+
import time
|
|
19
20
|
|
|
20
21
|
try:
|
|
21
22
|
from unittest import mock
|
|
@@ -894,3 +895,26 @@ class TestBackgroundConsumer(object):
|
|
|
894
895
|
|
|
895
896
|
# calling stop twice should not result in an error.
|
|
896
897
|
consumer.stop()
|
|
898
|
+
|
|
899
|
+
def test_stop_error_logs(self, caplog):
|
|
900
|
+
"""
|
|
901
|
+
Closing the client should result in no internal error logs
|
|
902
|
+
|
|
903
|
+
https://github.com/googleapis/python-api-core/issues/788
|
|
904
|
+
"""
|
|
905
|
+
caplog.set_level(logging.DEBUG)
|
|
906
|
+
bidi_rpc = mock.create_autospec(bidi.BidiRpc, instance=True)
|
|
907
|
+
bidi_rpc.is_active = True
|
|
908
|
+
on_response = mock.Mock(spec=["__call__"])
|
|
909
|
+
|
|
910
|
+
consumer = bidi.BackgroundConsumer(bidi_rpc, on_response)
|
|
911
|
+
|
|
912
|
+
consumer.start()
|
|
913
|
+
consumer.stop()
|
|
914
|
+
# let the background thread run for a while before exiting
|
|
915
|
+
time.sleep(0.1)
|
|
916
|
+
bidi_rpc.is_active = False
|
|
917
|
+
# running thread should not result in error logs
|
|
918
|
+
error_logs = [r.message for r in caplog.records if r.levelname == "ERROR"]
|
|
919
|
+
assert not error_logs, f"Found unexpected ERROR logs: {error_logs}"
|
|
920
|
+
bidi_rpc.is_active = False
|
|
@@ -46,6 +46,7 @@ def test_constructor_options():
|
|
|
46
46
|
client_library_version="5",
|
|
47
47
|
user_agent="6",
|
|
48
48
|
rest_version="7",
|
|
49
|
+
protobuf_runtime_version="8",
|
|
49
50
|
)
|
|
50
51
|
|
|
51
52
|
assert info.python_version == "1"
|
|
@@ -55,11 +56,15 @@ def test_constructor_options():
|
|
|
55
56
|
assert info.client_library_version == "5"
|
|
56
57
|
assert info.user_agent == "6"
|
|
57
58
|
assert info.rest_version == "7"
|
|
59
|
+
assert info.protobuf_runtime_version == "8"
|
|
58
60
|
|
|
59
61
|
|
|
60
62
|
def test_to_user_agent_minimal():
|
|
61
63
|
info = client_info.ClientInfo(
|
|
62
|
-
python_version="1",
|
|
64
|
+
python_version="1",
|
|
65
|
+
api_core_version="2",
|
|
66
|
+
grpc_version=None,
|
|
67
|
+
protobuf_runtime_version=None,
|
|
63
68
|
)
|
|
64
69
|
|
|
65
70
|
user_agent = info.to_user_agent()
|
|
@@ -75,11 +80,12 @@ def test_to_user_agent_full():
|
|
|
75
80
|
gapic_version="4",
|
|
76
81
|
client_library_version="5",
|
|
77
82
|
user_agent="app-name/1.0",
|
|
83
|
+
protobuf_runtime_version="6",
|
|
78
84
|
)
|
|
79
85
|
|
|
80
86
|
user_agent = info.to_user_agent()
|
|
81
87
|
|
|
82
|
-
assert user_agent == "app-name/1.0 gl-python/1 grpc/2 gax/3 gapic/4 gccl/5"
|
|
88
|
+
assert user_agent == "app-name/1.0 gl-python/1 grpc/2 gax/3 gapic/4 gccl/5 pb/6"
|
|
83
89
|
|
|
84
90
|
|
|
85
91
|
def test_to_user_agent_rest():
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{google_api_core-2.24.2 → google_api_core-2.25.0}/google/api_core/gapic_v1/routing_header.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{google_api_core-2.24.2 → google_api_core-2.25.0}/google/api_core/operations_v1/operations_client.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{google_api_core-2.24.2 → google_api_core-2.25.0}/google/api_core/operations_v1/pagers_async.py
RENAMED
|
File without changes
|
{google_api_core-2.24.2 → google_api_core-2.25.0}/google/api_core/operations_v1/pagers_base.py
RENAMED
|
File without changes
|
|
File without changes
|
{google_api_core-2.24.2 → google_api_core-2.25.0}/google/api_core/operations_v1/transports/base.py
RENAMED
|
File without changes
|
{google_api_core-2.24.2 → google_api_core-2.25.0}/google/api_core/operations_v1/transports/rest.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{google_api_core-2.24.2 → google_api_core-2.25.0}/google_api_core.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{google_api_core-2.24.2 → google_api_core-2.25.0}/tests/asyncio/test_rest_streaming_async.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{google_api_core-2.24.2 → google_api_core-2.25.0}/tests/unit/operations_v1/test_operations_client.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|