From 659db456ff6cc7a09fffd83479b2b43d5905239f Mon Sep 17 00:00:00 2001 From: "gcf-owl-bot[bot]" <78513119+gcf-owl-bot[bot]@users.noreply.github.com> Date: Fri, 8 Oct 2021 14:34:14 +0000 Subject: [PATCH] feat: add context manager support in client (#314) - [ ] Regenerate this pull request now. chore: fix docstring for first attribute of protos committer: @busunkim96 PiperOrigin-RevId: 401271153 Source-Link: https://github.com/googleapis/googleapis/commit/787f8c9a731f44e74a90b9847d48659ca9462d10 Source-Link: https://github.com/googleapis/googleapis-gen/commit/81decffe9fc72396a8153e756d1d67a6eecfd620 Copy-Tag: eyJwIjoiLmdpdGh1Yi8uT3dsQm90LnlhbWwiLCJoIjoiODFkZWNmZmU5ZmM3MjM5NmE4MTUzZTc1NmQxZDY3YTZlZWNmZDYyMCJ9 --- .../services/asset_service/async_client.py | 6 +++ .../asset_v1/services/asset_service/client.py | 18 +++++-- .../services/asset_service/transports/base.py | 9 ++++ .../services/asset_service/transports/grpc.py | 3 ++ .../asset_service/transports/grpc_asyncio.py | 3 ++ google/cloud/asset_v1/types/asset_service.py | 36 ++++++++++++- google/cloud/asset_v1/types/assets.py | 13 +++++ .../services/asset_service/async_client.py | 6 +++ .../services/asset_service/client.py | 18 +++++-- .../services/asset_service/transports/base.py | 9 ++++ .../services/asset_service/transports/grpc.py | 3 ++ .../asset_service/transports/grpc_asyncio.py | 3 ++ .../asset_v1p1beta1/types/asset_service.py | 4 ++ google/cloud/asset_v1p1beta1/types/assets.py | 4 ++ .../services/asset_service/async_client.py | 6 +++ .../services/asset_service/client.py | 18 +++++-- .../services/asset_service/transports/base.py | 9 ++++ .../services/asset_service/transports/grpc.py | 3 ++ .../asset_service/transports/grpc_asyncio.py | 3 ++ .../asset_v1p2beta1/types/asset_service.py | 10 ++++ google/cloud/asset_v1p2beta1/types/assets.py | 2 + .../services/asset_service/async_client.py | 6 +++ .../services/asset_service/client.py | 18 +++++-- .../services/asset_service/transports/base.py | 9 ++++ .../services/asset_service/transports/grpc.py | 3 ++ .../asset_service/transports/grpc_asyncio.py | 3 ++ .../asset_v1p4beta1/types/asset_service.py | 5 ++ google/cloud/asset_v1p4beta1/types/assets.py | 5 ++ .../services/asset_service/async_client.py | 6 +++ .../services/asset_service/client.py | 18 +++++-- .../services/asset_service/transports/base.py | 9 ++++ .../services/asset_service/transports/grpc.py | 3 ++ .../asset_service/transports/grpc_asyncio.py | 3 ++ .../asset_v1p5beta1/types/asset_service.py | 2 + google/cloud/asset_v1p5beta1/types/assets.py | 1 + .../unit/gapic/asset_v1/test_asset_service.py | 50 +++++++++++++++++++ .../asset_v1p1beta1/test_asset_service.py | 50 +++++++++++++++++++ .../asset_v1p2beta1/test_asset_service.py | 50 +++++++++++++++++++ .../asset_v1p4beta1/test_asset_service.py | 50 +++++++++++++++++++ .../asset_v1p5beta1/test_asset_service.py | 50 +++++++++++++++++++ 40 files changed, 506 insertions(+), 21 deletions(-) diff --git a/google/cloud/asset_v1/services/asset_service/async_client.py b/google/cloud/asset_v1/services/asset_service/async_client.py index cac62725..e22ca302 100644 --- a/google/cloud/asset_v1/services/asset_service/async_client.py +++ b/google/cloud/asset_v1/services/asset_service/async_client.py @@ -1342,6 +1342,12 @@ async def analyze_move( # Done; return the response. return response + async def __aenter__(self): + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + try: DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/google/cloud/asset_v1/services/asset_service/client.py b/google/cloud/asset_v1/services/asset_service/client.py index 4ca03f85..8e5e62fb 100644 --- a/google/cloud/asset_v1/services/asset_service/client.py +++ b/google/cloud/asset_v1/services/asset_service/client.py @@ -405,10 +405,7 @@ def __init__( client_cert_source_for_mtls=client_cert_source_func, quota_project_id=client_options.quota_project_id, client_info=client_info, - always_use_jwt_access=( - Transport == type(self).get_transport_class("grpc") - or Transport == type(self).get_transport_class("grpc_asyncio") - ), + always_use_jwt_access=True, ) def export_assets( @@ -1510,6 +1507,19 @@ def analyze_move( # Done; return the response. return response + def __enter__(self): + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + try: DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/google/cloud/asset_v1/services/asset_service/transports/base.py b/google/cloud/asset_v1/services/asset_service/transports/base.py index 54ec1960..00490870 100644 --- a/google/cloud/asset_v1/services/asset_service/transports/base.py +++ b/google/cloud/asset_v1/services/asset_service/transports/base.py @@ -291,6 +291,15 @@ def _prep_wrapped_messages(self, client_info): ), } + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + @property def operations_client(self) -> operations_v1.OperationsClient: """Return the client designed to process long-running operations.""" diff --git a/google/cloud/asset_v1/services/asset_service/transports/grpc.py b/google/cloud/asset_v1/services/asset_service/transports/grpc.py index 2e062e07..ea1e6748 100644 --- a/google/cloud/asset_v1/services/asset_service/transports/grpc.py +++ b/google/cloud/asset_v1/services/asset_service/transports/grpc.py @@ -642,5 +642,8 @@ def analyze_move( ) return self._stubs["analyze_move"] + def close(self): + self.grpc_channel.close() + __all__ = ("AssetServiceGrpcTransport",) diff --git a/google/cloud/asset_v1/services/asset_service/transports/grpc_asyncio.py b/google/cloud/asset_v1/services/asset_service/transports/grpc_asyncio.py index 16fb44c6..5453cfb0 100644 --- a/google/cloud/asset_v1/services/asset_service/transports/grpc_asyncio.py +++ b/google/cloud/asset_v1/services/asset_service/transports/grpc_asyncio.py @@ -657,5 +657,8 @@ def analyze_move( ) return self._stubs["analyze_move"] + def close(self): + return self.grpc_channel.close() + __all__ = ("AssetServiceGrpcAsyncIOTransport",) diff --git a/google/cloud/asset_v1/types/asset_service.py b/google/cloud/asset_v1/types/asset_service.py index ff66dd71..dc2e0068 100644 --- a/google/cloud/asset_v1/types/asset_service.py +++ b/google/cloud/asset_v1/types/asset_service.py @@ -94,6 +94,7 @@ class AnalyzeIamPolicyLongrunningMetadata(proto.Message): class ExportAssetsRequest(proto.Message): r"""Export asset request. + Attributes: parent (str): Required. The relative name of the root @@ -196,6 +197,7 @@ class ExportAssetsResponse(proto.Message): class ListAssetsRequest(proto.Message): r"""ListAssets request. + Attributes: parent (str): Required. Name of the organization or project the assets @@ -278,6 +280,7 @@ class ListAssetsRequest(proto.Message): class ListAssetsResponse(proto.Message): r"""ListAssets response. + Attributes: read_time (google.protobuf.timestamp_pb2.Timestamp): Time the snapshot was taken. @@ -301,6 +304,7 @@ def raw_page(self): class BatchGetAssetsHistoryRequest(proto.Message): r"""Batch get assets history request. + Attributes: parent (str): Required. The relative name of the root @@ -358,6 +362,7 @@ class BatchGetAssetsHistoryRequest(proto.Message): class BatchGetAssetsHistoryResponse(proto.Message): r"""Batch get assets history response. + Attributes: assets (Sequence[google.cloud.asset_v1.types.TemporalAsset]): A list of assets with valid time windows. @@ -370,6 +375,7 @@ class BatchGetAssetsHistoryResponse(proto.Message): class CreateFeedRequest(proto.Message): r"""Create asset feed request. + Attributes: parent (str): Required. The name of the @@ -399,6 +405,7 @@ class CreateFeedRequest(proto.Message): class GetFeedRequest(proto.Message): r"""Get asset feed request. + Attributes: name (str): Required. The name of the Feed and it must be in the format @@ -412,6 +419,7 @@ class GetFeedRequest(proto.Message): class ListFeedsRequest(proto.Message): r"""List asset feeds request. + Attributes: parent (str): Required. The parent @@ -427,6 +435,7 @@ class ListFeedsRequest(proto.Message): class ListFeedsResponse(proto.Message): r""" + Attributes: feeds (Sequence[google.cloud.asset_v1.types.Feed]): A list of feeds. @@ -437,6 +446,7 @@ class ListFeedsResponse(proto.Message): class UpdateFeedRequest(proto.Message): r"""Update asset feed request. + Attributes: feed (google.cloud.asset_v1.types.Feed): Required. The new values of feed details. It must match an @@ -458,6 +468,7 @@ class UpdateFeedRequest(proto.Message): class DeleteFeedRequest(proto.Message): r""" + Attributes: name (str): Required. The name of the feed and it must be in the format @@ -471,6 +482,7 @@ class DeleteFeedRequest(proto.Message): class OutputConfig(proto.Message): r"""Output configuration for export assets destination. + Attributes: gcs_destination (google.cloud.asset_v1.types.GcsDestination): Destination on Cloud Storage. @@ -490,6 +502,7 @@ class OutputConfig(proto.Message): class OutputResult(proto.Message): r"""Output result of export assets. + Attributes: gcs_result (google.cloud.asset_v1.types.GcsOutputResult): Export result on Cloud Storage. @@ -502,6 +515,7 @@ class OutputResult(proto.Message): class GcsOutputResult(proto.Message): r"""A Cloud Storage output result. + Attributes: uris (Sequence[str]): List of uris of the Cloud Storage objects. Example: @@ -513,6 +527,7 @@ class GcsOutputResult(proto.Message): class GcsDestination(proto.Message): r"""A Cloud Storage location. + Attributes: uri (str): The uri of the Cloud Storage object. It's the same uri that @@ -543,6 +558,7 @@ class GcsDestination(proto.Message): class BigQueryDestination(proto.Message): r"""A BigQuery destination for exporting assets to. + Attributes: dataset (str): Required. The BigQuery dataset in format @@ -651,6 +667,7 @@ class PartitionKey(proto.Enum): class PubsubDestination(proto.Message): r"""A Pub/Sub destination. + Attributes: topic (str): The name of the Pub/Sub topic to publish to. Example: @@ -662,6 +679,7 @@ class PubsubDestination(proto.Message): class FeedOutputConfig(proto.Message): r"""Output configuration for asset feed destination. + Attributes: pubsub_destination (google.cloud.asset_v1.types.PubsubDestination): Destination on Pub/Sub. @@ -765,6 +783,7 @@ class Feed(proto.Message): class SearchAllResourcesRequest(proto.Message): r"""Search all resources request. + Attributes: scope (str): Required. A scope can be a project, a folder, or an @@ -925,6 +944,7 @@ class SearchAllResourcesRequest(proto.Message): class SearchAllResourcesResponse(proto.Message): r"""Search all resources response. + Attributes: results (Sequence[google.cloud.asset_v1.types.ResourceSearchResult]): A list of Resources that match the search @@ -949,6 +969,7 @@ def raw_page(self): class SearchAllIamPoliciesRequest(proto.Message): r"""Search all IAM policies request. + Attributes: scope (str): Required. A scope can be a project, a folder, or an @@ -1069,6 +1090,7 @@ class SearchAllIamPoliciesRequest(proto.Message): class SearchAllIamPoliciesResponse(proto.Message): r"""Search all IAM policies response. + Attributes: results (Sequence[google.cloud.asset_v1.types.IamPolicySearchResult]): A list of IamPolicy that match the search @@ -1093,6 +1115,7 @@ def raw_page(self): class IamPolicyAnalysisQuery(proto.Message): r"""## IAM policy analysis query message. + Attributes: scope (str): Required. The relative name of the root asset. Only @@ -1181,6 +1204,7 @@ class AccessSelector(proto.Message): class Options(proto.Message): r"""Contains query options. + Attributes: expand_groups (bool): Optional. If true, the identities section of the result will @@ -1279,6 +1303,7 @@ class Options(proto.Message): class ConditionContext(proto.Message): r"""The IAM conditions context. + Attributes: access_time (google.protobuf.timestamp_pb2.Timestamp): The hypothetical access timestamp to evaluate IAM @@ -1354,6 +1379,7 @@ class AnalyzeIamPolicyResponse(proto.Message): class IamPolicyAnalysis(proto.Message): r"""An analysis message to group the query and results. + Attributes: analysis_query (google.cloud.asset_v1.types.IamPolicyAnalysisQuery): The analysis query. @@ -1402,6 +1428,7 @@ class IamPolicyAnalysisOutputConfig(proto.Message): class GcsDestination(proto.Message): r"""A Cloud Storage location. + Attributes: uri (str): Required. The uri of the Cloud Storage object. It's the same @@ -1421,6 +1448,7 @@ class GcsDestination(proto.Message): class BigQueryDestination(proto.Message): r"""A BigQuery destination. + Attributes: dataset (str): Required. The BigQuery dataset in format @@ -1512,11 +1540,13 @@ class AnalyzeIamPolicyLongrunningRequest(proto.Message): class AnalyzeIamPolicyLongrunningResponse(proto.Message): r"""A response message for [AssetService.AnalyzeIamPolicyLongrunning][google.cloud.asset.v1.AssetService.AnalyzeIamPolicyLongrunning]. - """ + + """ class AnalyzeMoveRequest(proto.Message): r"""The request message for performing resource move analysis. + Attributes: resource (str): Required. Name of the resource to perform the @@ -1552,6 +1582,7 @@ class AnalysisView(proto.Enum): class AnalyzeMoveResponse(proto.Message): r"""The response message for resource move analysis. + Attributes: move_analysis (Sequence[google.cloud.asset_v1.types.MoveAnalysis]): The list of analyses returned from performing @@ -1566,6 +1597,7 @@ class AnalyzeMoveResponse(proto.Message): class MoveAnalysis(proto.Message): r"""A message to group the analysis information. + Attributes: display_name (str): The user friendly display name of the @@ -1589,6 +1621,7 @@ class MoveAnalysis(proto.Message): class MoveAnalysisResult(proto.Message): r"""An analysis result including blockers and warnings. + Attributes: blockers (Sequence[google.cloud.asset_v1.types.MoveImpact]): Blocking information that would prevent the @@ -1608,6 +1641,7 @@ class MoveAnalysisResult(proto.Message): class MoveImpact(proto.Message): r"""A message to group impacts of moving the target resource. + Attributes: detail (str): User friendly impact detail in a free form diff --git a/google/cloud/asset_v1/types/assets.py b/google/cloud/asset_v1/types/assets.py index a159c426..8c2d81a0 100644 --- a/google/cloud/asset_v1/types/assets.py +++ b/google/cloud/asset_v1/types/assets.py @@ -87,6 +87,7 @@ class PriorAssetState(proto.Enum): class TimeWindow(proto.Message): r"""A time window specified by its ``start_time`` and ``end_time``. + Attributes: start_time (google.protobuf.timestamp_pb2.Timestamp): Start time of the time window (exclusive). @@ -214,6 +215,7 @@ class Asset(proto.Message): class Resource(proto.Message): r"""A representation of a Google Cloud resource. + Attributes: version (str): The API version. Example: ``v1`` @@ -271,6 +273,7 @@ class Resource(proto.Message): class RelatedAssets(proto.Message): r"""The detailed related assets with the ``relationship_type``. + Attributes: relationship_attributes (google.cloud.asset_v1.types.RelationshipAttributes): The detailed relationship attributes. @@ -690,6 +693,7 @@ class AttachedResource(proto.Message): class RelatedResources(proto.Message): r"""The related resources of the primary resource. + Attributes: related_resources (Sequence[google.cloud.asset_v1.types.RelatedResource]): The detailed related resources of the primary @@ -703,6 +707,7 @@ class RelatedResources(proto.Message): class RelatedResource(proto.Message): r"""The detailed related resource. + Attributes: asset_type (str): The type of the asset. Example: @@ -800,6 +805,7 @@ class IamPolicySearchResult(proto.Message): class Explanation(proto.Message): r"""Explanation about the IAM policy search result. + Attributes: matched_permissions (Sequence[google.cloud.asset_v1.types.IamPolicySearchResult.Explanation.MatchedPermissionsEntry]): The map from roles to their included permissions that match @@ -816,6 +822,7 @@ class Explanation(proto.Message): class Permissions(proto.Message): r"""IAM permissions + Attributes: permissions (Sequence[str]): A list of permissions. A sample permission string: @@ -866,6 +873,7 @@ class IamPolicyAnalysisState(proto.Message): class ConditionEvaluation(proto.Message): r"""The Condition evaluation. + Attributes: evaluation_value (google.cloud.asset_v1.types.ConditionEvaluation.EvaluationValue): The evaluation result. @@ -912,6 +920,7 @@ class IamPolicyAnalysisResult(proto.Message): class Resource(proto.Message): r"""A Google Cloud resource under analysis. + Attributes: full_resource_name (str): The `full resource @@ -927,6 +936,7 @@ class Resource(proto.Message): class Access(proto.Message): r"""An IAM role or permission under analysis. + Attributes: role (str): The role. @@ -944,6 +954,7 @@ class Access(proto.Message): class Identity(proto.Message): r"""An identity under analysis. + Attributes: name (str): The identity name in any form of members appear in `IAM @@ -969,6 +980,7 @@ class Identity(proto.Message): class Edge(proto.Message): r"""A directional edge. + Attributes: source_node (str): The source node of the edge. For example, it @@ -1046,6 +1058,7 @@ class AccessControlList(proto.Message): class IdentityList(proto.Message): r"""The identities and group edges. + Attributes: identities (Sequence[google.cloud.asset_v1.types.IamPolicyAnalysisResult.Identity]): Only the identities that match one of the following diff --git a/google/cloud/asset_v1p1beta1/services/asset_service/async_client.py b/google/cloud/asset_v1p1beta1/services/asset_service/async_client.py index 3e9880e3..5a6fa9ce 100644 --- a/google/cloud/asset_v1p1beta1/services/asset_service/async_client.py +++ b/google/cloud/asset_v1p1beta1/services/asset_service/async_client.py @@ -389,6 +389,12 @@ async def search_all_iam_policies( # Done; return the response. return response + async def __aenter__(self): + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + try: DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/google/cloud/asset_v1p1beta1/services/asset_service/client.py b/google/cloud/asset_v1p1beta1/services/asset_service/client.py index 39dfe2a3..35215ae9 100644 --- a/google/cloud/asset_v1p1beta1/services/asset_service/client.py +++ b/google/cloud/asset_v1p1beta1/services/asset_service/client.py @@ -327,10 +327,7 @@ def __init__( client_cert_source_for_mtls=client_cert_source_func, quota_project_id=client_options.quota_project_id, client_info=client_info, - always_use_jwt_access=( - Transport == type(self).get_transport_class("grpc") - or Transport == type(self).get_transport_class("grpc_asyncio") - ), + always_use_jwt_access=True, ) def search_all_resources( @@ -546,6 +543,19 @@ def search_all_iam_policies( # Done; return the response. return response + def __enter__(self): + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + try: DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/google/cloud/asset_v1p1beta1/services/asset_service/transports/base.py b/google/cloud/asset_v1p1beta1/services/asset_service/transports/base.py index 7d497c02..b4403329 100644 --- a/google/cloud/asset_v1p1beta1/services/asset_service/transports/base.py +++ b/google/cloud/asset_v1p1beta1/services/asset_service/transports/base.py @@ -184,6 +184,15 @@ def _prep_wrapped_messages(self, client_info): ), } + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + @property def search_all_resources( self, diff --git a/google/cloud/asset_v1p1beta1/services/asset_service/transports/grpc.py b/google/cloud/asset_v1p1beta1/services/asset_service/transports/grpc.py index 4952602a..5b4b5960 100644 --- a/google/cloud/asset_v1p1beta1/services/asset_service/transports/grpc.py +++ b/google/cloud/asset_v1p1beta1/services/asset_service/transports/grpc.py @@ -296,5 +296,8 @@ def search_all_iam_policies( ) return self._stubs["search_all_iam_policies"] + def close(self): + self.grpc_channel.close() + __all__ = ("AssetServiceGrpcTransport",) diff --git a/google/cloud/asset_v1p1beta1/services/asset_service/transports/grpc_asyncio.py b/google/cloud/asset_v1p1beta1/services/asset_service/transports/grpc_asyncio.py index 07e0c19b..f418c80f 100644 --- a/google/cloud/asset_v1p1beta1/services/asset_service/transports/grpc_asyncio.py +++ b/google/cloud/asset_v1p1beta1/services/asset_service/transports/grpc_asyncio.py @@ -299,5 +299,8 @@ def search_all_iam_policies( ) return self._stubs["search_all_iam_policies"] + def close(self): + return self.grpc_channel.close() + __all__ = ("AssetServiceGrpcAsyncIOTransport",) diff --git a/google/cloud/asset_v1p1beta1/types/asset_service.py b/google/cloud/asset_v1p1beta1/types/asset_service.py index ba012487..d30eff30 100644 --- a/google/cloud/asset_v1p1beta1/types/asset_service.py +++ b/google/cloud/asset_v1p1beta1/types/asset_service.py @@ -31,6 +31,7 @@ class SearchAllResourcesRequest(proto.Message): r"""Search all resources request. + Attributes: scope (str): Required. The relative name of an asset. The search is @@ -79,6 +80,7 @@ class SearchAllResourcesRequest(proto.Message): class SearchAllResourcesResponse(proto.Message): r"""Search all resources response. + Attributes: results (Sequence[google.cloud.asset_v1p1beta1.types.StandardResourceMetadata]): A list of resource that match the search @@ -102,6 +104,7 @@ def raw_page(self): class SearchAllIamPoliciesRequest(proto.Message): r"""Search all IAM policies request. + Attributes: scope (str): Required. The relative name of an asset. The search is @@ -140,6 +143,7 @@ class SearchAllIamPoliciesRequest(proto.Message): class SearchAllIamPoliciesResponse(proto.Message): r"""Search all IAM policies response. + Attributes: results (Sequence[google.cloud.asset_v1p1beta1.types.IamPolicySearchResult]): A list of IamPolicy that match the search diff --git a/google/cloud/asset_v1p1beta1/types/assets.py b/google/cloud/asset_v1p1beta1/types/assets.py index 1046dd68..120da83c 100644 --- a/google/cloud/asset_v1p1beta1/types/assets.py +++ b/google/cloud/asset_v1p1beta1/types/assets.py @@ -26,6 +26,7 @@ class StandardResourceMetadata(proto.Message): r"""The standard metadata of a cloud resource. + Attributes: name (str): The full resource name. For example: @@ -79,6 +80,7 @@ class StandardResourceMetadata(proto.Message): class IamPolicySearchResult(proto.Message): r"""The result for a IAM Policy search. + Attributes: resource (str): The `full resource @@ -107,6 +109,7 @@ class IamPolicySearchResult(proto.Message): class Explanation(proto.Message): r"""Explanation about the IAM policy search result. + Attributes: matched_permissions (Sequence[google.cloud.asset_v1p1beta1.types.IamPolicySearchResult.Explanation.MatchedPermissionsEntry]): The map from roles to their included permission matching the @@ -129,6 +132,7 @@ class Explanation(proto.Message): class Permissions(proto.Message): r"""IAM permissions + Attributes: permissions (Sequence[str]): A list of permissions. A sample permission diff --git a/google/cloud/asset_v1p2beta1/services/asset_service/async_client.py b/google/cloud/asset_v1p2beta1/services/asset_service/async_client.py index 9d06f397..a35725e4 100644 --- a/google/cloud/asset_v1p2beta1/services/asset_service/async_client.py +++ b/google/cloud/asset_v1p2beta1/services/asset_service/async_client.py @@ -565,6 +565,12 @@ async def delete_feed( request, retry=retry, timeout=timeout, metadata=metadata, ) + async def __aenter__(self): + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + try: DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/google/cloud/asset_v1p2beta1/services/asset_service/client.py b/google/cloud/asset_v1p2beta1/services/asset_service/client.py index 52a035f8..68b744d7 100644 --- a/google/cloud/asset_v1p2beta1/services/asset_service/client.py +++ b/google/cloud/asset_v1p2beta1/services/asset_service/client.py @@ -336,10 +336,7 @@ def __init__( client_cert_source_for_mtls=client_cert_source_func, quota_project_id=client_options.quota_project_id, client_info=client_info, - always_use_jwt_access=( - Transport == type(self).get_transport_class("grpc") - or Transport == type(self).get_transport_class("grpc_asyncio") - ), + always_use_jwt_access=True, ) def create_feed( @@ -721,6 +718,19 @@ def delete_feed( request, retry=retry, timeout=timeout, metadata=metadata, ) + def __enter__(self): + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + try: DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/google/cloud/asset_v1p2beta1/services/asset_service/transports/base.py b/google/cloud/asset_v1p2beta1/services/asset_service/transports/base.py index c4d7ebca..4aadbd52 100644 --- a/google/cloud/asset_v1p2beta1/services/asset_service/transports/base.py +++ b/google/cloud/asset_v1p2beta1/services/asset_service/transports/base.py @@ -206,6 +206,15 @@ def _prep_wrapped_messages(self, client_info): ), } + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + @property def create_feed( self, diff --git a/google/cloud/asset_v1p2beta1/services/asset_service/transports/grpc.py b/google/cloud/asset_v1p2beta1/services/asset_service/transports/grpc.py index 65411a81..fd9bcd45 100644 --- a/google/cloud/asset_v1p2beta1/services/asset_service/transports/grpc.py +++ b/google/cloud/asset_v1p2beta1/services/asset_service/transports/grpc.py @@ -357,5 +357,8 @@ def delete_feed( ) return self._stubs["delete_feed"] + def close(self): + self.grpc_channel.close() + __all__ = ("AssetServiceGrpcTransport",) diff --git a/google/cloud/asset_v1p2beta1/services/asset_service/transports/grpc_asyncio.py b/google/cloud/asset_v1p2beta1/services/asset_service/transports/grpc_asyncio.py index 23e4299c..1e264ea0 100644 --- a/google/cloud/asset_v1p2beta1/services/asset_service/transports/grpc_asyncio.py +++ b/google/cloud/asset_v1p2beta1/services/asset_service/transports/grpc_asyncio.py @@ -364,5 +364,8 @@ def delete_feed( ) return self._stubs["delete_feed"] + def close(self): + return self.grpc_channel.close() + __all__ = ("AssetServiceGrpcAsyncIOTransport",) diff --git a/google/cloud/asset_v1p2beta1/types/asset_service.py b/google/cloud/asset_v1p2beta1/types/asset_service.py index 682756ea..e02b95f9 100644 --- a/google/cloud/asset_v1p2beta1/types/asset_service.py +++ b/google/cloud/asset_v1p2beta1/types/asset_service.py @@ -46,6 +46,7 @@ class ContentType(proto.Enum): class CreateFeedRequest(proto.Message): r"""Create asset feed request. + Attributes: parent (str): Required. The name of the @@ -75,6 +76,7 @@ class CreateFeedRequest(proto.Message): class GetFeedRequest(proto.Message): r"""Get asset feed request. + Attributes: name (str): Required. The name of the Feed and it must be in the format @@ -88,6 +90,7 @@ class GetFeedRequest(proto.Message): class ListFeedsRequest(proto.Message): r"""List asset feeds request. + Attributes: parent (str): Required. The parent @@ -103,6 +106,7 @@ class ListFeedsRequest(proto.Message): class ListFeedsResponse(proto.Message): r""" + Attributes: feeds (Sequence[google.cloud.asset_v1p2beta1.types.Feed]): A list of feeds. @@ -113,6 +117,7 @@ class ListFeedsResponse(proto.Message): class UpdateFeedRequest(proto.Message): r"""Update asset feed request. + Attributes: feed (google.cloud.asset_v1p2beta1.types.Feed): Required. The new values of feed details. It must match an @@ -134,6 +139,7 @@ class UpdateFeedRequest(proto.Message): class DeleteFeedRequest(proto.Message): r""" + Attributes: name (str): Required. The name of the feed and it must be in the format @@ -147,6 +153,7 @@ class DeleteFeedRequest(proto.Message): class OutputConfig(proto.Message): r"""Output configuration for export assets destination. + Attributes: gcs_destination (google.cloud.asset_v1p2beta1.types.GcsDestination): Destination on Cloud Storage. @@ -159,6 +166,7 @@ class OutputConfig(proto.Message): class GcsDestination(proto.Message): r"""A Cloud Storage location. + Attributes: uri (str): The uri of the Cloud Storage object. It's the same uri that @@ -174,6 +182,7 @@ class GcsDestination(proto.Message): class PubsubDestination(proto.Message): r"""A Cloud Pubsub destination. + Attributes: topic (str): The name of the Cloud Pub/Sub topic to publish to. For @@ -185,6 +194,7 @@ class PubsubDestination(proto.Message): class FeedOutputConfig(proto.Message): r"""Output configuration for asset feed destination. + Attributes: pubsub_destination (google.cloud.asset_v1p2beta1.types.PubsubDestination): Destination on Cloud Pubsub. diff --git a/google/cloud/asset_v1p2beta1/types/assets.py b/google/cloud/asset_v1p2beta1/types/assets.py index 50722bd7..bbb85ca5 100644 --- a/google/cloud/asset_v1p2beta1/types/assets.py +++ b/google/cloud/asset_v1p2beta1/types/assets.py @@ -48,6 +48,7 @@ class TemporalAsset(proto.Message): class TimeWindow(proto.Message): r"""A time window of (start_time, end_time]. + Attributes: start_time (google.protobuf.timestamp_pb2.Timestamp): Start time of the time window (exclusive). @@ -101,6 +102,7 @@ class Asset(proto.Message): class Resource(proto.Message): r"""Representation of a cloud resource. + Attributes: version (str): The API version. Example: "v1". diff --git a/google/cloud/asset_v1p4beta1/services/asset_service/async_client.py b/google/cloud/asset_v1p4beta1/services/asset_service/async_client.py index d3a68933..709172f6 100644 --- a/google/cloud/asset_v1p4beta1/services/asset_service/async_client.py +++ b/google/cloud/asset_v1p4beta1/services/asset_service/async_client.py @@ -287,6 +287,12 @@ async def export_iam_policy_analysis( # Done; return the response. return response + async def __aenter__(self): + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + try: DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/google/cloud/asset_v1p4beta1/services/asset_service/client.py b/google/cloud/asset_v1p4beta1/services/asset_service/client.py index b936b0ce..11a73dd2 100644 --- a/google/cloud/asset_v1p4beta1/services/asset_service/client.py +++ b/google/cloud/asset_v1p4beta1/services/asset_service/client.py @@ -328,10 +328,7 @@ def __init__( client_cert_source_for_mtls=client_cert_source_func, quota_project_id=client_options.quota_project_id, client_info=client_info, - always_use_jwt_access=( - Transport == type(self).get_transport_class("grpc") - or Transport == type(self).get_transport_class("grpc_asyncio") - ), + always_use_jwt_access=True, ) def analyze_iam_policy( @@ -459,6 +456,19 @@ def export_iam_policy_analysis( # Done; return the response. return response + def __enter__(self): + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + try: DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/google/cloud/asset_v1p4beta1/services/asset_service/transports/base.py b/google/cloud/asset_v1p4beta1/services/asset_service/transports/base.py index bc234de8..a2dc71f9 100644 --- a/google/cloud/asset_v1p4beta1/services/asset_service/transports/base.py +++ b/google/cloud/asset_v1p4beta1/services/asset_service/transports/base.py @@ -175,6 +175,15 @@ def _prep_wrapped_messages(self, client_info): ), } + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + @property def operations_client(self) -> operations_v1.OperationsClient: """Return the client designed to process long-running operations.""" diff --git a/google/cloud/asset_v1p4beta1/services/asset_service/transports/grpc.py b/google/cloud/asset_v1p4beta1/services/asset_service/transports/grpc.py index 4379359f..ebfb7155 100644 --- a/google/cloud/asset_v1p4beta1/services/asset_service/transports/grpc.py +++ b/google/cloud/asset_v1p4beta1/services/asset_service/transports/grpc.py @@ -305,5 +305,8 @@ def export_iam_policy_analysis( ) return self._stubs["export_iam_policy_analysis"] + def close(self): + self.grpc_channel.close() + __all__ = ("AssetServiceGrpcTransport",) diff --git a/google/cloud/asset_v1p4beta1/services/asset_service/transports/grpc_asyncio.py b/google/cloud/asset_v1p4beta1/services/asset_service/transports/grpc_asyncio.py index 621468cf..a39ed4f9 100644 --- a/google/cloud/asset_v1p4beta1/services/asset_service/transports/grpc_asyncio.py +++ b/google/cloud/asset_v1p4beta1/services/asset_service/transports/grpc_asyncio.py @@ -312,5 +312,8 @@ def export_iam_policy_analysis( ) return self._stubs["export_iam_policy_analysis"] + def close(self): + return self.grpc_channel.close() + __all__ = ("AssetServiceGrpcAsyncIOTransport",) diff --git a/google/cloud/asset_v1p4beta1/types/asset_service.py b/google/cloud/asset_v1p4beta1/types/asset_service.py index 033c7e2e..d54f88b7 100644 --- a/google/cloud/asset_v1p4beta1/types/asset_service.py +++ b/google/cloud/asset_v1p4beta1/types/asset_service.py @@ -34,6 +34,7 @@ class IamPolicyAnalysisQuery(proto.Message): r"""IAM policy analysis query message. + Attributes: parent (str): Required. The relative name of the root @@ -122,6 +123,7 @@ class AnalyzeIamPolicyRequest(proto.Message): class Options(proto.Message): r"""Contains request options. + Attributes: expand_groups (bool): Optional. If true, the identities section of the result will @@ -248,6 +250,7 @@ class AnalyzeIamPolicyResponse(proto.Message): class IamPolicyAnalysis(proto.Message): r"""An analysis message to group the query and results. + Attributes: analysis_query (google.cloud.asset_v1p4beta1.types.IamPolicyAnalysisQuery): The analysis query. @@ -291,6 +294,7 @@ class IamPolicyAnalysisOutputConfig(proto.Message): class GcsDestination(proto.Message): r"""A Cloud Storage location. + Attributes: uri (str): Required. The uri of the Cloud Storage object. It's the same @@ -324,6 +328,7 @@ class ExportIamPolicyAnalysisRequest(proto.Message): class Options(proto.Message): r"""Contains request options. + Attributes: expand_groups (bool): Optional. If true, the identities section of the result will diff --git a/google/cloud/asset_v1p4beta1/types/assets.py b/google/cloud/asset_v1p4beta1/types/assets.py index 2374dfae..b3730ac7 100644 --- a/google/cloud/asset_v1p4beta1/types/assets.py +++ b/google/cloud/asset_v1p4beta1/types/assets.py @@ -76,6 +76,7 @@ class AnalysisState(proto.Message): class Resource(proto.Message): r"""A GCP resource that appears in an access control list. + Attributes: full_resource_name (str): The `full resource @@ -91,6 +92,7 @@ class Resource(proto.Message): class Access(proto.Message): r"""A role or permission that appears in an access control list. + Attributes: role (str): The role. @@ -108,6 +110,7 @@ class Access(proto.Message): class Edge(proto.Message): r"""A directional edge. + Attributes: source_node (str): The source node of the edge. @@ -120,6 +123,7 @@ class Edge(proto.Message): class Identity(proto.Message): r"""An identity that appears in an access control list. + Attributes: name (str): The identity name in any form of members appear in `IAM @@ -199,6 +203,7 @@ class AccessControlList(proto.Message): class IdentityList(proto.Message): r""" + Attributes: identities (Sequence[google.cloud.asset_v1p4beta1.types.IamPolicyAnalysisResult.Identity]): Only the identities that match one of the following diff --git a/google/cloud/asset_v1p5beta1/services/asset_service/async_client.py b/google/cloud/asset_v1p5beta1/services/asset_service/async_client.py index ef95fe81..26f0eb77 100644 --- a/google/cloud/asset_v1p5beta1/services/asset_service/async_client.py +++ b/google/cloud/asset_v1p5beta1/services/asset_service/async_client.py @@ -233,6 +233,12 @@ async def list_assets( # Done; return the response. return response + async def __aenter__(self): + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + try: DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/google/cloud/asset_v1p5beta1/services/asset_service/client.py b/google/cloud/asset_v1p5beta1/services/asset_service/client.py index 62faa0d3..3fa2f980 100644 --- a/google/cloud/asset_v1p5beta1/services/asset_service/client.py +++ b/google/cloud/asset_v1p5beta1/services/asset_service/client.py @@ -375,10 +375,7 @@ def __init__( client_cert_source_for_mtls=client_cert_source_func, quota_project_id=client_options.quota_project_id, client_info=client_info, - always_use_jwt_access=( - Transport == type(self).get_transport_class("grpc") - or Transport == type(self).get_transport_class("grpc_asyncio") - ), + always_use_jwt_access=True, ) def list_assets( @@ -439,6 +436,19 @@ def list_assets( # Done; return the response. return response + def __enter__(self): + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + try: DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/google/cloud/asset_v1p5beta1/services/asset_service/transports/base.py b/google/cloud/asset_v1p5beta1/services/asset_service/transports/base.py index bc83a331..4a6c651a 100644 --- a/google/cloud/asset_v1p5beta1/services/asset_service/transports/base.py +++ b/google/cloud/asset_v1p5beta1/services/asset_service/transports/base.py @@ -169,6 +169,15 @@ def _prep_wrapped_messages(self, client_info): ), } + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + @property def list_assets( self, diff --git a/google/cloud/asset_v1p5beta1/services/asset_service/transports/grpc.py b/google/cloud/asset_v1p5beta1/services/asset_service/transports/grpc.py index 51832ed2..1d6bac4a 100644 --- a/google/cloud/asset_v1p5beta1/services/asset_service/transports/grpc.py +++ b/google/cloud/asset_v1p5beta1/services/asset_service/transports/grpc.py @@ -252,5 +252,8 @@ def list_assets( ) return self._stubs["list_assets"] + def close(self): + self.grpc_channel.close() + __all__ = ("AssetServiceGrpcTransport",) diff --git a/google/cloud/asset_v1p5beta1/services/asset_service/transports/grpc_asyncio.py b/google/cloud/asset_v1p5beta1/services/asset_service/transports/grpc_asyncio.py index 645054c3..5fd7fa7e 100644 --- a/google/cloud/asset_v1p5beta1/services/asset_service/transports/grpc_asyncio.py +++ b/google/cloud/asset_v1p5beta1/services/asset_service/transports/grpc_asyncio.py @@ -257,5 +257,8 @@ def list_assets( ) return self._stubs["list_assets"] + def close(self): + return self.grpc_channel.close() + __all__ = ("AssetServiceGrpcAsyncIOTransport",) diff --git a/google/cloud/asset_v1p5beta1/types/asset_service.py b/google/cloud/asset_v1p5beta1/types/asset_service.py index 7b1ce49e..0a261d3d 100644 --- a/google/cloud/asset_v1p5beta1/types/asset_service.py +++ b/google/cloud/asset_v1p5beta1/types/asset_service.py @@ -36,6 +36,7 @@ class ContentType(proto.Enum): class ListAssetsRequest(proto.Message): r"""ListAssets request. + Attributes: parent (str): Required. Name of the organization or project the assets @@ -83,6 +84,7 @@ class ListAssetsRequest(proto.Message): class ListAssetsResponse(proto.Message): r"""ListAssets response. + Attributes: read_time (google.protobuf.timestamp_pb2.Timestamp): Time the snapshot was taken. diff --git a/google/cloud/asset_v1p5beta1/types/assets.py b/google/cloud/asset_v1p5beta1/types/assets.py index 79d70d6d..759713cb 100644 --- a/google/cloud/asset_v1p5beta1/types/assets.py +++ b/google/cloud/asset_v1p5beta1/types/assets.py @@ -101,6 +101,7 @@ class Asset(proto.Message): class Resource(proto.Message): r"""Representation of a cloud resource. + Attributes: version (str): The API version. Example: "v1". diff --git a/tests/unit/gapic/asset_v1/test_asset_service.py b/tests/unit/gapic/asset_v1/test_asset_service.py index 2037c805..01e68d22 100644 --- a/tests/unit/gapic/asset_v1/test_asset_service.py +++ b/tests/unit/gapic/asset_v1/test_asset_service.py @@ -32,6 +32,7 @@ from google.api_core import grpc_helpers_async from google.api_core import operation_async # type: ignore from google.api_core import operations_v1 +from google.api_core import path_template from google.auth import credentials as ga_credentials from google.auth.exceptions import MutualTLSChannelError from google.cloud.asset_v1.services.asset_service import AssetServiceAsyncClient @@ -3406,6 +3407,9 @@ def test_asset_service_base_transport(): with pytest.raises(NotImplementedError): getattr(transport, method)(request=object()) + with pytest.raises(NotImplementedError): + transport.close() + # Additionally, the LRO client (a property) should # also raise NotImplementedError with pytest.raises(NotImplementedError): @@ -3996,3 +4000,49 @@ def test_client_withDEFAULT_CLIENT_INFO(): credentials=ga_credentials.AnonymousCredentials(), client_info=client_info, ) prep.assert_called_once_with(client_info) + + +@pytest.mark.asyncio +async def test_transport_close_async(): + client = AssetServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc_asyncio", + ) + with mock.patch.object( + type(getattr(client.transport, "grpc_channel")), "close" + ) as close: + async with client: + close.assert_not_called() + close.assert_called_once() + + +def test_transport_close(): + transports = { + "grpc": "_grpc_channel", + } + + for transport, close_name in transports.items(): + client = AssetServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport=transport + ) + with mock.patch.object( + type(getattr(client.transport, close_name)), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + +def test_client_ctx(): + transports = [ + "grpc", + ] + for transport in transports: + client = AssetServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport=transport + ) + # Test client calls underlying transport. + with mock.patch.object(type(client.transport), "close") as close: + close.assert_not_called() + with client: + pass + close.assert_called() diff --git a/tests/unit/gapic/asset_v1p1beta1/test_asset_service.py b/tests/unit/gapic/asset_v1p1beta1/test_asset_service.py index 6c2579ad..c25e6960 100644 --- a/tests/unit/gapic/asset_v1p1beta1/test_asset_service.py +++ b/tests/unit/gapic/asset_v1p1beta1/test_asset_service.py @@ -29,6 +29,7 @@ from google.api_core import gapic_v1 from google.api_core import grpc_helpers from google.api_core import grpc_helpers_async +from google.api_core import path_template from google.auth import credentials as ga_credentials from google.auth.exceptions import MutualTLSChannelError from google.cloud.asset_v1p1beta1.services.asset_service import AssetServiceAsyncClient @@ -1372,6 +1373,9 @@ def test_asset_service_base_transport(): with pytest.raises(NotImplementedError): getattr(transport, method)(request=object()) + with pytest.raises(NotImplementedError): + transport.close() + @requires_google_auth_gte_1_25_0 def test_asset_service_base_transport_with_credentials_file(): @@ -1819,3 +1823,49 @@ def test_client_withDEFAULT_CLIENT_INFO(): credentials=ga_credentials.AnonymousCredentials(), client_info=client_info, ) prep.assert_called_once_with(client_info) + + +@pytest.mark.asyncio +async def test_transport_close_async(): + client = AssetServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc_asyncio", + ) + with mock.patch.object( + type(getattr(client.transport, "grpc_channel")), "close" + ) as close: + async with client: + close.assert_not_called() + close.assert_called_once() + + +def test_transport_close(): + transports = { + "grpc": "_grpc_channel", + } + + for transport, close_name in transports.items(): + client = AssetServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport=transport + ) + with mock.patch.object( + type(getattr(client.transport, close_name)), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + +def test_client_ctx(): + transports = [ + "grpc", + ] + for transport in transports: + client = AssetServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport=transport + ) + # Test client calls underlying transport. + with mock.patch.object(type(client.transport), "close") as close: + close.assert_not_called() + with client: + pass + close.assert_called() diff --git a/tests/unit/gapic/asset_v1p2beta1/test_asset_service.py b/tests/unit/gapic/asset_v1p2beta1/test_asset_service.py index c8e463aa..7a60b166 100644 --- a/tests/unit/gapic/asset_v1p2beta1/test_asset_service.py +++ b/tests/unit/gapic/asset_v1p2beta1/test_asset_service.py @@ -29,6 +29,7 @@ from google.api_core import gapic_v1 from google.api_core import grpc_helpers from google.api_core import grpc_helpers_async +from google.api_core import path_template from google.auth import credentials as ga_credentials from google.auth.exceptions import MutualTLSChannelError from google.cloud.asset_v1p2beta1.services.asset_service import AssetServiceAsyncClient @@ -1594,6 +1595,9 @@ def test_asset_service_base_transport(): with pytest.raises(NotImplementedError): getattr(transport, method)(request=object()) + with pytest.raises(NotImplementedError): + transport.close() + @requires_google_auth_gte_1_25_0 def test_asset_service_base_transport_with_credentials_file(): @@ -2061,3 +2065,49 @@ def test_client_withDEFAULT_CLIENT_INFO(): credentials=ga_credentials.AnonymousCredentials(), client_info=client_info, ) prep.assert_called_once_with(client_info) + + +@pytest.mark.asyncio +async def test_transport_close_async(): + client = AssetServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc_asyncio", + ) + with mock.patch.object( + type(getattr(client.transport, "grpc_channel")), "close" + ) as close: + async with client: + close.assert_not_called() + close.assert_called_once() + + +def test_transport_close(): + transports = { + "grpc": "_grpc_channel", + } + + for transport, close_name in transports.items(): + client = AssetServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport=transport + ) + with mock.patch.object( + type(getattr(client.transport, close_name)), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + +def test_client_ctx(): + transports = [ + "grpc", + ] + for transport in transports: + client = AssetServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport=transport + ) + # Test client calls underlying transport. + with mock.patch.object(type(client.transport), "close") as close: + close.assert_not_called() + with client: + pass + close.assert_called() diff --git a/tests/unit/gapic/asset_v1p4beta1/test_asset_service.py b/tests/unit/gapic/asset_v1p4beta1/test_asset_service.py index 71b71091..f8ab8132 100644 --- a/tests/unit/gapic/asset_v1p4beta1/test_asset_service.py +++ b/tests/unit/gapic/asset_v1p4beta1/test_asset_service.py @@ -32,6 +32,7 @@ from google.api_core import grpc_helpers_async from google.api_core import operation_async # type: ignore from google.api_core import operations_v1 +from google.api_core import path_template from google.auth import credentials as ga_credentials from google.auth.exceptions import MutualTLSChannelError from google.cloud.asset_v1p4beta1.services.asset_service import AssetServiceAsyncClient @@ -885,6 +886,9 @@ def test_asset_service_base_transport(): with pytest.raises(NotImplementedError): getattr(transport, method)(request=object()) + with pytest.raises(NotImplementedError): + transport.close() + # Additionally, the LRO client (a property) should # also raise NotImplementedError with pytest.raises(NotImplementedError): @@ -1363,3 +1367,49 @@ def test_client_withDEFAULT_CLIENT_INFO(): credentials=ga_credentials.AnonymousCredentials(), client_info=client_info, ) prep.assert_called_once_with(client_info) + + +@pytest.mark.asyncio +async def test_transport_close_async(): + client = AssetServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc_asyncio", + ) + with mock.patch.object( + type(getattr(client.transport, "grpc_channel")), "close" + ) as close: + async with client: + close.assert_not_called() + close.assert_called_once() + + +def test_transport_close(): + transports = { + "grpc": "_grpc_channel", + } + + for transport, close_name in transports.items(): + client = AssetServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport=transport + ) + with mock.patch.object( + type(getattr(client.transport, close_name)), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + +def test_client_ctx(): + transports = [ + "grpc", + ] + for transport in transports: + client = AssetServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport=transport + ) + # Test client calls underlying transport. + with mock.patch.object(type(client.transport), "close") as close: + close.assert_not_called() + with client: + pass + close.assert_called() diff --git a/tests/unit/gapic/asset_v1p5beta1/test_asset_service.py b/tests/unit/gapic/asset_v1p5beta1/test_asset_service.py index 3070a970..b2c75ae9 100644 --- a/tests/unit/gapic/asset_v1p5beta1/test_asset_service.py +++ b/tests/unit/gapic/asset_v1p5beta1/test_asset_service.py @@ -29,6 +29,7 @@ from google.api_core import gapic_v1 from google.api_core import grpc_helpers from google.api_core import grpc_helpers_async +from google.api_core import path_template from google.auth import credentials as ga_credentials from google.auth.exceptions import MutualTLSChannelError from google.cloud.asset_v1p5beta1.services.asset_service import AssetServiceAsyncClient @@ -832,6 +833,9 @@ def test_asset_service_base_transport(): with pytest.raises(NotImplementedError): getattr(transport, method)(request=object()) + with pytest.raises(NotImplementedError): + transport.close() + @requires_google_auth_gte_1_25_0 def test_asset_service_base_transport_with_credentials_file(): @@ -1347,3 +1351,49 @@ def test_client_withDEFAULT_CLIENT_INFO(): credentials=ga_credentials.AnonymousCredentials(), client_info=client_info, ) prep.assert_called_once_with(client_info) + + +@pytest.mark.asyncio +async def test_transport_close_async(): + client = AssetServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc_asyncio", + ) + with mock.patch.object( + type(getattr(client.transport, "grpc_channel")), "close" + ) as close: + async with client: + close.assert_not_called() + close.assert_called_once() + + +def test_transport_close(): + transports = { + "grpc": "_grpc_channel", + } + + for transport, close_name in transports.items(): + client = AssetServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport=transport + ) + with mock.patch.object( + type(getattr(client.transport, close_name)), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + +def test_client_ctx(): + transports = [ + "grpc", + ] + for transport in transports: + client = AssetServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport=transport + ) + # Test client calls underlying transport. + with mock.patch.object(type(client.transport), "close") as close: + close.assert_not_called() + with client: + pass + close.assert_called()