diff --git a/google/cloud/client.py b/google/cloud/client.py index 0697741..9e09450 100644 --- a/google/cloud/client.py +++ b/google/cloud/client.py @@ -214,6 +214,21 @@ def _http(self): self._http_internal.configure_mtls_channel(self._client_cert_source) return self._http_internal + def close(self): + """Clean up transport, if set. + + Suggested use: + + .. code-block:: python + + import contextlib + + with contextlib.closing(client): # closes on exit + do_something_with(client) + """ + if self._http_internal is not None: + self._http_internal.close() + class _ClientProjectMixin(object): """Mixin to allow setting the project on the client. diff --git a/tests/unit/test_client.py b/tests/unit/test_client.py index 9eeb757..1b933a2 100644 --- a/tests/unit/test_client.py +++ b/tests/unit/test_client.py @@ -205,6 +205,21 @@ def test_from_service_account_json(self): file_open.assert_called_once_with(mock.sentinel.filename, "r", encoding="utf-8") constructor.assert_called_once_with(info) + def test_close_w__http_internal_none(self): + credentials = _make_credentials() + client_obj = self._make_one(credentials=credentials, _http=None) + + client_obj.close() # noraise + + def test_close_w__http_internal_set(self): + credentials = _make_credentials() + http = mock.Mock(spec=["close"]) + client_obj = self._make_one(credentials=credentials, _http=http) + + client_obj.close() + + http.close.assert_called_once_with() + class Test_ClientProjectMixin(unittest.TestCase): @staticmethod