From 7a38243c351b228d103eee81fc5ae521ad1c930e Mon Sep 17 00:00:00 2001 From: Tres Seaver Date: Mon, 14 Dec 2020 17:28:21 -0500 Subject: [PATCH 1/3] fix: support 'retry' for ops built from HTTP/gRPC responses (#115) Closes #87. --- google/api_core/operation.py | 17 +++++++++++++--- tests/unit/test_operation.py | 39 +++++++++++++++++++++++++++++++++++- 2 files changed, 52 insertions(+), 4 deletions(-) diff --git a/google/api_core/operation.py b/google/api_core/operation.py index 55adbdd8..9af9c4e6 100644 --- a/google/api_core/operation.py +++ b/google/api_core/operation.py @@ -192,7 +192,7 @@ def cancelled(self): ) -def _refresh_http(api_request, operation_name): +def _refresh_http(api_request, operation_name, retry=None): """Refresh an operation using a JSON/HTTP client. Args: @@ -200,11 +200,16 @@ def _refresh_http(api_request, operation_name): should generally be :meth:`google.cloud._http.Connection.api_request`. operation_name (str): The name of the operation. + retry (google.api_core.retry.Retry): (Optional) retry policy Returns: google.longrunning.operations_pb2.Operation: The operation. """ path = "operations/{}".format(operation_name) + + if retry is not None: + api_request = retry(api_request) + api_response = api_request(method="GET", path=path) return json_format.ParseDict(api_response, operations_pb2.Operation()) @@ -249,19 +254,25 @@ def from_http_json(operation, api_request, result_type, **kwargs): return Operation(operation_proto, refresh, cancel, result_type, **kwargs) -def _refresh_grpc(operations_stub, operation_name): +def _refresh_grpc(operations_stub, operation_name, retry=None): """Refresh an operation using a gRPC client. Args: operations_stub (google.longrunning.operations_pb2.OperationsStub): The gRPC operations stub. operation_name (str): The name of the operation. + retry (google.api_core.retry.Retry): (Optional) retry policy Returns: google.longrunning.operations_pb2.Operation: The operation. """ request_pb = operations_pb2.GetOperationRequest(name=operation_name) - return operations_stub.GetOperation(request_pb) + + rpc = operations_stub.GetOperation + if retry is not None: + rpc = retry(rpc) + + return rpc(request_pb) def _cancel_grpc(operations_stub, operation_name): diff --git a/tests/unit/test_operation.py b/tests/unit/test_operation.py index 829a3f3b..2229c2d4 100644 --- a/tests/unit/test_operation.py +++ b/tests/unit/test_operation.py @@ -177,17 +177,39 @@ def test_unexpected_result(): def test__refresh_http(): - api_request = mock.Mock(return_value={"name": TEST_OPERATION_NAME, "done": True}) + json_response = {"name": TEST_OPERATION_NAME, "done": True} + api_request = mock.Mock(return_value=json_response) result = operation._refresh_http(api_request, TEST_OPERATION_NAME) + assert isinstance(result, operations_pb2.Operation) assert result.name == TEST_OPERATION_NAME assert result.done is True + api_request.assert_called_once_with( method="GET", path="operations/{}".format(TEST_OPERATION_NAME) ) +def test__refresh_http_w_retry(): + json_response = {"name": TEST_OPERATION_NAME, "done": True} + api_request = mock.Mock() + retry = mock.Mock() + retry.return_value.return_value = json_response + + result = operation._refresh_http(api_request, TEST_OPERATION_NAME, retry=retry) + + assert isinstance(result, operations_pb2.Operation) + assert result.name == TEST_OPERATION_NAME + assert result.done is True + + api_request.assert_not_called() + retry.assert_called_once_with(api_request) + retry.return_value.assert_called_once_with( + method="GET", path="operations/{}".format(TEST_OPERATION_NAME) + ) + + def test__cancel_http(): api_request = mock.Mock() @@ -224,6 +246,21 @@ def test__refresh_grpc(): operations_stub.GetOperation.assert_called_once_with(expected_request) +def test__refresh_grpc_w_retry(): + operations_stub = mock.Mock(spec=["GetOperation"]) + expected_result = make_operation_proto(done=True) + retry = mock.Mock() + retry.return_value.return_value = expected_result + + result = operation._refresh_grpc(operations_stub, TEST_OPERATION_NAME, retry=retry) + + assert result == expected_result + expected_request = operations_pb2.GetOperationRequest(name=TEST_OPERATION_NAME) + operations_stub.GetOperation.assert_not_called() + retry.assert_called_once_with(operations_stub.GetOperation) + retry.return_value.assert_called_once_with(expected_request) + + def test__cancel_grpc(): operations_stub = mock.Mock(spec=["CancelOperation"]) From 1dec3018a0776ff5e32738c867e0f0f8d8cb24d8 Mon Sep 17 00:00:00 2001 From: Yoshi Automation Bot Date: Wed, 16 Dec 2020 09:44:46 -0800 Subject: [PATCH 2/3] chore(deps): update precommit hook pre-commit/pre-commit-hooks to v3.4.0 (#119) * chore(deps): update precommit hook pre-commit/pre-commit-hooks to v3.3.0 Source-Author: WhiteSource Renovate Source-Date: Wed Dec 2 17:18:24 2020 +0100 Source-Repo: googleapis/synthtool Source-Sha: 69629b64b83c6421d616be2b8e11795738ec8a6c Source-Link: https://github.com/googleapis/synthtool/commit/69629b64b83c6421d616be2b8e11795738ec8a6c * chore(deps): update precommit hook pre-commit/pre-commit-hooks to v3.4.0 Co-authored-by: Tres Seaver Source-Author: WhiteSource Renovate Source-Date: Wed Dec 16 18:13:24 2020 +0100 Source-Repo: googleapis/synthtool Source-Sha: aa255b15d52b6d8950cca48cfdf58f7d27a60c8a Source-Link: https://github.com/googleapis/synthtool/commit/aa255b15d52b6d8950cca48cfdf58f7d27a60c8a --- .pre-commit-config.yaml | 2 +- synth.metadata | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 6ad83346..a9024b15 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -2,7 +2,7 @@ # See https://pre-commit.com/hooks.html for more hooks repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v3.3.0 + rev: v3.4.0 hooks: - id: trailing-whitespace - id: end-of-file-fixer diff --git a/synth.metadata b/synth.metadata index e401af95..5885a7d8 100644 --- a/synth.metadata +++ b/synth.metadata @@ -4,14 +4,14 @@ "git": { "name": ".", "remote": "https://github.com/googleapis/python-api-core.git", - "sha": "93976931f231da6b42304bd117d8481067c55f6a" + "sha": "7a38243c351b228d103eee81fc5ae521ad1c930e" } }, { "git": { "name": "synthtool", "remote": "https://github.com/googleapis/synthtool.git", - "sha": "32af6da519a6b042e3da62008e2a75e991efb6b4" + "sha": "aa255b15d52b6d8950cca48cfdf58f7d27a60c8a" } } ], From 4e12b76573e2a1726b0a59a5accc99532e010732 Mon Sep 17 00:00:00 2001 From: "release-please[bot]" <55107282+release-please[bot]@users.noreply.github.com> Date: Wed, 16 Dec 2020 13:05:29 -0500 Subject: [PATCH 3/3] chore: release 1.24.1 (#116) Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com> --- CHANGELOG.md | 7 +++++++ google/api_core/version.py | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ad77145c..9bf420a4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-api-core/#history +### [1.24.1](https://www.github.com/googleapis/python-api-core/compare/v1.24.0...v1.24.1) (2020-12-16) + + +### Bug Fixes + +* support 'retry' for ops built from HTTP/gRPC responses ([#115](https://www.github.com/googleapis/python-api-core/issues/115)) ([7a38243](https://www.github.com/googleapis/python-api-core/commit/7a38243c351b228d103eee81fc5ae521ad1c930e)), closes [#87](https://www.github.com/googleapis/python-api-core/issues/87) + ## [1.24.0](https://www.github.com/googleapis/python-api-core/compare/v1.23.0...v1.24.0) (2020-12-14) diff --git a/google/api_core/version.py b/google/api_core/version.py index 246eed12..10f4d5b9 100644 --- a/google/api_core/version.py +++ b/google/api_core/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "1.24.0" +__version__ = "1.24.1"