diff --git a/.github/.OwlBot.lock.yaml b/.github/.OwlBot.lock.yaml index cb89b2e..f33299d 100644 --- a/.github/.OwlBot.lock.yaml +++ b/.github/.OwlBot.lock.yaml @@ -1,3 +1,3 @@ docker: image: gcr.io/cloud-devrel-public-resources/owlbot-python:latest - digest: sha256:ec49167c606648a063d1222220b48119c912562849a0528f35bfb592a9f72737 + digest: sha256:899d5d7cc340fa8ef9d8ae1a8cfba362c6898584f779e156f25ee828ba824610 diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index d08d984..e446644 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -3,9 +3,10 @@ # # For syntax help see: # https://help.github.com/en/github/creating-cloning-and-archiving-repositories/about-code-owners#codeowners-syntax +# Note: This file is autogenerated. To make changes to the codeowner team, please update .repo-metadata.json. -# The @googleapis/yoshi-python is the default owner for changes in this repo -* @googleapis/yoshi-python +# @googleapis/yoshi-python is the default owner for changes in this repo +* @googleapis/yoshi-python - -/samples/ @googleapis/python-samples-owners \ No newline at end of file +# @googleapis/python-samples-reviewers is the default owner for samples changes +/samples/ @googleapis/python-samples-reviewers diff --git a/.repo-metadata.json b/.repo-metadata.json index 3730a2b..025ada3 100644 --- a/.repo-metadata.json +++ b/.repo-metadata.json @@ -2,14 +2,15 @@ "name": "cloudshell", "name_pretty": "Cloud Shell", "product_documentation": "https://cloud.google.com/shell/", - "client_documentation": "https://googleapis.dev/python/cloudshell/latest", + "client_documentation": "https://cloud.google.com/python/docs/reference/cloudshell/latest", "issue_tracker": "", - "release_level": "ga", + "release_level": "stable", "language": "python", "library_type": "GAPIC_AUTO", "repo": "googleapis/python-shell", "distribution_name": "google-cloud-shell", "api_id": "cloudshell.googleapis.com", "default_version": "v1", - "codeowner_team": "" + "codeowner_team": "", + "api_shortname": "cloudshell" } diff --git a/CHANGELOG.md b/CHANGELOG.md index 9f15823..1b4301f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +### [1.2.2](https://www.github.com/googleapis/python-shell/compare/v1.2.1...v1.2.2) (2022-01-07) + + +### Bug Fixes + +* provide appropriate mock values for message body fields ([24cf144](https://www.github.com/googleapis/python-shell/commit/24cf144d17b64dc71a5182d1ccbc44444bd68450)) + ### [1.2.1](https://www.github.com/googleapis/python-shell/compare/v1.2.0...v1.2.1) (2021-11-01) diff --git a/README.rst b/README.rst index 54cda61..15021e3 100644 --- a/README.rst +++ b/README.rst @@ -17,7 +17,7 @@ from your web browser. .. |versions| image:: https://img.shields.io/pypi/pyversions/google-cloud-shell.svg :target: https://pypi.org/project/google-cloud-shell/ .. _Cloud Shell: https://cloud.google.com/shell -.. _Client Library Documentation: https://googleapis.dev/python/cloudshell/latest +.. _Client Library Documentation: https://cloud.google.com/python/docs/reference/cloudshell/latest .. _Product Documentation: https://cloud.google.com/shell/docs Quick Start diff --git a/google/cloud/shell_v1/services/cloud_shell_service/async_client.py b/google/cloud/shell_v1/services/cloud_shell_service/async_client.py index 66e8922..454feca 100644 --- a/google/cloud/shell_v1/services/cloud_shell_service/async_client.py +++ b/google/cloud/shell_v1/services/cloud_shell_service/async_client.py @@ -19,14 +19,17 @@ from typing import Dict, Sequence, Tuple, Type, Union import pkg_resources -from google.api_core.client_options import ClientOptions # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore +from google.api_core.client_options import ClientOptions +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore from google.oauth2 import service_account # type: ignore -OptionalRetry = Union[retries.Retry, object] +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore from google.api_core import operation # type: ignore from google.api_core import operation_async # type: ignore diff --git a/google/cloud/shell_v1/services/cloud_shell_service/client.py b/google/cloud/shell_v1/services/cloud_shell_service/client.py index 3cf24e2..0d8052a 100644 --- a/google/cloud/shell_v1/services/cloud_shell_service/client.py +++ b/google/cloud/shell_v1/services/cloud_shell_service/client.py @@ -14,23 +14,25 @@ # limitations under the License. # from collections import OrderedDict -from distutils import util import os import re from typing import Dict, Optional, Sequence, Tuple, Type, Union import pkg_resources -from google.api_core import client_options as client_options_lib # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport import mtls # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.exceptions import MutualTLSChannelError # type: ignore from google.oauth2 import service_account # type: ignore -OptionalRetry = Union[retries.Retry, object] +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore from google.api_core import operation # type: ignore from google.api_core import operation_async # type: ignore @@ -291,8 +293,15 @@ def __init__( client_options = client_options_lib.ClientOptions() # Create SSL credentials for mutual TLS if needed. - use_client_cert = bool( - util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false")) + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" ) client_cert_source_func = None diff --git a/google/cloud/shell_v1/services/cloud_shell_service/transports/base.py b/google/cloud/shell_v1/services/cloud_shell_service/transports/base.py index 74af637..fece65e 100644 --- a/google/cloud/shell_v1/services/cloud_shell_service/transports/base.py +++ b/google/cloud/shell_v1/services/cloud_shell_service/transports/base.py @@ -18,11 +18,11 @@ import pkg_resources import google.auth # type: ignore -import google.api_core # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore -from google.api_core import operations_v1 # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.api_core import operations_v1 from google.auth import credentials as ga_credentials # type: ignore from google.oauth2 import service_account # type: ignore @@ -101,7 +101,6 @@ def __init__( credentials, _ = google.auth.load_credentials_from_file( credentials_file, **scopes_kwargs, quota_project_id=quota_project_id ) - elif credentials is None: credentials, _ = google.auth.default( **scopes_kwargs, quota_project_id=quota_project_id diff --git a/google/cloud/shell_v1/services/cloud_shell_service/transports/grpc.py b/google/cloud/shell_v1/services/cloud_shell_service/transports/grpc.py index 64a6687..e60ecf3 100644 --- a/google/cloud/shell_v1/services/cloud_shell_service/transports/grpc.py +++ b/google/cloud/shell_v1/services/cloud_shell_service/transports/grpc.py @@ -16,9 +16,9 @@ import warnings from typing import Callable, Dict, Optional, Sequence, Tuple, Union -from google.api_core import grpc_helpers # type: ignore -from google.api_core import operations_v1 # type: ignore -from google.api_core import gapic_v1 # type: ignore +from google.api_core import grpc_helpers +from google.api_core import operations_v1 +from google.api_core import gapic_v1 import google.auth # type: ignore from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore diff --git a/google/cloud/shell_v1/services/cloud_shell_service/transports/grpc_asyncio.py b/google/cloud/shell_v1/services/cloud_shell_service/transports/grpc_asyncio.py index cd1624b..8302cf9 100644 --- a/google/cloud/shell_v1/services/cloud_shell_service/transports/grpc_asyncio.py +++ b/google/cloud/shell_v1/services/cloud_shell_service/transports/grpc_asyncio.py @@ -16,9 +16,9 @@ import warnings from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union -from google.api_core import gapic_v1 # type: ignore -from google.api_core import grpc_helpers_async # type: ignore -from google.api_core import operations_v1 # type: ignore +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.api_core import operations_v1 from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore diff --git a/setup.py b/setup.py index ba53e0a..1cc7833 100644 --- a/setup.py +++ b/setup.py @@ -22,7 +22,7 @@ name = "google-cloud-shell" description = "Cloud Shell API client library" -version = "1.2.1" +version = "1.2.2" release_status = "Development Status :: 5 - Production/Stable" url = "https://github.com/googleapis/python-shell" dependencies = [ diff --git a/tests/unit/gapic/shell_v1/test_cloud_shell_service.py b/tests/unit/gapic/shell_v1/test_cloud_shell_service.py index 6903c1d..a3198da 100644 --- a/tests/unit/gapic/shell_v1/test_cloud_shell_service.py +++ b/tests/unit/gapic/shell_v1/test_cloud_shell_service.py @@ -253,20 +253,20 @@ def test_cloud_shell_service_client_client_options( # unsupported value. with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): with pytest.raises(MutualTLSChannelError): - client = client_class() + client = client_class(transport=transport_name) # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. with mock.patch.dict( os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} ): with pytest.raises(ValueError): - client = client_class() + client = client_class(transport=transport_name) # Check the case quota_project_id is provided options = client_options.ClientOptions(quota_project_id="octopus") with mock.patch.object(transport_class, "__init__") as patched: patched.return_value = None - client = client_class(transport=transport_name, client_options=options) + client = client_class(client_options=options, transport=transport_name) patched.assert_called_once_with( credentials=None, credentials_file=None, @@ -335,7 +335,7 @@ def test_cloud_shell_service_client_mtls_env_auto( ) with mock.patch.object(transport_class, "__init__") as patched: patched.return_value = None - client = client_class(transport=transport_name, client_options=options) + client = client_class(client_options=options, transport=transport_name) if use_client_cert_env == "false": expected_client_cert_source = None @@ -430,7 +430,7 @@ def test_cloud_shell_service_client_client_options_scopes( options = client_options.ClientOptions(scopes=["1", "2"],) with mock.patch.object(transport_class, "__init__") as patched: patched.return_value = None - client = client_class(transport=transport_name, client_options=options) + client = client_class(client_options=options, transport=transport_name) patched.assert_called_once_with( credentials=None, credentials_file=None, @@ -461,7 +461,7 @@ def test_cloud_shell_service_client_client_options_credentials_file( options = client_options.ClientOptions(credentials_file="credentials.json") with mock.patch.object(transport_class, "__init__") as patched: patched.return_value = None - client = client_class(transport=transport_name, client_options=options) + client = client_class(client_options=options, transport=transport_name) patched.assert_called_once_with( credentials=None, credentials_file="credentials.json", @@ -494,9 +494,8 @@ def test_cloud_shell_service_client_client_options_from_dict(): ) -def test_get_environment( - transport: str = "grpc", request_type=cloudshell.GetEnvironmentRequest -): +@pytest.mark.parametrize("request_type", [cloudshell.GetEnvironmentRequest, dict,]) +def test_get_environment(request_type, transport: str = "grpc"): client = CloudShellServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) @@ -539,10 +538,6 @@ def test_get_environment( assert response.public_keys == ["public_keys_value"] -def test_get_environment_from_dict(): - test_get_environment(request_type=dict) - - def test_get_environment_empty_call(): # This test is a coverage failsafe to make sure that totally empty calls, # i.e. request == None and no flattened fields passed, work. @@ -679,7 +674,9 @@ def test_get_environment_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_get_environment_flattened_error(): @@ -715,7 +712,9 @@ async def test_get_environment_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -732,9 +731,8 @@ async def test_get_environment_flattened_error_async(): ) -def test_start_environment( - transport: str = "grpc", request_type=cloudshell.StartEnvironmentRequest -): +@pytest.mark.parametrize("request_type", [cloudshell.StartEnvironmentRequest, dict,]) +def test_start_environment(request_type, transport: str = "grpc"): client = CloudShellServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) @@ -760,10 +758,6 @@ def test_start_environment( assert isinstance(response, future.Future) -def test_start_environment_from_dict(): - test_start_environment(request_type=dict) - - def test_start_environment_empty_call(): # This test is a coverage failsafe to make sure that totally empty calls, # i.e. request == None and no flattened fields passed, work. @@ -874,9 +868,10 @@ async def test_start_environment_field_headers_async(): assert ("x-goog-request-params", "name=name/value",) in kw["metadata"] -def test_authorize_environment( - transport: str = "grpc", request_type=cloudshell.AuthorizeEnvironmentRequest -): +@pytest.mark.parametrize( + "request_type", [cloudshell.AuthorizeEnvironmentRequest, dict,] +) +def test_authorize_environment(request_type, transport: str = "grpc"): client = CloudShellServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) @@ -902,10 +897,6 @@ def test_authorize_environment( assert isinstance(response, future.Future) -def test_authorize_environment_from_dict(): - test_authorize_environment(request_type=dict) - - def test_authorize_environment_empty_call(): # This test is a coverage failsafe to make sure that totally empty calls, # i.e. request == None and no flattened fields passed, work. @@ -1016,9 +1007,8 @@ async def test_authorize_environment_field_headers_async(): assert ("x-goog-request-params", "name=name/value",) in kw["metadata"] -def test_add_public_key( - transport: str = "grpc", request_type=cloudshell.AddPublicKeyRequest -): +@pytest.mark.parametrize("request_type", [cloudshell.AddPublicKeyRequest, dict,]) +def test_add_public_key(request_type, transport: str = "grpc"): client = CloudShellServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) @@ -1042,10 +1032,6 @@ def test_add_public_key( assert isinstance(response, future.Future) -def test_add_public_key_from_dict(): - test_add_public_key(request_type=dict) - - def test_add_public_key_empty_call(): # This test is a coverage failsafe to make sure that totally empty calls, # i.e. request == None and no flattened fields passed, work. @@ -1148,9 +1134,8 @@ async def test_add_public_key_field_headers_async(): assert ("x-goog-request-params", "environment=environment/value",) in kw["metadata"] -def test_remove_public_key( - transport: str = "grpc", request_type=cloudshell.RemovePublicKeyRequest -): +@pytest.mark.parametrize("request_type", [cloudshell.RemovePublicKeyRequest, dict,]) +def test_remove_public_key(request_type, transport: str = "grpc"): client = CloudShellServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) @@ -1176,10 +1161,6 @@ def test_remove_public_key( assert isinstance(response, future.Future) -def test_remove_public_key_from_dict(): - test_remove_public_key(request_type=dict) - - def test_remove_public_key_empty_call(): # This test is a coverage failsafe to make sure that totally empty calls, # i.e. request == None and no flattened fields passed, work. @@ -1839,7 +1820,7 @@ def test_parse_common_location_path(): assert expected == actual -def test_client_withDEFAULT_CLIENT_INFO(): +def test_client_with_default_client_info(): client_info = gapic_v1.client_info.ClientInfo() with mock.patch.object(