From 8149df9e3038bf02483fb2ee0c9dfc9d713a6152 Mon Sep 17 00:00:00 2001 From: "gcf-owl-bot[bot]" <78513119+gcf-owl-bot[bot]@users.noreply.github.com> Date: Wed, 3 Nov 2021 11:28:12 +0000 Subject: [PATCH] feat: add reCAPTCHA Enterprise account defender API methods (#146) - [ ] Regenerate this pull request now. This cl adds the following API methods to support the Preview release of reCAPTCHA Enterprise account defender: ListRelatedAccountGroups, ListRelatedAccountGroupMemberships, and SearchRelatedAccountGroupMemberships. Additionally it modifies the existing createAssessment API method to add a new hashed_account_id parameter along with AccountDefenderAssessment return value. PiperOrigin-RevId: 407130991 Source-Link: https://github.com/googleapis/googleapis/commit/d58e602ed8a92b8d21da92543528fa5980be6811 Source-Link: https://github.com/googleapis/googleapis-gen/commit/d1b97bf27608e42b5324f65916b16986d855e1b9 Copy-Tag: eyJwIjoiLmdpdGh1Yi8uT3dsQm90LnlhbWwiLCJoIjoiZDFiOTdiZjI3NjA4ZTQyYjUzMjRmNjU5MTZiMTY5ODZkODU1ZTFiOSJ9 --- google/cloud/recaptchaenterprise/__init__.py | 36 + .../cloud/recaptchaenterprise_v1/__init__.py | 18 + .../gapic_metadata.json | 30 + .../async_client.py | 275 ++++ .../recaptcha_enterprise_service/client.py | 311 ++++ .../recaptcha_enterprise_service/pagers.py | 420 +++++ .../transports/base.py | 51 + .../transports/grpc.py | 93 ++ .../transports/grpc_asyncio.py | 93 ++ .../recaptchaenterprise_v1/types/__init__.py | 18 + .../types/recaptchaenterprise.py | 252 ++- .../fixup_recaptchaenterprise_v1_keywords.py | 5 +- .../test_recaptcha_enterprise_service.py | 1375 ++++++++++++++++- 13 files changed, 2957 insertions(+), 20 deletions(-) diff --git a/google/cloud/recaptchaenterprise/__init__.py b/google/cloud/recaptchaenterprise/__init__.py index 3efc980..7750bf5 100644 --- a/google/cloud/recaptchaenterprise/__init__.py +++ b/google/cloud/recaptchaenterprise/__init__.py @@ -21,6 +21,9 @@ RecaptchaEnterpriseServiceAsyncClient, ) +from google.cloud.recaptchaenterprise_v1.types.recaptchaenterprise import ( + AccountDefenderAssessment, +) from google.cloud.recaptchaenterprise_v1.types.recaptchaenterprise import ( AndroidKeySettings, ) @@ -56,15 +59,39 @@ from google.cloud.recaptchaenterprise_v1.types.recaptchaenterprise import ( ListKeysResponse, ) +from google.cloud.recaptchaenterprise_v1.types.recaptchaenterprise import ( + ListRelatedAccountGroupMembershipsRequest, +) +from google.cloud.recaptchaenterprise_v1.types.recaptchaenterprise import ( + ListRelatedAccountGroupMembershipsResponse, +) +from google.cloud.recaptchaenterprise_v1.types.recaptchaenterprise import ( + ListRelatedAccountGroupsRequest, +) +from google.cloud.recaptchaenterprise_v1.types.recaptchaenterprise import ( + ListRelatedAccountGroupsResponse, +) from google.cloud.recaptchaenterprise_v1.types.recaptchaenterprise import Metrics from google.cloud.recaptchaenterprise_v1.types.recaptchaenterprise import ( MigrateKeyRequest, ) +from google.cloud.recaptchaenterprise_v1.types.recaptchaenterprise import ( + RelatedAccountGroup, +) +from google.cloud.recaptchaenterprise_v1.types.recaptchaenterprise import ( + RelatedAccountGroupMembership, +) from google.cloud.recaptchaenterprise_v1.types.recaptchaenterprise import RiskAnalysis from google.cloud.recaptchaenterprise_v1.types.recaptchaenterprise import ( ScoreDistribution, ) from google.cloud.recaptchaenterprise_v1.types.recaptchaenterprise import ScoreMetrics +from google.cloud.recaptchaenterprise_v1.types.recaptchaenterprise import ( + SearchRelatedAccountGroupMembershipsRequest, +) +from google.cloud.recaptchaenterprise_v1.types.recaptchaenterprise import ( + SearchRelatedAccountGroupMembershipsResponse, +) from google.cloud.recaptchaenterprise_v1.types.recaptchaenterprise import TestingOptions from google.cloud.recaptchaenterprise_v1.types.recaptchaenterprise import ( TokenProperties, @@ -77,6 +104,7 @@ __all__ = ( "RecaptchaEnterpriseServiceClient", "RecaptchaEnterpriseServiceAsyncClient", + "AccountDefenderAssessment", "AndroidKeySettings", "AnnotateAssessmentRequest", "AnnotateAssessmentResponse", @@ -92,11 +120,19 @@ "Key", "ListKeysRequest", "ListKeysResponse", + "ListRelatedAccountGroupMembershipsRequest", + "ListRelatedAccountGroupMembershipsResponse", + "ListRelatedAccountGroupsRequest", + "ListRelatedAccountGroupsResponse", "Metrics", "MigrateKeyRequest", + "RelatedAccountGroup", + "RelatedAccountGroupMembership", "RiskAnalysis", "ScoreDistribution", "ScoreMetrics", + "SearchRelatedAccountGroupMembershipsRequest", + "SearchRelatedAccountGroupMembershipsResponse", "TestingOptions", "TokenProperties", "UpdateKeyRequest", diff --git a/google/cloud/recaptchaenterprise_v1/__init__.py b/google/cloud/recaptchaenterprise_v1/__init__.py index b98676d..54006cf 100644 --- a/google/cloud/recaptchaenterprise_v1/__init__.py +++ b/google/cloud/recaptchaenterprise_v1/__init__.py @@ -17,6 +17,7 @@ from .services.recaptcha_enterprise_service import RecaptchaEnterpriseServiceClient from .services.recaptcha_enterprise_service import RecaptchaEnterpriseServiceAsyncClient +from .types.recaptchaenterprise import AccountDefenderAssessment from .types.recaptchaenterprise import AndroidKeySettings from .types.recaptchaenterprise import AnnotateAssessmentRequest from .types.recaptchaenterprise import AnnotateAssessmentResponse @@ -32,11 +33,19 @@ from .types.recaptchaenterprise import Key from .types.recaptchaenterprise import ListKeysRequest from .types.recaptchaenterprise import ListKeysResponse +from .types.recaptchaenterprise import ListRelatedAccountGroupMembershipsRequest +from .types.recaptchaenterprise import ListRelatedAccountGroupMembershipsResponse +from .types.recaptchaenterprise import ListRelatedAccountGroupsRequest +from .types.recaptchaenterprise import ListRelatedAccountGroupsResponse from .types.recaptchaenterprise import Metrics from .types.recaptchaenterprise import MigrateKeyRequest +from .types.recaptchaenterprise import RelatedAccountGroup +from .types.recaptchaenterprise import RelatedAccountGroupMembership from .types.recaptchaenterprise import RiskAnalysis from .types.recaptchaenterprise import ScoreDistribution from .types.recaptchaenterprise import ScoreMetrics +from .types.recaptchaenterprise import SearchRelatedAccountGroupMembershipsRequest +from .types.recaptchaenterprise import SearchRelatedAccountGroupMembershipsResponse from .types.recaptchaenterprise import TestingOptions from .types.recaptchaenterprise import TokenProperties from .types.recaptchaenterprise import UpdateKeyRequest @@ -44,6 +53,7 @@ __all__ = ( "RecaptchaEnterpriseServiceAsyncClient", + "AccountDefenderAssessment", "AndroidKeySettings", "AnnotateAssessmentRequest", "AnnotateAssessmentResponse", @@ -59,12 +69,20 @@ "Key", "ListKeysRequest", "ListKeysResponse", + "ListRelatedAccountGroupMembershipsRequest", + "ListRelatedAccountGroupMembershipsResponse", + "ListRelatedAccountGroupsRequest", + "ListRelatedAccountGroupsResponse", "Metrics", "MigrateKeyRequest", "RecaptchaEnterpriseServiceClient", + "RelatedAccountGroup", + "RelatedAccountGroupMembership", "RiskAnalysis", "ScoreDistribution", "ScoreMetrics", + "SearchRelatedAccountGroupMembershipsRequest", + "SearchRelatedAccountGroupMembershipsResponse", "TestingOptions", "TokenProperties", "UpdateKeyRequest", diff --git a/google/cloud/recaptchaenterprise_v1/gapic_metadata.json b/google/cloud/recaptchaenterprise_v1/gapic_metadata.json index aac10be..a170c7f 100644 --- a/google/cloud/recaptchaenterprise_v1/gapic_metadata.json +++ b/google/cloud/recaptchaenterprise_v1/gapic_metadata.json @@ -45,11 +45,26 @@ "list_keys" ] }, + "ListRelatedAccountGroupMemberships": { + "methods": [ + "list_related_account_group_memberships" + ] + }, + "ListRelatedAccountGroups": { + "methods": [ + "list_related_account_groups" + ] + }, "MigrateKey": { "methods": [ "migrate_key" ] }, + "SearchRelatedAccountGroupMemberships": { + "methods": [ + "search_related_account_group_memberships" + ] + }, "UpdateKey": { "methods": [ "update_key" @@ -95,11 +110,26 @@ "list_keys" ] }, + "ListRelatedAccountGroupMemberships": { + "methods": [ + "list_related_account_group_memberships" + ] + }, + "ListRelatedAccountGroups": { + "methods": [ + "list_related_account_groups" + ] + }, "MigrateKey": { "methods": [ "migrate_key" ] }, + "SearchRelatedAccountGroupMemberships": { + "methods": [ + "search_related_account_group_memberships" + ] + }, "UpdateKey": { "methods": [ "update_key" diff --git a/google/cloud/recaptchaenterprise_v1/services/recaptcha_enterprise_service/async_client.py b/google/cloud/recaptchaenterprise_v1/services/recaptcha_enterprise_service/async_client.py index 3706409..97cc6af 100644 --- a/google/cloud/recaptchaenterprise_v1/services/recaptcha_enterprise_service/async_client.py +++ b/google/cloud/recaptchaenterprise_v1/services/recaptcha_enterprise_service/async_client.py @@ -56,6 +56,18 @@ class RecaptchaEnterpriseServiceAsyncClient: parse_metrics_path = staticmethod( RecaptchaEnterpriseServiceClient.parse_metrics_path ) + related_account_group_path = staticmethod( + RecaptchaEnterpriseServiceClient.related_account_group_path + ) + parse_related_account_group_path = staticmethod( + RecaptchaEnterpriseServiceClient.parse_related_account_group_path + ) + related_account_group_membership_path = staticmethod( + RecaptchaEnterpriseServiceClient.related_account_group_membership_path + ) + parse_related_account_group_membership_path = staticmethod( + RecaptchaEnterpriseServiceClient.parse_related_account_group_membership_path + ) common_billing_account_path = staticmethod( RecaptchaEnterpriseServiceClient.common_billing_account_path ) @@ -718,6 +730,269 @@ async def get_metrics( # Done; return the response. return response + async def list_related_account_groups( + self, + request: Union[ + recaptchaenterprise.ListRelatedAccountGroupsRequest, dict + ] = None, + *, + parent: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ListRelatedAccountGroupsAsyncPager: + r"""List groups of related accounts. + + Args: + request (Union[google.cloud.recaptchaenterprise_v1.types.ListRelatedAccountGroupsRequest, dict]): + The request object. The request message to list related + account groups. + parent (:class:`str`): + Required. The name of the project to + list related account groups from, in the + format "projects/{project}". + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.recaptchaenterprise_v1.services.recaptcha_enterprise_service.pagers.ListRelatedAccountGroupsAsyncPager: + The response to a ListRelatedAccountGroups call. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = recaptchaenterprise.ListRelatedAccountGroupsRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.list_related_account_groups, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Send the request. + response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # This method is paged; wrap the response in a pager, which provides + # an `__aiter__` convenience method. + response = pagers.ListRelatedAccountGroupsAsyncPager( + method=rpc, request=request, response=response, metadata=metadata, + ) + + # Done; return the response. + return response + + async def list_related_account_group_memberships( + self, + request: Union[ + recaptchaenterprise.ListRelatedAccountGroupMembershipsRequest, dict + ] = None, + *, + parent: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ListRelatedAccountGroupMembershipsAsyncPager: + r"""Get the memberships in a group of related accounts. + + Args: + request (Union[google.cloud.recaptchaenterprise_v1.types.ListRelatedAccountGroupMembershipsRequest, dict]): + The request object. The request message to list + memberships in a related account group. + parent (:class:`str`): + Required. The resource name for the related account + group in the format + ``projects/{project}/relatedaccountgroups/{relatedaccountgroup}``. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.recaptchaenterprise_v1.services.recaptcha_enterprise_service.pagers.ListRelatedAccountGroupMembershipsAsyncPager: + The response to a ListRelatedAccountGroupMemberships + call. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = recaptchaenterprise.ListRelatedAccountGroupMembershipsRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.list_related_account_group_memberships, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Send the request. + response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # This method is paged; wrap the response in a pager, which provides + # an `__aiter__` convenience method. + response = pagers.ListRelatedAccountGroupMembershipsAsyncPager( + method=rpc, request=request, response=response, metadata=metadata, + ) + + # Done; return the response. + return response + + async def search_related_account_group_memberships( + self, + request: Union[ + recaptchaenterprise.SearchRelatedAccountGroupMembershipsRequest, dict + ] = None, + *, + parent: str = None, + hashed_account_id: bytes = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.SearchRelatedAccountGroupMembershipsAsyncPager: + r"""Search group memberships related to a given account. + + Args: + request (Union[google.cloud.recaptchaenterprise_v1.types.SearchRelatedAccountGroupMembershipsRequest, dict]): + The request object. The request message to search + related account group memberships. + parent (:class:`str`): + Required. The name of the project to + search related account group memberships + from, in the format + "projects/{project}". + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + hashed_account_id (:class:`bytes`): + Optional. The unique stable hashed user identifier we + should search connections to. The identifier should + correspond to a ``hashed_account_id`` provided in a + previous CreateAssessment or AnnotateAssessment call. + + This corresponds to the ``hashed_account_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.recaptchaenterprise_v1.services.recaptcha_enterprise_service.pagers.SearchRelatedAccountGroupMembershipsAsyncPager: + The response to a SearchRelatedAccountGroupMemberships + call. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent, hashed_account_id]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = recaptchaenterprise.SearchRelatedAccountGroupMembershipsRequest( + request + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if hashed_account_id is not None: + request.hashed_account_id = hashed_account_id + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.search_related_account_group_memberships, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Send the request. + response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # This method is paged; wrap the response in a pager, which provides + # an `__aiter__` convenience method. + response = pagers.SearchRelatedAccountGroupMembershipsAsyncPager( + method=rpc, request=request, response=response, metadata=metadata, + ) + + # Done; return the response. + return response + async def __aenter__(self): return self diff --git a/google/cloud/recaptchaenterprise_v1/services/recaptcha_enterprise_service/client.py b/google/cloud/recaptchaenterprise_v1/services/recaptcha_enterprise_service/client.py index f5010e7..f972701 100644 --- a/google/cloud/recaptchaenterprise_v1/services/recaptcha_enterprise_service/client.py +++ b/google/cloud/recaptchaenterprise_v1/services/recaptcha_enterprise_service/client.py @@ -199,6 +199,42 @@ def parse_metrics_path(path: str) -> Dict[str, str]: m = re.match(r"^projects/(?P.+?)/keys/(?P.+?)/metrics$", path) return m.groupdict() if m else {} + @staticmethod + def related_account_group_path(project: str, relatedaccountgroup: str,) -> str: + """Returns a fully-qualified related_account_group string.""" + return "projects/{project}/relatedaccountgroups/{relatedaccountgroup}".format( + project=project, relatedaccountgroup=relatedaccountgroup, + ) + + @staticmethod + def parse_related_account_group_path(path: str) -> Dict[str, str]: + """Parses a related_account_group path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/relatedaccountgroups/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def related_account_group_membership_path( + project: str, relatedaccountgroup: str, membership: str, + ) -> str: + """Returns a fully-qualified related_account_group_membership string.""" + return "projects/{project}/relatedaccountgroups/{relatedaccountgroup}/memberships/{membership}".format( + project=project, + relatedaccountgroup=relatedaccountgroup, + membership=membership, + ) + + @staticmethod + def parse_related_account_group_membership_path(path: str) -> Dict[str, str]: + """Parses a related_account_group_membership path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/relatedaccountgroups/(?P.+?)/memberships/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + @staticmethod def common_billing_account_path(billing_account: str,) -> str: """Returns a fully-qualified billing_account string.""" @@ -918,6 +954,281 @@ def get_metrics( # Done; return the response. return response + def list_related_account_groups( + self, + request: Union[ + recaptchaenterprise.ListRelatedAccountGroupsRequest, dict + ] = None, + *, + parent: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ListRelatedAccountGroupsPager: + r"""List groups of related accounts. + + Args: + request (Union[google.cloud.recaptchaenterprise_v1.types.ListRelatedAccountGroupsRequest, dict]): + The request object. The request message to list related + account groups. + parent (str): + Required. The name of the project to + list related account groups from, in the + format "projects/{project}". + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.recaptchaenterprise_v1.services.recaptcha_enterprise_service.pagers.ListRelatedAccountGroupsPager: + The response to a ListRelatedAccountGroups call. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a recaptchaenterprise.ListRelatedAccountGroupsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, recaptchaenterprise.ListRelatedAccountGroupsRequest): + request = recaptchaenterprise.ListRelatedAccountGroupsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.list_related_account_groups + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Send the request. + response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # This method is paged; wrap the response in a pager, which provides + # an `__iter__` convenience method. + response = pagers.ListRelatedAccountGroupsPager( + method=rpc, request=request, response=response, metadata=metadata, + ) + + # Done; return the response. + return response + + def list_related_account_group_memberships( + self, + request: Union[ + recaptchaenterprise.ListRelatedAccountGroupMembershipsRequest, dict + ] = None, + *, + parent: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ListRelatedAccountGroupMembershipsPager: + r"""Get the memberships in a group of related accounts. + + Args: + request (Union[google.cloud.recaptchaenterprise_v1.types.ListRelatedAccountGroupMembershipsRequest, dict]): + The request object. The request message to list + memberships in a related account group. + parent (str): + Required. The resource name for the related account + group in the format + ``projects/{project}/relatedaccountgroups/{relatedaccountgroup}``. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.recaptchaenterprise_v1.services.recaptcha_enterprise_service.pagers.ListRelatedAccountGroupMembershipsPager: + The response to a ListRelatedAccountGroupMemberships + call. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a recaptchaenterprise.ListRelatedAccountGroupMembershipsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, recaptchaenterprise.ListRelatedAccountGroupMembershipsRequest + ): + request = recaptchaenterprise.ListRelatedAccountGroupMembershipsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.list_related_account_group_memberships + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Send the request. + response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # This method is paged; wrap the response in a pager, which provides + # an `__iter__` convenience method. + response = pagers.ListRelatedAccountGroupMembershipsPager( + method=rpc, request=request, response=response, metadata=metadata, + ) + + # Done; return the response. + return response + + def search_related_account_group_memberships( + self, + request: Union[ + recaptchaenterprise.SearchRelatedAccountGroupMembershipsRequest, dict + ] = None, + *, + parent: str = None, + hashed_account_id: bytes = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.SearchRelatedAccountGroupMembershipsPager: + r"""Search group memberships related to a given account. + + Args: + request (Union[google.cloud.recaptchaenterprise_v1.types.SearchRelatedAccountGroupMembershipsRequest, dict]): + The request object. The request message to search + related account group memberships. + parent (str): + Required. The name of the project to + search related account group memberships + from, in the format + "projects/{project}". + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + hashed_account_id (bytes): + Optional. The unique stable hashed user identifier we + should search connections to. The identifier should + correspond to a ``hashed_account_id`` provided in a + previous CreateAssessment or AnnotateAssessment call. + + This corresponds to the ``hashed_account_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.recaptchaenterprise_v1.services.recaptcha_enterprise_service.pagers.SearchRelatedAccountGroupMembershipsPager: + The response to a SearchRelatedAccountGroupMemberships + call. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent, hashed_account_id]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a recaptchaenterprise.SearchRelatedAccountGroupMembershipsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, recaptchaenterprise.SearchRelatedAccountGroupMembershipsRequest + ): + request = recaptchaenterprise.SearchRelatedAccountGroupMembershipsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if hashed_account_id is not None: + request.hashed_account_id = hashed_account_id + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.search_related_account_group_memberships + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Send the request. + response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # This method is paged; wrap the response in a pager, which provides + # an `__iter__` convenience method. + response = pagers.SearchRelatedAccountGroupMembershipsPager( + method=rpc, request=request, response=response, metadata=metadata, + ) + + # Done; return the response. + return response + def __enter__(self): return self diff --git a/google/cloud/recaptchaenterprise_v1/services/recaptcha_enterprise_service/pagers.py b/google/cloud/recaptchaenterprise_v1/services/recaptcha_enterprise_service/pagers.py index 158b928..5049b7e 100644 --- a/google/cloud/recaptchaenterprise_v1/services/recaptcha_enterprise_service/pagers.py +++ b/google/cloud/recaptchaenterprise_v1/services/recaptcha_enterprise_service/pagers.py @@ -153,3 +153,423 @@ async def async_generator(): def __repr__(self) -> str: return "{0}<{1!r}>".format(self.__class__.__name__, self._response) + + +class ListRelatedAccountGroupsPager: + """A pager for iterating through ``list_related_account_groups`` requests. + + This class thinly wraps an initial + :class:`google.cloud.recaptchaenterprise_v1.types.ListRelatedAccountGroupsResponse` object, and + provides an ``__iter__`` method to iterate through its + ``related_account_groups`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListRelatedAccountGroups`` requests and continue to iterate + through the ``related_account_groups`` field on the + corresponding responses. + + All the usual :class:`google.cloud.recaptchaenterprise_v1.types.ListRelatedAccountGroupsResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + + def __init__( + self, + method: Callable[..., recaptchaenterprise.ListRelatedAccountGroupsResponse], + request: recaptchaenterprise.ListRelatedAccountGroupsRequest, + response: recaptchaenterprise.ListRelatedAccountGroupsResponse, + *, + metadata: Sequence[Tuple[str, str]] = () + ): + """Instantiate the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.recaptchaenterprise_v1.types.ListRelatedAccountGroupsRequest): + The initial request object. + response (google.cloud.recaptchaenterprise_v1.types.ListRelatedAccountGroupsResponse): + The initial response object. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = recaptchaenterprise.ListRelatedAccountGroupsRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages(self) -> Iterator[recaptchaenterprise.ListRelatedAccountGroupsResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = self._method(self._request, metadata=self._metadata) + yield self._response + + def __iter__(self) -> Iterator[recaptchaenterprise.RelatedAccountGroup]: + for page in self.pages: + yield from page.related_account_groups + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) + + +class ListRelatedAccountGroupsAsyncPager: + """A pager for iterating through ``list_related_account_groups`` requests. + + This class thinly wraps an initial + :class:`google.cloud.recaptchaenterprise_v1.types.ListRelatedAccountGroupsResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``related_account_groups`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``ListRelatedAccountGroups`` requests and continue to iterate + through the ``related_account_groups`` field on the + corresponding responses. + + All the usual :class:`google.cloud.recaptchaenterprise_v1.types.ListRelatedAccountGroupsResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + + def __init__( + self, + method: Callable[ + ..., Awaitable[recaptchaenterprise.ListRelatedAccountGroupsResponse] + ], + request: recaptchaenterprise.ListRelatedAccountGroupsRequest, + response: recaptchaenterprise.ListRelatedAccountGroupsResponse, + *, + metadata: Sequence[Tuple[str, str]] = () + ): + """Instantiates the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.recaptchaenterprise_v1.types.ListRelatedAccountGroupsRequest): + The initial request object. + response (google.cloud.recaptchaenterprise_v1.types.ListRelatedAccountGroupsResponse): + The initial response object. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = recaptchaenterprise.ListRelatedAccountGroupsRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages( + self, + ) -> AsyncIterator[recaptchaenterprise.ListRelatedAccountGroupsResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = await self._method(self._request, metadata=self._metadata) + yield self._response + + def __aiter__(self) -> AsyncIterator[recaptchaenterprise.RelatedAccountGroup]: + async def async_generator(): + async for page in self.pages: + for response in page.related_account_groups: + yield response + + return async_generator() + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) + + +class ListRelatedAccountGroupMembershipsPager: + """A pager for iterating through ``list_related_account_group_memberships`` requests. + + This class thinly wraps an initial + :class:`google.cloud.recaptchaenterprise_v1.types.ListRelatedAccountGroupMembershipsResponse` object, and + provides an ``__iter__`` method to iterate through its + ``related_account_group_memberships`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListRelatedAccountGroupMemberships`` requests and continue to iterate + through the ``related_account_group_memberships`` field on the + corresponding responses. + + All the usual :class:`google.cloud.recaptchaenterprise_v1.types.ListRelatedAccountGroupMembershipsResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + + def __init__( + self, + method: Callable[ + ..., recaptchaenterprise.ListRelatedAccountGroupMembershipsResponse + ], + request: recaptchaenterprise.ListRelatedAccountGroupMembershipsRequest, + response: recaptchaenterprise.ListRelatedAccountGroupMembershipsResponse, + *, + metadata: Sequence[Tuple[str, str]] = () + ): + """Instantiate the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.recaptchaenterprise_v1.types.ListRelatedAccountGroupMembershipsRequest): + The initial request object. + response (google.cloud.recaptchaenterprise_v1.types.ListRelatedAccountGroupMembershipsResponse): + The initial response object. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = recaptchaenterprise.ListRelatedAccountGroupMembershipsRequest( + request + ) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages( + self, + ) -> Iterator[recaptchaenterprise.ListRelatedAccountGroupMembershipsResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = self._method(self._request, metadata=self._metadata) + yield self._response + + def __iter__(self) -> Iterator[recaptchaenterprise.RelatedAccountGroupMembership]: + for page in self.pages: + yield from page.related_account_group_memberships + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) + + +class ListRelatedAccountGroupMembershipsAsyncPager: + """A pager for iterating through ``list_related_account_group_memberships`` requests. + + This class thinly wraps an initial + :class:`google.cloud.recaptchaenterprise_v1.types.ListRelatedAccountGroupMembershipsResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``related_account_group_memberships`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``ListRelatedAccountGroupMemberships`` requests and continue to iterate + through the ``related_account_group_memberships`` field on the + corresponding responses. + + All the usual :class:`google.cloud.recaptchaenterprise_v1.types.ListRelatedAccountGroupMembershipsResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + + def __init__( + self, + method: Callable[ + ..., + Awaitable[recaptchaenterprise.ListRelatedAccountGroupMembershipsResponse], + ], + request: recaptchaenterprise.ListRelatedAccountGroupMembershipsRequest, + response: recaptchaenterprise.ListRelatedAccountGroupMembershipsResponse, + *, + metadata: Sequence[Tuple[str, str]] = () + ): + """Instantiates the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.recaptchaenterprise_v1.types.ListRelatedAccountGroupMembershipsRequest): + The initial request object. + response (google.cloud.recaptchaenterprise_v1.types.ListRelatedAccountGroupMembershipsResponse): + The initial response object. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = recaptchaenterprise.ListRelatedAccountGroupMembershipsRequest( + request + ) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages( + self, + ) -> AsyncIterator[recaptchaenterprise.ListRelatedAccountGroupMembershipsResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = await self._method(self._request, metadata=self._metadata) + yield self._response + + def __aiter__( + self, + ) -> AsyncIterator[recaptchaenterprise.RelatedAccountGroupMembership]: + async def async_generator(): + async for page in self.pages: + for response in page.related_account_group_memberships: + yield response + + return async_generator() + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) + + +class SearchRelatedAccountGroupMembershipsPager: + """A pager for iterating through ``search_related_account_group_memberships`` requests. + + This class thinly wraps an initial + :class:`google.cloud.recaptchaenterprise_v1.types.SearchRelatedAccountGroupMembershipsResponse` object, and + provides an ``__iter__`` method to iterate through its + ``related_account_group_memberships`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``SearchRelatedAccountGroupMemberships`` requests and continue to iterate + through the ``related_account_group_memberships`` field on the + corresponding responses. + + All the usual :class:`google.cloud.recaptchaenterprise_v1.types.SearchRelatedAccountGroupMembershipsResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + + def __init__( + self, + method: Callable[ + ..., recaptchaenterprise.SearchRelatedAccountGroupMembershipsResponse + ], + request: recaptchaenterprise.SearchRelatedAccountGroupMembershipsRequest, + response: recaptchaenterprise.SearchRelatedAccountGroupMembershipsResponse, + *, + metadata: Sequence[Tuple[str, str]] = () + ): + """Instantiate the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.recaptchaenterprise_v1.types.SearchRelatedAccountGroupMembershipsRequest): + The initial request object. + response (google.cloud.recaptchaenterprise_v1.types.SearchRelatedAccountGroupMembershipsResponse): + The initial response object. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = recaptchaenterprise.SearchRelatedAccountGroupMembershipsRequest( + request + ) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages( + self, + ) -> Iterator[recaptchaenterprise.SearchRelatedAccountGroupMembershipsResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = self._method(self._request, metadata=self._metadata) + yield self._response + + def __iter__(self) -> Iterator[recaptchaenterprise.RelatedAccountGroupMembership]: + for page in self.pages: + yield from page.related_account_group_memberships + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) + + +class SearchRelatedAccountGroupMembershipsAsyncPager: + """A pager for iterating through ``search_related_account_group_memberships`` requests. + + This class thinly wraps an initial + :class:`google.cloud.recaptchaenterprise_v1.types.SearchRelatedAccountGroupMembershipsResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``related_account_group_memberships`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``SearchRelatedAccountGroupMemberships`` requests and continue to iterate + through the ``related_account_group_memberships`` field on the + corresponding responses. + + All the usual :class:`google.cloud.recaptchaenterprise_v1.types.SearchRelatedAccountGroupMembershipsResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + + def __init__( + self, + method: Callable[ + ..., + Awaitable[recaptchaenterprise.SearchRelatedAccountGroupMembershipsResponse], + ], + request: recaptchaenterprise.SearchRelatedAccountGroupMembershipsRequest, + response: recaptchaenterprise.SearchRelatedAccountGroupMembershipsResponse, + *, + metadata: Sequence[Tuple[str, str]] = () + ): + """Instantiates the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.recaptchaenterprise_v1.types.SearchRelatedAccountGroupMembershipsRequest): + The initial request object. + response (google.cloud.recaptchaenterprise_v1.types.SearchRelatedAccountGroupMembershipsResponse): + The initial response object. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = recaptchaenterprise.SearchRelatedAccountGroupMembershipsRequest( + request + ) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages( + self, + ) -> AsyncIterator[ + recaptchaenterprise.SearchRelatedAccountGroupMembershipsResponse + ]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = await self._method(self._request, metadata=self._metadata) + yield self._response + + def __aiter__( + self, + ) -> AsyncIterator[recaptchaenterprise.RelatedAccountGroupMembership]: + async def async_generator(): + async for page in self.pages: + for response in page.related_account_group_memberships: + yield response + + return async_generator() + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) diff --git a/google/cloud/recaptchaenterprise_v1/services/recaptcha_enterprise_service/transports/base.py b/google/cloud/recaptchaenterprise_v1/services/recaptcha_enterprise_service/transports/base.py index 34aa42e..25a8ef2 100644 --- a/google/cloud/recaptchaenterprise_v1/services/recaptcha_enterprise_service/transports/base.py +++ b/google/cloud/recaptchaenterprise_v1/services/recaptcha_enterprise_service/transports/base.py @@ -151,6 +151,21 @@ def _prep_wrapped_messages(self, client_info): self.get_metrics: gapic_v1.method.wrap_method( self.get_metrics, default_timeout=None, client_info=client_info, ), + self.list_related_account_groups: gapic_v1.method.wrap_method( + self.list_related_account_groups, + default_timeout=None, + client_info=client_info, + ), + self.list_related_account_group_memberships: gapic_v1.method.wrap_method( + self.list_related_account_group_memberships, + default_timeout=None, + client_info=client_info, + ), + self.search_related_account_group_memberships: gapic_v1.method.wrap_method( + self.search_related_account_group_memberships, + default_timeout=None, + client_info=client_info, + ), } def close(self): @@ -251,5 +266,41 @@ def get_metrics( ]: raise NotImplementedError() + @property + def list_related_account_groups( + self, + ) -> Callable[ + [recaptchaenterprise.ListRelatedAccountGroupsRequest], + Union[ + recaptchaenterprise.ListRelatedAccountGroupsResponse, + Awaitable[recaptchaenterprise.ListRelatedAccountGroupsResponse], + ], + ]: + raise NotImplementedError() + + @property + def list_related_account_group_memberships( + self, + ) -> Callable[ + [recaptchaenterprise.ListRelatedAccountGroupMembershipsRequest], + Union[ + recaptchaenterprise.ListRelatedAccountGroupMembershipsResponse, + Awaitable[recaptchaenterprise.ListRelatedAccountGroupMembershipsResponse], + ], + ]: + raise NotImplementedError() + + @property + def search_related_account_group_memberships( + self, + ) -> Callable[ + [recaptchaenterprise.SearchRelatedAccountGroupMembershipsRequest], + Union[ + recaptchaenterprise.SearchRelatedAccountGroupMembershipsResponse, + Awaitable[recaptchaenterprise.SearchRelatedAccountGroupMembershipsResponse], + ], + ]: + raise NotImplementedError() + __all__ = ("RecaptchaEnterpriseServiceTransport",) diff --git a/google/cloud/recaptchaenterprise_v1/services/recaptcha_enterprise_service/transports/grpc.py b/google/cloud/recaptchaenterprise_v1/services/recaptcha_enterprise_service/transports/grpc.py index 65a5dda..35852bd 100644 --- a/google/cloud/recaptchaenterprise_v1/services/recaptcha_enterprise_service/transports/grpc.py +++ b/google/cloud/recaptchaenterprise_v1/services/recaptcha_enterprise_service/transports/grpc.py @@ -478,6 +478,99 @@ def get_metrics( ) return self._stubs["get_metrics"] + @property + def list_related_account_groups( + self, + ) -> Callable[ + [recaptchaenterprise.ListRelatedAccountGroupsRequest], + recaptchaenterprise.ListRelatedAccountGroupsResponse, + ]: + r"""Return a callable for the list related account groups method over gRPC. + + List groups of related accounts. + + Returns: + Callable[[~.ListRelatedAccountGroupsRequest], + ~.ListRelatedAccountGroupsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_related_account_groups" not in self._stubs: + self._stubs["list_related_account_groups"] = self.grpc_channel.unary_unary( + "/google.cloud.recaptchaenterprise.v1.RecaptchaEnterpriseService/ListRelatedAccountGroups", + request_serializer=recaptchaenterprise.ListRelatedAccountGroupsRequest.serialize, + response_deserializer=recaptchaenterprise.ListRelatedAccountGroupsResponse.deserialize, + ) + return self._stubs["list_related_account_groups"] + + @property + def list_related_account_group_memberships( + self, + ) -> Callable[ + [recaptchaenterprise.ListRelatedAccountGroupMembershipsRequest], + recaptchaenterprise.ListRelatedAccountGroupMembershipsResponse, + ]: + r"""Return a callable for the list related account group + memberships method over gRPC. + + Get the memberships in a group of related accounts. + + Returns: + Callable[[~.ListRelatedAccountGroupMembershipsRequest], + ~.ListRelatedAccountGroupMembershipsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_related_account_group_memberships" not in self._stubs: + self._stubs[ + "list_related_account_group_memberships" + ] = self.grpc_channel.unary_unary( + "/google.cloud.recaptchaenterprise.v1.RecaptchaEnterpriseService/ListRelatedAccountGroupMemberships", + request_serializer=recaptchaenterprise.ListRelatedAccountGroupMembershipsRequest.serialize, + response_deserializer=recaptchaenterprise.ListRelatedAccountGroupMembershipsResponse.deserialize, + ) + return self._stubs["list_related_account_group_memberships"] + + @property + def search_related_account_group_memberships( + self, + ) -> Callable[ + [recaptchaenterprise.SearchRelatedAccountGroupMembershipsRequest], + recaptchaenterprise.SearchRelatedAccountGroupMembershipsResponse, + ]: + r"""Return a callable for the search related account group + memberships method over gRPC. + + Search group memberships related to a given account. + + Returns: + Callable[[~.SearchRelatedAccountGroupMembershipsRequest], + ~.SearchRelatedAccountGroupMembershipsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "search_related_account_group_memberships" not in self._stubs: + self._stubs[ + "search_related_account_group_memberships" + ] = self.grpc_channel.unary_unary( + "/google.cloud.recaptchaenterprise.v1.RecaptchaEnterpriseService/SearchRelatedAccountGroupMemberships", + request_serializer=recaptchaenterprise.SearchRelatedAccountGroupMembershipsRequest.serialize, + response_deserializer=recaptchaenterprise.SearchRelatedAccountGroupMembershipsResponse.deserialize, + ) + return self._stubs["search_related_account_group_memberships"] + def close(self): self.grpc_channel.close() diff --git a/google/cloud/recaptchaenterprise_v1/services/recaptcha_enterprise_service/transports/grpc_asyncio.py b/google/cloud/recaptchaenterprise_v1/services/recaptcha_enterprise_service/transports/grpc_asyncio.py index ec821bb..3ebf314 100644 --- a/google/cloud/recaptchaenterprise_v1/services/recaptcha_enterprise_service/transports/grpc_asyncio.py +++ b/google/cloud/recaptchaenterprise_v1/services/recaptcha_enterprise_service/transports/grpc_asyncio.py @@ -494,6 +494,99 @@ def get_metrics( ) return self._stubs["get_metrics"] + @property + def list_related_account_groups( + self, + ) -> Callable[ + [recaptchaenterprise.ListRelatedAccountGroupsRequest], + Awaitable[recaptchaenterprise.ListRelatedAccountGroupsResponse], + ]: + r"""Return a callable for the list related account groups method over gRPC. + + List groups of related accounts. + + Returns: + Callable[[~.ListRelatedAccountGroupsRequest], + Awaitable[~.ListRelatedAccountGroupsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_related_account_groups" not in self._stubs: + self._stubs["list_related_account_groups"] = self.grpc_channel.unary_unary( + "/google.cloud.recaptchaenterprise.v1.RecaptchaEnterpriseService/ListRelatedAccountGroups", + request_serializer=recaptchaenterprise.ListRelatedAccountGroupsRequest.serialize, + response_deserializer=recaptchaenterprise.ListRelatedAccountGroupsResponse.deserialize, + ) + return self._stubs["list_related_account_groups"] + + @property + def list_related_account_group_memberships( + self, + ) -> Callable[ + [recaptchaenterprise.ListRelatedAccountGroupMembershipsRequest], + Awaitable[recaptchaenterprise.ListRelatedAccountGroupMembershipsResponse], + ]: + r"""Return a callable for the list related account group + memberships method over gRPC. + + Get the memberships in a group of related accounts. + + Returns: + Callable[[~.ListRelatedAccountGroupMembershipsRequest], + Awaitable[~.ListRelatedAccountGroupMembershipsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_related_account_group_memberships" not in self._stubs: + self._stubs[ + "list_related_account_group_memberships" + ] = self.grpc_channel.unary_unary( + "/google.cloud.recaptchaenterprise.v1.RecaptchaEnterpriseService/ListRelatedAccountGroupMemberships", + request_serializer=recaptchaenterprise.ListRelatedAccountGroupMembershipsRequest.serialize, + response_deserializer=recaptchaenterprise.ListRelatedAccountGroupMembershipsResponse.deserialize, + ) + return self._stubs["list_related_account_group_memberships"] + + @property + def search_related_account_group_memberships( + self, + ) -> Callable[ + [recaptchaenterprise.SearchRelatedAccountGroupMembershipsRequest], + Awaitable[recaptchaenterprise.SearchRelatedAccountGroupMembershipsResponse], + ]: + r"""Return a callable for the search related account group + memberships method over gRPC. + + Search group memberships related to a given account. + + Returns: + Callable[[~.SearchRelatedAccountGroupMembershipsRequest], + Awaitable[~.SearchRelatedAccountGroupMembershipsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "search_related_account_group_memberships" not in self._stubs: + self._stubs[ + "search_related_account_group_memberships" + ] = self.grpc_channel.unary_unary( + "/google.cloud.recaptchaenterprise.v1.RecaptchaEnterpriseService/SearchRelatedAccountGroupMemberships", + request_serializer=recaptchaenterprise.SearchRelatedAccountGroupMembershipsRequest.serialize, + response_deserializer=recaptchaenterprise.SearchRelatedAccountGroupMembershipsResponse.deserialize, + ) + return self._stubs["search_related_account_group_memberships"] + def close(self): return self.grpc_channel.close() diff --git a/google/cloud/recaptchaenterprise_v1/types/__init__.py b/google/cloud/recaptchaenterprise_v1/types/__init__.py index 750356b..3c11c9c 100644 --- a/google/cloud/recaptchaenterprise_v1/types/__init__.py +++ b/google/cloud/recaptchaenterprise_v1/types/__init__.py @@ -14,6 +14,7 @@ # limitations under the License. # from .recaptchaenterprise import ( + AccountDefenderAssessment, AndroidKeySettings, AnnotateAssessmentRequest, AnnotateAssessmentResponse, @@ -29,11 +30,19 @@ Key, ListKeysRequest, ListKeysResponse, + ListRelatedAccountGroupMembershipsRequest, + ListRelatedAccountGroupMembershipsResponse, + ListRelatedAccountGroupsRequest, + ListRelatedAccountGroupsResponse, Metrics, MigrateKeyRequest, + RelatedAccountGroup, + RelatedAccountGroupMembership, RiskAnalysis, ScoreDistribution, ScoreMetrics, + SearchRelatedAccountGroupMembershipsRequest, + SearchRelatedAccountGroupMembershipsResponse, TestingOptions, TokenProperties, UpdateKeyRequest, @@ -41,6 +50,7 @@ ) __all__ = ( + "AccountDefenderAssessment", "AndroidKeySettings", "AnnotateAssessmentRequest", "AnnotateAssessmentResponse", @@ -56,11 +66,19 @@ "Key", "ListKeysRequest", "ListKeysResponse", + "ListRelatedAccountGroupMembershipsRequest", + "ListRelatedAccountGroupMembershipsResponse", + "ListRelatedAccountGroupsRequest", + "ListRelatedAccountGroupsResponse", "Metrics", "MigrateKeyRequest", + "RelatedAccountGroup", + "RelatedAccountGroupMembership", "RiskAnalysis", "ScoreDistribution", "ScoreMetrics", + "SearchRelatedAccountGroupMembershipsRequest", + "SearchRelatedAccountGroupMembershipsResponse", "TestingOptions", "TokenProperties", "UpdateKeyRequest", diff --git a/google/cloud/recaptchaenterprise_v1/types/recaptchaenterprise.py b/google/cloud/recaptchaenterprise_v1/types/recaptchaenterprise.py index 543c8b7..0710c2d 100644 --- a/google/cloud/recaptchaenterprise_v1/types/recaptchaenterprise.py +++ b/google/cloud/recaptchaenterprise_v1/types/recaptchaenterprise.py @@ -29,6 +29,7 @@ "Event", "RiskAnalysis", "TokenProperties", + "AccountDefenderAssessment", "CreateKeyRequest", "ListKeysRequest", "ListKeysResponse", @@ -46,6 +47,14 @@ "ScoreDistribution", "ScoreMetrics", "ChallengeMetrics", + "ListRelatedAccountGroupMembershipsRequest", + "ListRelatedAccountGroupMembershipsResponse", + "ListRelatedAccountGroupsRequest", + "ListRelatedAccountGroupsResponse", + "SearchRelatedAccountGroupMembershipsRequest", + "SearchRelatedAccountGroupMembershipsResponse", + "RelatedAccountGroupMembership", + "RelatedAccountGroup", }, ) @@ -83,6 +92,13 @@ class AnnotateAssessmentRequest(proto.Message): reasons (Sequence[google.cloud.recaptchaenterprise_v1.types.AnnotateAssessmentRequest.Reason]): Optional. Optional reasons for the annotation that will be assigned to the Event. + hashed_account_id (bytes): + Optional. Optional unique stable hashed user identifier to + apply to the assessment. This is an alternative to setting + the hashed_account_id in CreateAssessment, for example when + the account identifier is not yet known in the initial + request. It is recommended that the identifier is hashed + using hmac-sha256 with stable secret. """ class Annotation(proto.Enum): @@ -109,6 +125,7 @@ class Reason(proto.Enum): name = proto.Field(proto.STRING, number=1,) annotation = proto.Field(proto.ENUM, number=2, enum=Annotation,) reasons = proto.RepeatedField(proto.ENUM, number=3, enum=Reason,) + hashed_account_id = proto.Field(proto.BYTES, number=4,) class AnnotateAssessmentResponse(proto.Message): @@ -132,12 +149,18 @@ class Assessment(proto.Message): token_properties (google.cloud.recaptchaenterprise_v1.types.TokenProperties): Output only. Properties of the provided event token. + account_defender_assessment (google.cloud.recaptchaenterprise_v1.types.AccountDefenderAssessment): + Assessment returned by Account Defender when a + hashed_account_id is provided. """ name = proto.Field(proto.STRING, number=1,) event = proto.Field(proto.MESSAGE, number=2, message="Event",) risk_analysis = proto.Field(proto.MESSAGE, number=3, message="RiskAnalysis",) token_properties = proto.Field(proto.MESSAGE, number=4, message="TokenProperties",) + account_defender_assessment = proto.Field( + proto.MESSAGE, number=6, message="AccountDefenderAssessment", + ) class Event(proto.Message): @@ -165,6 +188,11 @@ class Event(proto.Message): provided at token generation time on client-side platforms already integrated with recaptcha enterprise. + hashed_account_id (bytes): + Optional. Optional unique stable hashed user + identifier for the request. The identifier + should ideally be hashed using sha256 with + stable secret. """ token = proto.Field(proto.STRING, number=1,) @@ -172,6 +200,7 @@ class Event(proto.Message): user_agent = proto.Field(proto.STRING, number=3,) user_ip_address = proto.Field(proto.STRING, number=4,) expected_action = proto.Field(proto.STRING, number=5,) + hashed_account_id = proto.Field(proto.BYTES, number=6,) class RiskAnalysis(proto.Message): @@ -241,6 +270,25 @@ class InvalidReason(proto.Enum): action = proto.Field(proto.STRING, number=5,) +class AccountDefenderAssessment(proto.Message): + r"""Account Defender risk assessment. + + Attributes: + labels (Sequence[google.cloud.recaptchaenterprise_v1.types.AccountDefenderAssessment.AccountDefenderLabel]): + Labels for this request. + """ + + class AccountDefenderLabel(proto.Enum): + r"""Labels returned by Account Defender for this request.""" + ACCOUNT_DEFENDER_LABEL_UNSPECIFIED = 0 + PROFILE_MATCH = 1 + SUSPICIOUS_LOGIN_ACTIVITY = 2 + SUSPICIOUS_ACCOUNT_CREATION = 3 + RELATED_ACCOUNTS_NUMBER_HIGH = 4 + + labels = proto.RepeatedField(proto.ENUM, number=1, enum=AccountDefenderLabel,) + + class CreateKeyRequest(proto.Message): r"""The create key request message. @@ -498,9 +546,9 @@ class WebKeySettings(proto.Message): port, query or fragment. Examples: 'example.com' or 'subdomain.example.com' allow_amp_traffic (bool): - Required. Whether this key can be used on AMP - (Accelerated Mobile Pages) websites. This can - only be set for the SCORE integration type. + If set to true, the key can be used on AMP + (Accelerated Mobile Pages) websites. This is + supported only for the SCORE integration type. integration_type (google.cloud.recaptchaenterprise_v1.types.WebKeySettings.IntegrationType): Required. Describes how this key is integrated with the website. @@ -541,8 +589,7 @@ class AndroidKeySettings(proto.Message): Attributes: allow_all_package_names (bool): - If set to true, it means allowed_package_names will not be - enforced. + If set to true, allowed_package_names are not enforced. allowed_package_names (Sequence[str]): Android package names of apps allowed to use the key. Example: 'com.companyname.appname' @@ -557,8 +604,7 @@ class IOSKeySettings(proto.Message): Attributes: allow_all_bundle_ids (bool): - If set to true, it means allowed_bundle_ids will not be - enforced. + If set to true, allowed_bundle_ids are not enforced. allowed_bundle_ids (Sequence[str]): iOS bundle ids of apps allowed to use the key. Example: @@ -630,4 +676,196 @@ class ChallengeMetrics(proto.Message): passed_count = proto.Field(proto.INT64, number=4,) +class ListRelatedAccountGroupMembershipsRequest(proto.Message): + r"""The request message to list memberships in a related account + group. + + Attributes: + parent (str): + Required. The resource name for the related account group in + the format + ``projects/{project}/relatedaccountgroups/{relatedaccountgroup}``. + page_size (int): + Optional. The maximum number of accounts to + return. The service may return fewer than this + value. If unspecified, at most 50 accounts will + be returned. The maximum value is 1000; values + above 1000 will be coerced to 1000. + page_token (str): + Optional. A page token, received from a previous + ``ListRelatedAccountGroupMemberships`` call. + + When paginating, all other parameters provided to + ``ListRelatedAccountGroupMemberships`` must match the call + that provided the page token. + """ + + parent = proto.Field(proto.STRING, number=1,) + page_size = proto.Field(proto.INT32, number=2,) + page_token = proto.Field(proto.STRING, number=3,) + + +class ListRelatedAccountGroupMembershipsResponse(proto.Message): + r"""The response to a ``ListRelatedAccountGroupMemberships`` call. + + Attributes: + related_account_group_memberships (Sequence[google.cloud.recaptchaenterprise_v1.types.RelatedAccountGroupMembership]): + The memberships listed by the query. + next_page_token (str): + A token, which can be sent as ``page_token`` to retrieve the + next page. If this field is omitted, there are no subsequent + pages. + """ + + @property + def raw_page(self): + return self + + related_account_group_memberships = proto.RepeatedField( + proto.MESSAGE, number=1, message="RelatedAccountGroupMembership", + ) + next_page_token = proto.Field(proto.STRING, number=2,) + + +class ListRelatedAccountGroupsRequest(proto.Message): + r"""The request message to list related account groups. + + Attributes: + parent (str): + Required. The name of the project to list + related account groups from, in the format + "projects/{project}". + page_size (int): + Optional. The maximum number of groups to + return. The service may return fewer than this + value. If unspecified, at most 50 groups will be + returned. The maximum value is 1000; values + above 1000 will be coerced to 1000. + page_token (str): + Optional. A page token, received from a previous + ``ListRelatedAccountGroups`` call. Provide this to retrieve + the subsequent page. + + When paginating, all other parameters provided to + ``ListRelatedAccountGroups`` must match the call that + provided the page token. + """ + + parent = proto.Field(proto.STRING, number=1,) + page_size = proto.Field(proto.INT32, number=2,) + page_token = proto.Field(proto.STRING, number=3,) + + +class ListRelatedAccountGroupsResponse(proto.Message): + r"""The response to a ``ListRelatedAccountGroups`` call. + + Attributes: + related_account_groups (Sequence[google.cloud.recaptchaenterprise_v1.types.RelatedAccountGroup]): + The groups of related accounts listed by the + query. + next_page_token (str): + A token, which can be sent as ``page_token`` to retrieve the + next page. If this field is omitted, there are no subsequent + pages. + """ + + @property + def raw_page(self): + return self + + related_account_groups = proto.RepeatedField( + proto.MESSAGE, number=1, message="RelatedAccountGroup", + ) + next_page_token = proto.Field(proto.STRING, number=2,) + + +class SearchRelatedAccountGroupMembershipsRequest(proto.Message): + r"""The request message to search related account group + memberships. + + Attributes: + parent (str): + Required. The name of the project to search + related account group memberships from, in the + format "projects/{project}". + hashed_account_id (bytes): + Optional. The unique stable hashed user identifier we should + search connections to. The identifier should correspond to a + ``hashed_account_id`` provided in a previous + CreateAssessment or AnnotateAssessment call. + page_size (int): + Optional. The maximum number of groups to + return. The service may return fewer than this + value. If unspecified, at most 50 groups will be + returned. The maximum value is 1000; values + above 1000 will be coerced to 1000. + page_token (str): + Optional. A page token, received from a previous + ``SearchRelatedAccountGroupMemberships`` call. Provide this + to retrieve the subsequent page. + + When paginating, all other parameters provided to + ``SearchRelatedAccountGroupMemberships`` must match the call + that provided the page token. + """ + + parent = proto.Field(proto.STRING, number=1,) + hashed_account_id = proto.Field(proto.BYTES, number=2,) + page_size = proto.Field(proto.INT32, number=3,) + page_token = proto.Field(proto.STRING, number=4,) + + +class SearchRelatedAccountGroupMembershipsResponse(proto.Message): + r"""The response to a ``SearchRelatedAccountGroupMemberships`` call. + + Attributes: + related_account_group_memberships (Sequence[google.cloud.recaptchaenterprise_v1.types.RelatedAccountGroupMembership]): + The queried memberships. + next_page_token (str): + A token, which can be sent as ``page_token`` to retrieve the + next page. If this field is omitted, there are no subsequent + pages. + """ + + @property + def raw_page(self): + return self + + related_account_group_memberships = proto.RepeatedField( + proto.MESSAGE, number=1, message="RelatedAccountGroupMembership", + ) + next_page_token = proto.Field(proto.STRING, number=2,) + + +class RelatedAccountGroupMembership(proto.Message): + r"""A membership in a group of related accounts. + + Attributes: + name (str): + Required. The resource name for this membership in the + format + ``projects/{project}/relatedaccountgroups/{relatedaccountgroup}/memberships/{membership}``. + hashed_account_id (bytes): + The unique stable hashed user identifier of the member. The + identifier corresponds to a ``hashed_account_id`` provided + in a previous CreateAssessment or AnnotateAssessment call. + """ + + name = proto.Field(proto.STRING, number=1,) + hashed_account_id = proto.Field(proto.BYTES, number=2,) + + +class RelatedAccountGroup(proto.Message): + r"""A group of related accounts. + + Attributes: + name (str): + Required. The resource name for the related account group in + the format + ``projects/{project}/relatedaccountgroups/{related_account_group}``. + """ + + name = proto.Field(proto.STRING, number=1,) + + __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/scripts/fixup_recaptchaenterprise_v1_keywords.py b/scripts/fixup_recaptchaenterprise_v1_keywords.py index 9674209..de4844d 100644 --- a/scripts/fixup_recaptchaenterprise_v1_keywords.py +++ b/scripts/fixup_recaptchaenterprise_v1_keywords.py @@ -39,14 +39,17 @@ def partition( class recaptchaenterpriseCallTransformer(cst.CSTTransformer): CTRL_PARAMS: Tuple[str] = ('retry', 'timeout', 'metadata') METHOD_TO_PARAMS: Dict[str, Tuple[str]] = { - 'annotate_assessment': ('name', 'annotation', 'reasons', ), + 'annotate_assessment': ('name', 'annotation', 'reasons', 'hashed_account_id', ), 'create_assessment': ('parent', 'assessment', ), 'create_key': ('parent', 'key', ), 'delete_key': ('name', ), 'get_key': ('name', ), 'get_metrics': ('name', ), 'list_keys': ('parent', 'page_size', 'page_token', ), + 'list_related_account_group_memberships': ('parent', 'page_size', 'page_token', ), + 'list_related_account_groups': ('parent', 'page_size', 'page_token', ), 'migrate_key': ('name', ), + 'search_related_account_group_memberships': ('parent', 'hashed_account_id', 'page_size', 'page_token', ), 'update_key': ('key', 'update_mask', ), } diff --git a/tests/unit/gapic/recaptchaenterprise_v1/test_recaptcha_enterprise_service.py b/tests/unit/gapic/recaptchaenterprise_v1/test_recaptcha_enterprise_service.py index 09d22be..8760db6 100644 --- a/tests/unit/gapic/recaptchaenterprise_v1/test_recaptcha_enterprise_service.py +++ b/tests/unit/gapic/recaptchaenterprise_v1/test_recaptcha_enterprise_service.py @@ -2192,6 +2192,1300 @@ async def test_get_metrics_flattened_error_async(): ) +def test_list_related_account_groups( + transport: str = "grpc", + request_type=recaptchaenterprise.ListRelatedAccountGroupsRequest, +): + client = RecaptchaEnterpriseServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_related_account_groups), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = recaptchaenterprise.ListRelatedAccountGroupsResponse( + next_page_token="next_page_token_value", + ) + response = client.list_related_account_groups(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == recaptchaenterprise.ListRelatedAccountGroupsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListRelatedAccountGroupsPager) + assert response.next_page_token == "next_page_token_value" + + +def test_list_related_account_groups_from_dict(): + test_list_related_account_groups(request_type=dict) + + +def test_list_related_account_groups_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. + client = RecaptchaEnterpriseServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_related_account_groups), "__call__" + ) as call: + client.list_related_account_groups() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == recaptchaenterprise.ListRelatedAccountGroupsRequest() + + +@pytest.mark.asyncio +async def test_list_related_account_groups_async( + transport: str = "grpc_asyncio", + request_type=recaptchaenterprise.ListRelatedAccountGroupsRequest, +): + client = RecaptchaEnterpriseServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_related_account_groups), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + recaptchaenterprise.ListRelatedAccountGroupsResponse( + next_page_token="next_page_token_value", + ) + ) + response = await client.list_related_account_groups(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == recaptchaenterprise.ListRelatedAccountGroupsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListRelatedAccountGroupsAsyncPager) + assert response.next_page_token == "next_page_token_value" + + +@pytest.mark.asyncio +async def test_list_related_account_groups_async_from_dict(): + await test_list_related_account_groups_async(request_type=dict) + + +def test_list_related_account_groups_field_headers(): + client = RecaptchaEnterpriseServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = recaptchaenterprise.ListRelatedAccountGroupsRequest() + + request.parent = "parent/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_related_account_groups), "__call__" + ) as call: + call.return_value = recaptchaenterprise.ListRelatedAccountGroupsResponse() + client.list_related_account_groups(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ("x-goog-request-params", "parent=parent/value",) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_list_related_account_groups_field_headers_async(): + client = RecaptchaEnterpriseServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = recaptchaenterprise.ListRelatedAccountGroupsRequest() + + request.parent = "parent/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_related_account_groups), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + recaptchaenterprise.ListRelatedAccountGroupsResponse() + ) + await client.list_related_account_groups(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ("x-goog-request-params", "parent=parent/value",) in kw["metadata"] + + +def test_list_related_account_groups_flattened(): + client = RecaptchaEnterpriseServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_related_account_groups), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = recaptchaenterprise.ListRelatedAccountGroupsResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.list_related_account_groups(parent="parent_value",) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0].parent == "parent_value" + + +def test_list_related_account_groups_flattened_error(): + client = RecaptchaEnterpriseServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_related_account_groups( + recaptchaenterprise.ListRelatedAccountGroupsRequest(), + parent="parent_value", + ) + + +@pytest.mark.asyncio +async def test_list_related_account_groups_flattened_async(): + client = RecaptchaEnterpriseServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_related_account_groups), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = recaptchaenterprise.ListRelatedAccountGroupsResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + recaptchaenterprise.ListRelatedAccountGroupsResponse() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.list_related_account_groups(parent="parent_value",) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0].parent == "parent_value" + + +@pytest.mark.asyncio +async def test_list_related_account_groups_flattened_error_async(): + client = RecaptchaEnterpriseServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.list_related_account_groups( + recaptchaenterprise.ListRelatedAccountGroupsRequest(), + parent="parent_value", + ) + + +def test_list_related_account_groups_pager(): + client = RecaptchaEnterpriseServiceClient( + credentials=ga_credentials.AnonymousCredentials, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_related_account_groups), "__call__" + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + recaptchaenterprise.ListRelatedAccountGroupsResponse( + related_account_groups=[ + recaptchaenterprise.RelatedAccountGroup(), + recaptchaenterprise.RelatedAccountGroup(), + recaptchaenterprise.RelatedAccountGroup(), + ], + next_page_token="abc", + ), + recaptchaenterprise.ListRelatedAccountGroupsResponse( + related_account_groups=[], next_page_token="def", + ), + recaptchaenterprise.ListRelatedAccountGroupsResponse( + related_account_groups=[recaptchaenterprise.RelatedAccountGroup(),], + next_page_token="ghi", + ), + recaptchaenterprise.ListRelatedAccountGroupsResponse( + related_account_groups=[ + recaptchaenterprise.RelatedAccountGroup(), + recaptchaenterprise.RelatedAccountGroup(), + ], + ), + RuntimeError, + ) + + metadata = () + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", ""),)), + ) + pager = client.list_related_account_groups(request={}) + + assert pager._metadata == metadata + + results = [i for i in pager] + assert len(results) == 6 + assert all( + isinstance(i, recaptchaenterprise.RelatedAccountGroup) for i in results + ) + + +def test_list_related_account_groups_pages(): + client = RecaptchaEnterpriseServiceClient( + credentials=ga_credentials.AnonymousCredentials, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_related_account_groups), "__call__" + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + recaptchaenterprise.ListRelatedAccountGroupsResponse( + related_account_groups=[ + recaptchaenterprise.RelatedAccountGroup(), + recaptchaenterprise.RelatedAccountGroup(), + recaptchaenterprise.RelatedAccountGroup(), + ], + next_page_token="abc", + ), + recaptchaenterprise.ListRelatedAccountGroupsResponse( + related_account_groups=[], next_page_token="def", + ), + recaptchaenterprise.ListRelatedAccountGroupsResponse( + related_account_groups=[recaptchaenterprise.RelatedAccountGroup(),], + next_page_token="ghi", + ), + recaptchaenterprise.ListRelatedAccountGroupsResponse( + related_account_groups=[ + recaptchaenterprise.RelatedAccountGroup(), + recaptchaenterprise.RelatedAccountGroup(), + ], + ), + RuntimeError, + ) + pages = list(client.list_related_account_groups(request={}).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +@pytest.mark.asyncio +async def test_list_related_account_groups_async_pager(): + client = RecaptchaEnterpriseServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_related_account_groups), + "__call__", + new_callable=mock.AsyncMock, + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + recaptchaenterprise.ListRelatedAccountGroupsResponse( + related_account_groups=[ + recaptchaenterprise.RelatedAccountGroup(), + recaptchaenterprise.RelatedAccountGroup(), + recaptchaenterprise.RelatedAccountGroup(), + ], + next_page_token="abc", + ), + recaptchaenterprise.ListRelatedAccountGroupsResponse( + related_account_groups=[], next_page_token="def", + ), + recaptchaenterprise.ListRelatedAccountGroupsResponse( + related_account_groups=[recaptchaenterprise.RelatedAccountGroup(),], + next_page_token="ghi", + ), + recaptchaenterprise.ListRelatedAccountGroupsResponse( + related_account_groups=[ + recaptchaenterprise.RelatedAccountGroup(), + recaptchaenterprise.RelatedAccountGroup(), + ], + ), + RuntimeError, + ) + async_pager = await client.list_related_account_groups(request={},) + assert async_pager.next_page_token == "abc" + responses = [] + async for response in async_pager: + responses.append(response) + + assert len(responses) == 6 + assert all( + isinstance(i, recaptchaenterprise.RelatedAccountGroup) for i in responses + ) + + +@pytest.mark.asyncio +async def test_list_related_account_groups_async_pages(): + client = RecaptchaEnterpriseServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_related_account_groups), + "__call__", + new_callable=mock.AsyncMock, + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + recaptchaenterprise.ListRelatedAccountGroupsResponse( + related_account_groups=[ + recaptchaenterprise.RelatedAccountGroup(), + recaptchaenterprise.RelatedAccountGroup(), + recaptchaenterprise.RelatedAccountGroup(), + ], + next_page_token="abc", + ), + recaptchaenterprise.ListRelatedAccountGroupsResponse( + related_account_groups=[], next_page_token="def", + ), + recaptchaenterprise.ListRelatedAccountGroupsResponse( + related_account_groups=[recaptchaenterprise.RelatedAccountGroup(),], + next_page_token="ghi", + ), + recaptchaenterprise.ListRelatedAccountGroupsResponse( + related_account_groups=[ + recaptchaenterprise.RelatedAccountGroup(), + recaptchaenterprise.RelatedAccountGroup(), + ], + ), + RuntimeError, + ) + pages = [] + async for page_ in (await client.list_related_account_groups(request={})).pages: + pages.append(page_) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +def test_list_related_account_group_memberships( + transport: str = "grpc", + request_type=recaptchaenterprise.ListRelatedAccountGroupMembershipsRequest, +): + client = RecaptchaEnterpriseServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_related_account_group_memberships), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = recaptchaenterprise.ListRelatedAccountGroupMembershipsResponse( + next_page_token="next_page_token_value", + ) + response = client.list_related_account_group_memberships(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert ( + args[0] == recaptchaenterprise.ListRelatedAccountGroupMembershipsRequest() + ) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListRelatedAccountGroupMembershipsPager) + assert response.next_page_token == "next_page_token_value" + + +def test_list_related_account_group_memberships_from_dict(): + test_list_related_account_group_memberships(request_type=dict) + + +def test_list_related_account_group_memberships_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. + client = RecaptchaEnterpriseServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_related_account_group_memberships), "__call__" + ) as call: + client.list_related_account_group_memberships() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert ( + args[0] == recaptchaenterprise.ListRelatedAccountGroupMembershipsRequest() + ) + + +@pytest.mark.asyncio +async def test_list_related_account_group_memberships_async( + transport: str = "grpc_asyncio", + request_type=recaptchaenterprise.ListRelatedAccountGroupMembershipsRequest, +): + client = RecaptchaEnterpriseServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_related_account_group_memberships), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + recaptchaenterprise.ListRelatedAccountGroupMembershipsResponse( + next_page_token="next_page_token_value", + ) + ) + response = await client.list_related_account_group_memberships(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert ( + args[0] == recaptchaenterprise.ListRelatedAccountGroupMembershipsRequest() + ) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListRelatedAccountGroupMembershipsAsyncPager) + assert response.next_page_token == "next_page_token_value" + + +@pytest.mark.asyncio +async def test_list_related_account_group_memberships_async_from_dict(): + await test_list_related_account_group_memberships_async(request_type=dict) + + +def test_list_related_account_group_memberships_field_headers(): + client = RecaptchaEnterpriseServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = recaptchaenterprise.ListRelatedAccountGroupMembershipsRequest() + + request.parent = "parent/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_related_account_group_memberships), "__call__" + ) as call: + call.return_value = ( + recaptchaenterprise.ListRelatedAccountGroupMembershipsResponse() + ) + client.list_related_account_group_memberships(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ("x-goog-request-params", "parent=parent/value",) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_list_related_account_group_memberships_field_headers_async(): + client = RecaptchaEnterpriseServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = recaptchaenterprise.ListRelatedAccountGroupMembershipsRequest() + + request.parent = "parent/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_related_account_group_memberships), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + recaptchaenterprise.ListRelatedAccountGroupMembershipsResponse() + ) + await client.list_related_account_group_memberships(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ("x-goog-request-params", "parent=parent/value",) in kw["metadata"] + + +def test_list_related_account_group_memberships_flattened(): + client = RecaptchaEnterpriseServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_related_account_group_memberships), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = ( + recaptchaenterprise.ListRelatedAccountGroupMembershipsResponse() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.list_related_account_group_memberships(parent="parent_value",) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0].parent == "parent_value" + + +def test_list_related_account_group_memberships_flattened_error(): + client = RecaptchaEnterpriseServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_related_account_group_memberships( + recaptchaenterprise.ListRelatedAccountGroupMembershipsRequest(), + parent="parent_value", + ) + + +@pytest.mark.asyncio +async def test_list_related_account_group_memberships_flattened_async(): + client = RecaptchaEnterpriseServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_related_account_group_memberships), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = ( + recaptchaenterprise.ListRelatedAccountGroupMembershipsResponse() + ) + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + recaptchaenterprise.ListRelatedAccountGroupMembershipsResponse() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.list_related_account_group_memberships( + parent="parent_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0].parent == "parent_value" + + +@pytest.mark.asyncio +async def test_list_related_account_group_memberships_flattened_error_async(): + client = RecaptchaEnterpriseServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.list_related_account_group_memberships( + recaptchaenterprise.ListRelatedAccountGroupMembershipsRequest(), + parent="parent_value", + ) + + +def test_list_related_account_group_memberships_pager(): + client = RecaptchaEnterpriseServiceClient( + credentials=ga_credentials.AnonymousCredentials, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_related_account_group_memberships), "__call__" + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + recaptchaenterprise.ListRelatedAccountGroupMembershipsResponse( + related_account_group_memberships=[ + recaptchaenterprise.RelatedAccountGroupMembership(), + recaptchaenterprise.RelatedAccountGroupMembership(), + recaptchaenterprise.RelatedAccountGroupMembership(), + ], + next_page_token="abc", + ), + recaptchaenterprise.ListRelatedAccountGroupMembershipsResponse( + related_account_group_memberships=[], next_page_token="def", + ), + recaptchaenterprise.ListRelatedAccountGroupMembershipsResponse( + related_account_group_memberships=[ + recaptchaenterprise.RelatedAccountGroupMembership(), + ], + next_page_token="ghi", + ), + recaptchaenterprise.ListRelatedAccountGroupMembershipsResponse( + related_account_group_memberships=[ + recaptchaenterprise.RelatedAccountGroupMembership(), + recaptchaenterprise.RelatedAccountGroupMembership(), + ], + ), + RuntimeError, + ) + + metadata = () + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", ""),)), + ) + pager = client.list_related_account_group_memberships(request={}) + + assert pager._metadata == metadata + + results = [i for i in pager] + assert len(results) == 6 + assert all( + isinstance(i, recaptchaenterprise.RelatedAccountGroupMembership) + for i in results + ) + + +def test_list_related_account_group_memberships_pages(): + client = RecaptchaEnterpriseServiceClient( + credentials=ga_credentials.AnonymousCredentials, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_related_account_group_memberships), "__call__" + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + recaptchaenterprise.ListRelatedAccountGroupMembershipsResponse( + related_account_group_memberships=[ + recaptchaenterprise.RelatedAccountGroupMembership(), + recaptchaenterprise.RelatedAccountGroupMembership(), + recaptchaenterprise.RelatedAccountGroupMembership(), + ], + next_page_token="abc", + ), + recaptchaenterprise.ListRelatedAccountGroupMembershipsResponse( + related_account_group_memberships=[], next_page_token="def", + ), + recaptchaenterprise.ListRelatedAccountGroupMembershipsResponse( + related_account_group_memberships=[ + recaptchaenterprise.RelatedAccountGroupMembership(), + ], + next_page_token="ghi", + ), + recaptchaenterprise.ListRelatedAccountGroupMembershipsResponse( + related_account_group_memberships=[ + recaptchaenterprise.RelatedAccountGroupMembership(), + recaptchaenterprise.RelatedAccountGroupMembership(), + ], + ), + RuntimeError, + ) + pages = list(client.list_related_account_group_memberships(request={}).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +@pytest.mark.asyncio +async def test_list_related_account_group_memberships_async_pager(): + client = RecaptchaEnterpriseServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_related_account_group_memberships), + "__call__", + new_callable=mock.AsyncMock, + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + recaptchaenterprise.ListRelatedAccountGroupMembershipsResponse( + related_account_group_memberships=[ + recaptchaenterprise.RelatedAccountGroupMembership(), + recaptchaenterprise.RelatedAccountGroupMembership(), + recaptchaenterprise.RelatedAccountGroupMembership(), + ], + next_page_token="abc", + ), + recaptchaenterprise.ListRelatedAccountGroupMembershipsResponse( + related_account_group_memberships=[], next_page_token="def", + ), + recaptchaenterprise.ListRelatedAccountGroupMembershipsResponse( + related_account_group_memberships=[ + recaptchaenterprise.RelatedAccountGroupMembership(), + ], + next_page_token="ghi", + ), + recaptchaenterprise.ListRelatedAccountGroupMembershipsResponse( + related_account_group_memberships=[ + recaptchaenterprise.RelatedAccountGroupMembership(), + recaptchaenterprise.RelatedAccountGroupMembership(), + ], + ), + RuntimeError, + ) + async_pager = await client.list_related_account_group_memberships(request={},) + assert async_pager.next_page_token == "abc" + responses = [] + async for response in async_pager: + responses.append(response) + + assert len(responses) == 6 + assert all( + isinstance(i, recaptchaenterprise.RelatedAccountGroupMembership) + for i in responses + ) + + +@pytest.mark.asyncio +async def test_list_related_account_group_memberships_async_pages(): + client = RecaptchaEnterpriseServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_related_account_group_memberships), + "__call__", + new_callable=mock.AsyncMock, + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + recaptchaenterprise.ListRelatedAccountGroupMembershipsResponse( + related_account_group_memberships=[ + recaptchaenterprise.RelatedAccountGroupMembership(), + recaptchaenterprise.RelatedAccountGroupMembership(), + recaptchaenterprise.RelatedAccountGroupMembership(), + ], + next_page_token="abc", + ), + recaptchaenterprise.ListRelatedAccountGroupMembershipsResponse( + related_account_group_memberships=[], next_page_token="def", + ), + recaptchaenterprise.ListRelatedAccountGroupMembershipsResponse( + related_account_group_memberships=[ + recaptchaenterprise.RelatedAccountGroupMembership(), + ], + next_page_token="ghi", + ), + recaptchaenterprise.ListRelatedAccountGroupMembershipsResponse( + related_account_group_memberships=[ + recaptchaenterprise.RelatedAccountGroupMembership(), + recaptchaenterprise.RelatedAccountGroupMembership(), + ], + ), + RuntimeError, + ) + pages = [] + async for page_ in ( + await client.list_related_account_group_memberships(request={}) + ).pages: + pages.append(page_) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +def test_search_related_account_group_memberships( + transport: str = "grpc", + request_type=recaptchaenterprise.SearchRelatedAccountGroupMembershipsRequest, +): + client = RecaptchaEnterpriseServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.search_related_account_group_memberships), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = recaptchaenterprise.SearchRelatedAccountGroupMembershipsResponse( + next_page_token="next_page_token_value", + ) + response = client.search_related_account_group_memberships(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert ( + args[0] == recaptchaenterprise.SearchRelatedAccountGroupMembershipsRequest() + ) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.SearchRelatedAccountGroupMembershipsPager) + assert response.next_page_token == "next_page_token_value" + + +def test_search_related_account_group_memberships_from_dict(): + test_search_related_account_group_memberships(request_type=dict) + + +def test_search_related_account_group_memberships_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. + client = RecaptchaEnterpriseServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.search_related_account_group_memberships), "__call__" + ) as call: + client.search_related_account_group_memberships() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert ( + args[0] == recaptchaenterprise.SearchRelatedAccountGroupMembershipsRequest() + ) + + +@pytest.mark.asyncio +async def test_search_related_account_group_memberships_async( + transport: str = "grpc_asyncio", + request_type=recaptchaenterprise.SearchRelatedAccountGroupMembershipsRequest, +): + client = RecaptchaEnterpriseServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.search_related_account_group_memberships), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + recaptchaenterprise.SearchRelatedAccountGroupMembershipsResponse( + next_page_token="next_page_token_value", + ) + ) + response = await client.search_related_account_group_memberships(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert ( + args[0] == recaptchaenterprise.SearchRelatedAccountGroupMembershipsRequest() + ) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.SearchRelatedAccountGroupMembershipsAsyncPager) + assert response.next_page_token == "next_page_token_value" + + +@pytest.mark.asyncio +async def test_search_related_account_group_memberships_async_from_dict(): + await test_search_related_account_group_memberships_async(request_type=dict) + + +def test_search_related_account_group_memberships_field_headers(): + client = RecaptchaEnterpriseServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = recaptchaenterprise.SearchRelatedAccountGroupMembershipsRequest() + + request.parent = "parent/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.search_related_account_group_memberships), "__call__" + ) as call: + call.return_value = ( + recaptchaenterprise.SearchRelatedAccountGroupMembershipsResponse() + ) + client.search_related_account_group_memberships(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ("x-goog-request-params", "parent=parent/value",) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_search_related_account_group_memberships_field_headers_async(): + client = RecaptchaEnterpriseServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = recaptchaenterprise.SearchRelatedAccountGroupMembershipsRequest() + + request.parent = "parent/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.search_related_account_group_memberships), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + recaptchaenterprise.SearchRelatedAccountGroupMembershipsResponse() + ) + await client.search_related_account_group_memberships(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ("x-goog-request-params", "parent=parent/value",) in kw["metadata"] + + +def test_search_related_account_group_memberships_flattened(): + client = RecaptchaEnterpriseServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.search_related_account_group_memberships), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = ( + recaptchaenterprise.SearchRelatedAccountGroupMembershipsResponse() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.search_related_account_group_memberships( + parent="parent_value", hashed_account_id=b"hashed_account_id_blob", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0].parent == "parent_value" + assert args[0].hashed_account_id == b"hashed_account_id_blob" + + +def test_search_related_account_group_memberships_flattened_error(): + client = RecaptchaEnterpriseServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.search_related_account_group_memberships( + recaptchaenterprise.SearchRelatedAccountGroupMembershipsRequest(), + parent="parent_value", + hashed_account_id=b"hashed_account_id_blob", + ) + + +@pytest.mark.asyncio +async def test_search_related_account_group_memberships_flattened_async(): + client = RecaptchaEnterpriseServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.search_related_account_group_memberships), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = ( + recaptchaenterprise.SearchRelatedAccountGroupMembershipsResponse() + ) + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + recaptchaenterprise.SearchRelatedAccountGroupMembershipsResponse() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.search_related_account_group_memberships( + parent="parent_value", hashed_account_id=b"hashed_account_id_blob", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0].parent == "parent_value" + assert args[0].hashed_account_id == b"hashed_account_id_blob" + + +@pytest.mark.asyncio +async def test_search_related_account_group_memberships_flattened_error_async(): + client = RecaptchaEnterpriseServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.search_related_account_group_memberships( + recaptchaenterprise.SearchRelatedAccountGroupMembershipsRequest(), + parent="parent_value", + hashed_account_id=b"hashed_account_id_blob", + ) + + +def test_search_related_account_group_memberships_pager(): + client = RecaptchaEnterpriseServiceClient( + credentials=ga_credentials.AnonymousCredentials, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.search_related_account_group_memberships), "__call__" + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + recaptchaenterprise.SearchRelatedAccountGroupMembershipsResponse( + related_account_group_memberships=[ + recaptchaenterprise.RelatedAccountGroupMembership(), + recaptchaenterprise.RelatedAccountGroupMembership(), + recaptchaenterprise.RelatedAccountGroupMembership(), + ], + next_page_token="abc", + ), + recaptchaenterprise.SearchRelatedAccountGroupMembershipsResponse( + related_account_group_memberships=[], next_page_token="def", + ), + recaptchaenterprise.SearchRelatedAccountGroupMembershipsResponse( + related_account_group_memberships=[ + recaptchaenterprise.RelatedAccountGroupMembership(), + ], + next_page_token="ghi", + ), + recaptchaenterprise.SearchRelatedAccountGroupMembershipsResponse( + related_account_group_memberships=[ + recaptchaenterprise.RelatedAccountGroupMembership(), + recaptchaenterprise.RelatedAccountGroupMembership(), + ], + ), + RuntimeError, + ) + + metadata = () + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", ""),)), + ) + pager = client.search_related_account_group_memberships(request={}) + + assert pager._metadata == metadata + + results = [i for i in pager] + assert len(results) == 6 + assert all( + isinstance(i, recaptchaenterprise.RelatedAccountGroupMembership) + for i in results + ) + + +def test_search_related_account_group_memberships_pages(): + client = RecaptchaEnterpriseServiceClient( + credentials=ga_credentials.AnonymousCredentials, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.search_related_account_group_memberships), "__call__" + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + recaptchaenterprise.SearchRelatedAccountGroupMembershipsResponse( + related_account_group_memberships=[ + recaptchaenterprise.RelatedAccountGroupMembership(), + recaptchaenterprise.RelatedAccountGroupMembership(), + recaptchaenterprise.RelatedAccountGroupMembership(), + ], + next_page_token="abc", + ), + recaptchaenterprise.SearchRelatedAccountGroupMembershipsResponse( + related_account_group_memberships=[], next_page_token="def", + ), + recaptchaenterprise.SearchRelatedAccountGroupMembershipsResponse( + related_account_group_memberships=[ + recaptchaenterprise.RelatedAccountGroupMembership(), + ], + next_page_token="ghi", + ), + recaptchaenterprise.SearchRelatedAccountGroupMembershipsResponse( + related_account_group_memberships=[ + recaptchaenterprise.RelatedAccountGroupMembership(), + recaptchaenterprise.RelatedAccountGroupMembership(), + ], + ), + RuntimeError, + ) + pages = list(client.search_related_account_group_memberships(request={}).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +@pytest.mark.asyncio +async def test_search_related_account_group_memberships_async_pager(): + client = RecaptchaEnterpriseServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.search_related_account_group_memberships), + "__call__", + new_callable=mock.AsyncMock, + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + recaptchaenterprise.SearchRelatedAccountGroupMembershipsResponse( + related_account_group_memberships=[ + recaptchaenterprise.RelatedAccountGroupMembership(), + recaptchaenterprise.RelatedAccountGroupMembership(), + recaptchaenterprise.RelatedAccountGroupMembership(), + ], + next_page_token="abc", + ), + recaptchaenterprise.SearchRelatedAccountGroupMembershipsResponse( + related_account_group_memberships=[], next_page_token="def", + ), + recaptchaenterprise.SearchRelatedAccountGroupMembershipsResponse( + related_account_group_memberships=[ + recaptchaenterprise.RelatedAccountGroupMembership(), + ], + next_page_token="ghi", + ), + recaptchaenterprise.SearchRelatedAccountGroupMembershipsResponse( + related_account_group_memberships=[ + recaptchaenterprise.RelatedAccountGroupMembership(), + recaptchaenterprise.RelatedAccountGroupMembership(), + ], + ), + RuntimeError, + ) + async_pager = await client.search_related_account_group_memberships(request={},) + assert async_pager.next_page_token == "abc" + responses = [] + async for response in async_pager: + responses.append(response) + + assert len(responses) == 6 + assert all( + isinstance(i, recaptchaenterprise.RelatedAccountGroupMembership) + for i in responses + ) + + +@pytest.mark.asyncio +async def test_search_related_account_group_memberships_async_pages(): + client = RecaptchaEnterpriseServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.search_related_account_group_memberships), + "__call__", + new_callable=mock.AsyncMock, + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + recaptchaenterprise.SearchRelatedAccountGroupMembershipsResponse( + related_account_group_memberships=[ + recaptchaenterprise.RelatedAccountGroupMembership(), + recaptchaenterprise.RelatedAccountGroupMembership(), + recaptchaenterprise.RelatedAccountGroupMembership(), + ], + next_page_token="abc", + ), + recaptchaenterprise.SearchRelatedAccountGroupMembershipsResponse( + related_account_group_memberships=[], next_page_token="def", + ), + recaptchaenterprise.SearchRelatedAccountGroupMembershipsResponse( + related_account_group_memberships=[ + recaptchaenterprise.RelatedAccountGroupMembership(), + ], + next_page_token="ghi", + ), + recaptchaenterprise.SearchRelatedAccountGroupMembershipsResponse( + related_account_group_memberships=[ + recaptchaenterprise.RelatedAccountGroupMembership(), + recaptchaenterprise.RelatedAccountGroupMembership(), + ], + ), + RuntimeError, + ) + pages = [] + async for page_ in ( + await client.search_related_account_group_memberships(request={}) + ).pages: + pages.append(page_) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + def test_credentials_transport_error(): # It is an error to provide credentials and a transport instance. transport = transports.RecaptchaEnterpriseServiceGrpcTransport( @@ -2302,6 +3596,9 @@ def test_recaptcha_enterprise_service_base_transport(): "delete_key", "migrate_key", "get_metrics", + "list_related_account_groups", + "list_related_account_group_memberships", + "search_related_account_group_memberships", ) for method in methods: with pytest.raises(NotImplementedError): @@ -2664,8 +3961,62 @@ def test_parse_metrics_path(): assert expected == actual +def test_related_account_group_path(): + project = "squid" + relatedaccountgroup = "clam" + expected = "projects/{project}/relatedaccountgroups/{relatedaccountgroup}".format( + project=project, relatedaccountgroup=relatedaccountgroup, + ) + actual = RecaptchaEnterpriseServiceClient.related_account_group_path( + project, relatedaccountgroup + ) + assert expected == actual + + +def test_parse_related_account_group_path(): + expected = { + "project": "whelk", + "relatedaccountgroup": "octopus", + } + path = RecaptchaEnterpriseServiceClient.related_account_group_path(**expected) + + # Check that the path construction is reversible. + actual = RecaptchaEnterpriseServiceClient.parse_related_account_group_path(path) + assert expected == actual + + +def test_related_account_group_membership_path(): + project = "oyster" + relatedaccountgroup = "nudibranch" + membership = "cuttlefish" + expected = "projects/{project}/relatedaccountgroups/{relatedaccountgroup}/memberships/{membership}".format( + project=project, relatedaccountgroup=relatedaccountgroup, membership=membership, + ) + actual = RecaptchaEnterpriseServiceClient.related_account_group_membership_path( + project, relatedaccountgroup, membership + ) + assert expected == actual + + +def test_parse_related_account_group_membership_path(): + expected = { + "project": "mussel", + "relatedaccountgroup": "winkle", + "membership": "nautilus", + } + path = RecaptchaEnterpriseServiceClient.related_account_group_membership_path( + **expected + ) + + # Check that the path construction is reversible. + actual = RecaptchaEnterpriseServiceClient.parse_related_account_group_membership_path( + path + ) + assert expected == actual + + def test_common_billing_account_path(): - billing_account = "squid" + billing_account = "scallop" expected = "billingAccounts/{billing_account}".format( billing_account=billing_account, ) @@ -2677,7 +4028,7 @@ def test_common_billing_account_path(): def test_parse_common_billing_account_path(): expected = { - "billing_account": "clam", + "billing_account": "abalone", } path = RecaptchaEnterpriseServiceClient.common_billing_account_path(**expected) @@ -2687,7 +4038,7 @@ def test_parse_common_billing_account_path(): def test_common_folder_path(): - folder = "whelk" + folder = "squid" expected = "folders/{folder}".format(folder=folder,) actual = RecaptchaEnterpriseServiceClient.common_folder_path(folder) assert expected == actual @@ -2695,7 +4046,7 @@ def test_common_folder_path(): def test_parse_common_folder_path(): expected = { - "folder": "octopus", + "folder": "clam", } path = RecaptchaEnterpriseServiceClient.common_folder_path(**expected) @@ -2705,7 +4056,7 @@ def test_parse_common_folder_path(): def test_common_organization_path(): - organization = "oyster" + organization = "whelk" expected = "organizations/{organization}".format(organization=organization,) actual = RecaptchaEnterpriseServiceClient.common_organization_path(organization) assert expected == actual @@ -2713,7 +4064,7 @@ def test_common_organization_path(): def test_parse_common_organization_path(): expected = { - "organization": "nudibranch", + "organization": "octopus", } path = RecaptchaEnterpriseServiceClient.common_organization_path(**expected) @@ -2723,7 +4074,7 @@ def test_parse_common_organization_path(): def test_common_project_path(): - project = "cuttlefish" + project = "oyster" expected = "projects/{project}".format(project=project,) actual = RecaptchaEnterpriseServiceClient.common_project_path(project) assert expected == actual @@ -2731,7 +4082,7 @@ def test_common_project_path(): def test_parse_common_project_path(): expected = { - "project": "mussel", + "project": "nudibranch", } path = RecaptchaEnterpriseServiceClient.common_project_path(**expected) @@ -2741,8 +4092,8 @@ def test_parse_common_project_path(): def test_common_location_path(): - project = "winkle" - location = "nautilus" + project = "cuttlefish" + location = "mussel" expected = "projects/{project}/locations/{location}".format( project=project, location=location, ) @@ -2752,8 +4103,8 @@ def test_common_location_path(): def test_parse_common_location_path(): expected = { - "project": "scallop", - "location": "abalone", + "project": "winkle", + "location": "nautilus", } path = RecaptchaEnterpriseServiceClient.common_location_path(**expected)