diff --git a/google/analytics/data_v1alpha/__init__.py b/google/analytics/data_v1alpha/__init__.py index 8674d50..0567673 100644 --- a/google/analytics/data_v1alpha/__init__.py +++ b/google/analytics/data_v1alpha/__init__.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2020 Google LLC +# Copyright 2022 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -17,90 +17,138 @@ from .services.alpha_analytics_data import AlphaAnalyticsDataClient from .services.alpha_analytics_data import AlphaAnalyticsDataAsyncClient -from .types.analytics_data_api import BatchRunPivotReportsRequest -from .types.analytics_data_api import BatchRunPivotReportsResponse -from .types.analytics_data_api import BatchRunReportsRequest -from .types.analytics_data_api import BatchRunReportsResponse -from .types.analytics_data_api import GetMetadataRequest -from .types.analytics_data_api import Metadata -from .types.analytics_data_api import RunPivotReportRequest -from .types.analytics_data_api import RunPivotReportResponse -from .types.analytics_data_api import RunRealtimeReportRequest -from .types.analytics_data_api import RunRealtimeReportResponse -from .types.analytics_data_api import RunReportRequest -from .types.analytics_data_api import RunReportResponse -from .types.data import Cohort -from .types.data import CohortReportSettings -from .types.data import CohortSpec -from .types.data import CohortsRange +from .types.analytics_data_api import RunFunnelReportRequest +from .types.analytics_data_api import RunFunnelReportResponse +from .types.data import BetweenFilter from .types.data import DateRange from .types.data import Dimension from .types.data import DimensionExpression from .types.data import DimensionHeader -from .types.data import DimensionMetadata from .types.data import DimensionValue -from .types.data import Entity +from .types.data import EventSegment +from .types.data import EventSegmentConditionGroup +from .types.data import EventSegmentCriteria +from .types.data import EventSegmentExclusion from .types.data import Filter from .types.data import FilterExpression from .types.data import FilterExpressionList -from .types.data import Metric +from .types.data import Funnel +from .types.data import FunnelBreakdown +from .types.data import FunnelEventFilter +from .types.data import FunnelFilter +from .types.data import FunnelFilterExpression +from .types.data import FunnelFilterExpressionList +from .types.data import FunnelNextAction +from .types.data import FunnelParameterFilter +from .types.data import FunnelParameterFilterExpression +from .types.data import FunnelParameterFilterExpressionList +from .types.data import FunnelResponseMetadata +from .types.data import FunnelStep +from .types.data import FunnelSubReport +from .types.data import InListFilter from .types.data import MetricHeader -from .types.data import MetricMetadata from .types.data import MetricValue +from .types.data import NumericFilter from .types.data import NumericValue -from .types.data import OrderBy -from .types.data import Pivot -from .types.data import PivotDimensionHeader -from .types.data import PivotHeader from .types.data import PropertyQuota from .types.data import QuotaStatus -from .types.data import ResponseMetaData from .types.data import Row -from .types.data import MetricAggregation +from .types.data import SamplingMetadata +from .types.data import Segment +from .types.data import SegmentEventFilter +from .types.data import SegmentFilter +from .types.data import SegmentFilterExpression +from .types.data import SegmentFilterExpressionList +from .types.data import SegmentFilterScoping +from .types.data import SegmentParameterFilter +from .types.data import SegmentParameterFilterExpression +from .types.data import SegmentParameterFilterExpressionList +from .types.data import SegmentParameterFilterScoping +from .types.data import SessionSegment +from .types.data import SessionSegmentConditionGroup +from .types.data import SessionSegmentCriteria +from .types.data import SessionSegmentExclusion +from .types.data import StringFilter +from .types.data import UserSegment +from .types.data import UserSegmentConditionGroup +from .types.data import UserSegmentCriteria +from .types.data import UserSegmentExclusion +from .types.data import UserSegmentSequenceGroup +from .types.data import UserSequenceStep +from .types.data import EventCriteriaScoping +from .types.data import EventExclusionDuration from .types.data import MetricType +from .types.data import SessionCriteriaScoping +from .types.data import SessionExclusionDuration +from .types.data import UserCriteriaScoping +from .types.data import UserExclusionDuration __all__ = ( "AlphaAnalyticsDataAsyncClient", "AlphaAnalyticsDataClient", - "BatchRunPivotReportsRequest", - "BatchRunPivotReportsResponse", - "BatchRunReportsRequest", - "BatchRunReportsResponse", - "Cohort", - "CohortReportSettings", - "CohortSpec", - "CohortsRange", + "BetweenFilter", "DateRange", "Dimension", "DimensionExpression", "DimensionHeader", - "DimensionMetadata", "DimensionValue", - "Entity", + "EventCriteriaScoping", + "EventExclusionDuration", + "EventSegment", + "EventSegmentConditionGroup", + "EventSegmentCriteria", + "EventSegmentExclusion", "Filter", "FilterExpression", "FilterExpressionList", - "GetMetadataRequest", - "Metadata", - "Metric", - "MetricAggregation", + "Funnel", + "FunnelBreakdown", + "FunnelEventFilter", + "FunnelFilter", + "FunnelFilterExpression", + "FunnelFilterExpressionList", + "FunnelNextAction", + "FunnelParameterFilter", + "FunnelParameterFilterExpression", + "FunnelParameterFilterExpressionList", + "FunnelResponseMetadata", + "FunnelStep", + "FunnelSubReport", + "InListFilter", "MetricHeader", - "MetricMetadata", "MetricType", "MetricValue", + "NumericFilter", "NumericValue", - "OrderBy", - "Pivot", - "PivotDimensionHeader", - "PivotHeader", "PropertyQuota", "QuotaStatus", - "ResponseMetaData", "Row", - "RunPivotReportRequest", - "RunPivotReportResponse", - "RunRealtimeReportRequest", - "RunRealtimeReportResponse", - "RunReportRequest", - "RunReportResponse", + "RunFunnelReportRequest", + "RunFunnelReportResponse", + "SamplingMetadata", + "Segment", + "SegmentEventFilter", + "SegmentFilter", + "SegmentFilterExpression", + "SegmentFilterExpressionList", + "SegmentFilterScoping", + "SegmentParameterFilter", + "SegmentParameterFilterExpression", + "SegmentParameterFilterExpressionList", + "SegmentParameterFilterScoping", + "SessionCriteriaScoping", + "SessionExclusionDuration", + "SessionSegment", + "SessionSegmentConditionGroup", + "SessionSegmentCriteria", + "SessionSegmentExclusion", + "StringFilter", + "UserCriteriaScoping", + "UserExclusionDuration", + "UserSegment", + "UserSegmentConditionGroup", + "UserSegmentCriteria", + "UserSegmentExclusion", + "UserSegmentSequenceGroup", + "UserSequenceStep", ) diff --git a/google/analytics/data_v1alpha/gapic_metadata.json b/google/analytics/data_v1alpha/gapic_metadata.json index 013b073..10c59bf 100644 --- a/google/analytics/data_v1alpha/gapic_metadata.json +++ b/google/analytics/data_v1alpha/gapic_metadata.json @@ -10,34 +10,9 @@ "grpc": { "libraryClient": "AlphaAnalyticsDataClient", "rpcs": { - "BatchRunPivotReports": { + "RunFunnelReport": { "methods": [ - "batch_run_pivot_reports" - ] - }, - "BatchRunReports": { - "methods": [ - "batch_run_reports" - ] - }, - "GetMetadata": { - "methods": [ - "get_metadata" - ] - }, - "RunPivotReport": { - "methods": [ - "run_pivot_report" - ] - }, - "RunRealtimeReport": { - "methods": [ - "run_realtime_report" - ] - }, - "RunReport": { - "methods": [ - "run_report" + "run_funnel_report" ] } } @@ -45,34 +20,9 @@ "grpc-async": { "libraryClient": "AlphaAnalyticsDataAsyncClient", "rpcs": { - "BatchRunPivotReports": { - "methods": [ - "batch_run_pivot_reports" - ] - }, - "BatchRunReports": { - "methods": [ - "batch_run_reports" - ] - }, - "GetMetadata": { - "methods": [ - "get_metadata" - ] - }, - "RunPivotReport": { - "methods": [ - "run_pivot_report" - ] - }, - "RunRealtimeReport": { - "methods": [ - "run_realtime_report" - ] - }, - "RunReport": { + "RunFunnelReport": { "methods": [ - "run_report" + "run_funnel_report" ] } } diff --git a/google/analytics/data_v1alpha/services/__init__.py b/google/analytics/data_v1alpha/services/__init__.py index 4de6597..e8e1c38 100644 --- a/google/analytics/data_v1alpha/services/__init__.py +++ b/google/analytics/data_v1alpha/services/__init__.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2020 Google LLC +# Copyright 2022 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/google/analytics/data_v1alpha/services/alpha_analytics_data/__init__.py b/google/analytics/data_v1alpha/services/alpha_analytics_data/__init__.py index 57d375c..053b669 100644 --- a/google/analytics/data_v1alpha/services/alpha_analytics_data/__init__.py +++ b/google/analytics/data_v1alpha/services/alpha_analytics_data/__init__.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2020 Google LLC +# Copyright 2022 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/google/analytics/data_v1alpha/services/alpha_analytics_data/async_client.py b/google/analytics/data_v1alpha/services/alpha_analytics_data/async_client.py index 5a21726..44b3049 100644 --- a/google/analytics/data_v1alpha/services/alpha_analytics_data/async_client.py +++ b/google/analytics/data_v1alpha/services/alpha_analytics_data/async_client.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2020 Google LLC +# Copyright 2022 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -16,16 +16,21 @@ from collections import OrderedDict import functools import re -from typing import Dict, Sequence, Tuple, Type, Union +from typing import Dict, Mapping, Optional, Sequence, Tuple, Type, Union import pkg_resources -import google.api_core.client_options as ClientOptions # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore +from google.api_core.client_options import ClientOptions +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore from google.oauth2 import service_account # type: ignore +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + from google.analytics.data_v1alpha.types import analytics_data_api from google.analytics.data_v1alpha.types import data from .transports.base import AlphaAnalyticsDataTransport, DEFAULT_CLIENT_INFO @@ -41,8 +46,6 @@ class AlphaAnalyticsDataAsyncClient: DEFAULT_ENDPOINT = AlphaAnalyticsDataClient.DEFAULT_ENDPOINT DEFAULT_MTLS_ENDPOINT = AlphaAnalyticsDataClient.DEFAULT_MTLS_ENDPOINT - metadata_path = staticmethod(AlphaAnalyticsDataClient.metadata_path) - parse_metadata_path = staticmethod(AlphaAnalyticsDataClient.parse_metadata_path) common_billing_account_path = staticmethod( AlphaAnalyticsDataClient.common_billing_account_path ) @@ -101,6 +104,42 @@ def from_service_account_file(cls, filename: str, *args, **kwargs): from_service_account_json = from_service_account_file + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variabel is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return AlphaAnalyticsDataClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + @property def transport(self) -> AlphaAnalyticsDataTransport: """Returns the transport used by the client instance. @@ -162,178 +201,48 @@ def __init__( client_info=client_info, ) - async def run_report( + async def run_funnel_report( self, - request: analytics_data_api.RunReportRequest = None, + request: Union[analytics_data_api.RunFunnelReportRequest, dict] = None, *, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), - ) -> analytics_data_api.RunReportResponse: - r"""Returns a customized report of your Google Analytics - event data. Reports contain statistics derived from data - collected by the Google Analytics tracking code. The - data returned from the API is as a table with columns - for the requested dimensions and metrics. Metrics are - individual measurements of user activity on your - property, such as active users or event count. - Dimensions break down metrics across some common - criteria, such as country or event name. - - Args: - request (:class:`google.analytics.data_v1alpha.types.RunReportRequest`): - The request object. The request to generate a report. - 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.analytics.data_v1alpha.types.RunReportResponse: - The response report table - corresponding to a request. - - """ - # Create or coerce a protobuf request object. - request = analytics_data_api.RunReportRequest(request) + ) -> analytics_data_api.RunFunnelReportResponse: + r"""Returns a customized funnel report of your Google Analytics + event data. The data returned from the API is as a table with + columns for the requested dimensions and metrics. - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = gapic_v1.method_async.wrap_method( - self._client._transport.run_report, - default_timeout=60.0, - client_info=DEFAULT_CLIENT_INFO, - ) + Funnel exploration lets you visualize the steps your users take + to complete a task and quickly see how well they are succeeding + or failing at each step. For example, how do prospects become + shoppers and then become buyers? How do one time buyers become + repeat buyers? With this information, you can improve + inefficient or abandoned customer journeys. To learn more, see + `GA4 Funnel + Explorations `__. - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + .. code-block:: python - # Done; return the response. - return response + from google.analytics import data_v1alpha - async def run_pivot_report( - self, - request: analytics_data_api.RunPivotReportRequest = None, - *, - retry: retries.Retry = gapic_v1.method.DEFAULT, - timeout: float = None, - metadata: Sequence[Tuple[str, str]] = (), - ) -> analytics_data_api.RunPivotReportResponse: - r"""Returns a customized pivot report of your Google - Analytics event data. Pivot reports are more advanced - and expressive formats than regular reports. In a pivot - report, dimensions are only visible if they are included - in a pivot. Multiple pivots can be specified to further - dissect your data. - - Args: - request (:class:`google.analytics.data_v1alpha.types.RunPivotReportRequest`): - The request object. The request to generate a pivot - report. - 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.analytics.data_v1alpha.types.RunPivotReportResponse: - The response pivot report table - corresponding to a pivot request. - - """ - # Create or coerce a protobuf request object. - request = analytics_data_api.RunPivotReportRequest(request) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = gapic_v1.method_async.wrap_method( - self._client._transport.run_pivot_report, - default_timeout=60.0, - client_info=DEFAULT_CLIENT_INFO, - ) - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def batch_run_reports( - self, - request: analytics_data_api.BatchRunReportsRequest = None, - *, - retry: retries.Retry = gapic_v1.method.DEFAULT, - timeout: float = None, - metadata: Sequence[Tuple[str, str]] = (), - ) -> analytics_data_api.BatchRunReportsResponse: - r"""Returns multiple reports in a batch. All reports must - be for the same Entity. - - Args: - request (:class:`google.analytics.data_v1alpha.types.BatchRunReportsRequest`): - The request object. The batch request containing - multiple report requests. - 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.analytics.data_v1alpha.types.BatchRunReportsResponse: - The batch response containing - multiple reports. - - """ - # Create or coerce a protobuf request object. - request = analytics_data_api.BatchRunReportsRequest(request) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = gapic_v1.method_async.wrap_method( - self._client._transport.batch_run_reports, - default_timeout=60.0, - client_info=DEFAULT_CLIENT_INFO, - ) + async def sample_run_funnel_report(): + # Create a client + client = data_v1alpha.AlphaAnalyticsDataAsyncClient() - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + # Initialize request argument(s) + request = data_v1alpha.RunFunnelReportRequest( + ) - # Done; return the response. - return response + # Make the request + response = await client.run_funnel_report(request=request) - async def batch_run_pivot_reports( - self, - request: analytics_data_api.BatchRunPivotReportsRequest = None, - *, - retry: retries.Retry = gapic_v1.method.DEFAULT, - timeout: float = None, - metadata: Sequence[Tuple[str, str]] = (), - ) -> analytics_data_api.BatchRunPivotReportsResponse: - r"""Returns multiple pivot reports in a batch. All - reports must be for the same Entity. + # Handle the response + print(response) Args: - request (:class:`google.analytics.data_v1alpha.types.BatchRunPivotReportsRequest`): - The request object. The batch request containing - multiple pivot report requests. + request (Union[google.analytics.data_v1alpha.types.RunFunnelReportRequest, dict]): + The request object. The request for a funnel report. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -341,116 +250,28 @@ async def batch_run_pivot_reports( sent along with the request as metadata. Returns: - google.analytics.data_v1alpha.types.BatchRunPivotReportsResponse: - The batch response containing - multiple pivot reports. + google.analytics.data_v1alpha.types.RunFunnelReportResponse: + The funnel report response contains + two sub reports. The two sub reports are + different combinations of dimensions and + metrics. """ # Create or coerce a protobuf request object. - request = analytics_data_api.BatchRunPivotReportsRequest(request) + request = analytics_data_api.RunFunnelReportRequest(request) # Wrap the RPC method; this adds retry and timeout information, # and friendly error handling. rpc = gapic_v1.method_async.wrap_method( - self._client._transport.batch_run_pivot_reports, + self._client._transport.run_funnel_report, default_timeout=60.0, client_info=DEFAULT_CLIENT_INFO, ) - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def get_metadata( - self, - request: analytics_data_api.GetMetadataRequest = None, - *, - name: str = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, - timeout: float = None, - metadata: Sequence[Tuple[str, str]] = (), - ) -> analytics_data_api.Metadata: - r"""Returns metadata for dimensions and metrics available in - reporting methods. Used to explore the dimensions and metrics. - In this method, a Google Analytics GA4 Property Identifier is - specified in the request, and the metadata response includes - Custom dimensions and metrics as well as Universal metadata. - - For example if a custom metric with parameter name - ``levels_unlocked`` is registered to a property, the Metadata - response will contain ``customEvent:levels_unlocked``. Universal - metadata are dimensions and metrics applicable to any property - such as ``country`` and ``totalUsers``. - - Args: - request (:class:`google.analytics.data_v1alpha.types.GetMetadataRequest`): - The request object. Request for a property's dimension - and metric metadata. - name (:class:`str`): - Required. The resource name of the metadata to retrieve. - This name field is specified in the URL path and not URL - parameters. Property is a numeric Google Analytics GA4 - Property identifier. To learn more, see `where to find - your Property - ID `__. - - Example: properties/1234/metadata - - Set the Property ID to 0 for dimensions and metrics - common to all properties. In this special mode, this - method will not return custom dimensions and metrics. - - This corresponds to the ``name`` 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.analytics.data_v1alpha.types.Metadata: - The dimensions and metrics currently - accepted in reporting methods. - - """ - # 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([name]) - 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 = analytics_data_api.GetMetadataRequest(request) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if name is not None: - request.name = name - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = gapic_v1.method_async.wrap_method( - self._client._transport.get_metadata, - 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((("name", request.name),)), + gapic_v1.routing_header.to_grpc_metadata((("property", request.property),)), ) # Send the request. @@ -464,62 +285,11 @@ async def get_metadata( # Done; return the response. return response - async def run_realtime_report( - self, - request: analytics_data_api.RunRealtimeReportRequest = None, - *, - retry: retries.Retry = gapic_v1.method.DEFAULT, - timeout: float = None, - metadata: Sequence[Tuple[str, str]] = (), - ) -> analytics_data_api.RunRealtimeReportResponse: - r"""The Google Analytics Realtime API returns a - customized report of realtime event data for your - property. These reports show events and usage from the - last 30 minutes. - - Args: - request (:class:`google.analytics.data_v1alpha.types.RunRealtimeReportRequest`): - The request object. The request to generate a realtime - report. - 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.analytics.data_v1alpha.types.RunRealtimeReportResponse: - The response realtime report table - corresponding to a request. - - """ - # Create or coerce a protobuf request object. - request = analytics_data_api.RunRealtimeReportRequest(request) + async def __aenter__(self): + return self - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = gapic_v1.method_async.wrap_method( - self._client._transport.run_realtime_report, - 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((("property", request.property),)), - ) - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() try: diff --git a/google/analytics/data_v1alpha/services/alpha_analytics_data/client.py b/google/analytics/data_v1alpha/services/alpha_analytics_data/client.py index 797be3e..c168d64 100644 --- a/google/analytics/data_v1alpha/services/alpha_analytics_data/client.py +++ b/google/analytics/data_v1alpha/services/alpha_analytics_data/client.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2020 Google LLC +# Copyright 2022 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -14,22 +14,26 @@ # limitations under the License. # from collections import OrderedDict -from distutils import util import os import re -from typing import Dict, Optional, Sequence, Tuple, Type, Union +from typing import Dict, Mapping, Optional, Sequence, Tuple, Type, Union import pkg_resources -from google.api_core import client_options as client_options_lib # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport import mtls # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.exceptions import MutualTLSChannelError # type: ignore from google.oauth2 import service_account # type: ignore +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + from google.analytics.data_v1alpha.types import analytics_data_api from google.analytics.data_v1alpha.types import data from .transports.base import AlphaAnalyticsDataTransport, DEFAULT_CLIENT_INFO @@ -158,21 +162,6 @@ def transport(self) -> AlphaAnalyticsDataTransport: """ return self._transport - @staticmethod - def metadata_path( - property: str, - ) -> str: - """Returns a fully-qualified metadata string.""" - return "properties/{property}/metadata".format( - property=property, - ) - - @staticmethod - def parse_metadata_path(path: str) -> Dict[str, str]: - """Parses a metadata path into its component segments.""" - m = re.match(r"^properties/(?P.+?)/metadata$", path) - return m.groupdict() if m else {} - @staticmethod def common_billing_account_path( billing_account: str, @@ -250,6 +239,73 @@ def parse_common_location_path(path: str) -> Dict[str, str]: m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)$", path) return m.groupdict() if m else {} + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variabel is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_client_cert not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert == "true": + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + def __init__( self, *, @@ -300,50 +356,22 @@ def __init__( if client_options is None: client_options = client_options_lib.ClientOptions() - # Create SSL credentials for mutual TLS if needed. - use_client_cert = bool( - util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false")) + api_endpoint, client_cert_source_func = self.get_mtls_endpoint_and_cert_source( + client_options ) - client_cert_source_func = None - is_mtls = False - if use_client_cert: - if client_options.client_cert_source: - is_mtls = True - client_cert_source_func = client_options.client_cert_source - else: - is_mtls = mtls.has_default_client_cert_source() - if is_mtls: - client_cert_source_func = mtls.default_client_cert_source() - else: - client_cert_source_func = None - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - else: - use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_mtls_env == "never": - api_endpoint = self.DEFAULT_ENDPOINT - elif use_mtls_env == "always": - api_endpoint = self.DEFAULT_MTLS_ENDPOINT - elif use_mtls_env == "auto": - if is_mtls: - api_endpoint = self.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = self.DEFAULT_ENDPOINT - else: - raise MutualTLSChannelError( - "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " - "values: never, auto, always" - ) + api_key_value = getattr(client_options, "api_key", None) + if api_key_value and credentials: + raise ValueError( + "client_options.api_key and credentials are mutually exclusive" + ) # Save or instantiate the transport. # Ordinarily, we provide the transport, but allowing a custom transport # instance provides an extensibility point for unusual situations. if isinstance(transport, AlphaAnalyticsDataTransport): # transport is a AlphaAnalyticsDataTransport instance. - if credentials or client_options.credentials_file: + if credentials or client_options.credentials_file or api_key_value: raise ValueError( "When providing a transport instance, " "provide its credentials directly." @@ -355,6 +383,15 @@ def __init__( ) self._transport = transport else: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + Transport = type(self).get_transport_class(transport) self._transport = Transport( credentials=credentials, @@ -364,264 +401,51 @@ def __init__( client_cert_source_for_mtls=client_cert_source_func, quota_project_id=client_options.quota_project_id, client_info=client_info, - always_use_jwt_access=( - Transport == type(self).get_transport_class("grpc") - or Transport == type(self).get_transport_class("grpc_asyncio") - ), + always_use_jwt_access=True, ) - def run_report( - self, - request: Union[analytics_data_api.RunReportRequest, dict] = None, - *, - retry: retries.Retry = gapic_v1.method.DEFAULT, - timeout: float = None, - metadata: Sequence[Tuple[str, str]] = (), - ) -> analytics_data_api.RunReportResponse: - r"""Returns a customized report of your Google Analytics - event data. Reports contain statistics derived from data - collected by the Google Analytics tracking code. The - data returned from the API is as a table with columns - for the requested dimensions and metrics. Metrics are - individual measurements of user activity on your - property, such as active users or event count. - Dimensions break down metrics across some common - criteria, such as country or event name. - - Args: - request (Union[google.analytics.data_v1alpha.types.RunReportRequest, dict]): - The request object. The request to generate a report. - 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.analytics.data_v1alpha.types.RunReportResponse: - The response report table - corresponding to a request. - - """ - # Create or coerce a protobuf request object. - # Minor optimization to avoid making a copy if the user passes - # in a analytics_data_api.RunReportRequest. - # There's no risk of modifying the input as we've already verified - # there are no flattened fields. - if not isinstance(request, analytics_data_api.RunReportRequest): - request = analytics_data_api.RunReportRequest(request) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.run_report] - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def run_pivot_report( + def run_funnel_report( self, - request: Union[analytics_data_api.RunPivotReportRequest, dict] = None, + request: Union[analytics_data_api.RunFunnelReportRequest, dict] = None, *, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), - ) -> analytics_data_api.RunPivotReportResponse: - r"""Returns a customized pivot report of your Google - Analytics event data. Pivot reports are more advanced - and expressive formats than regular reports. In a pivot - report, dimensions are only visible if they are included - in a pivot. Multiple pivots can be specified to further - dissect your data. - - Args: - request (Union[google.analytics.data_v1alpha.types.RunPivotReportRequest, dict]): - The request object. The request to generate a pivot - report. - 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.analytics.data_v1alpha.types.RunPivotReportResponse: - The response pivot report table - corresponding to a pivot request. - - """ - # Create or coerce a protobuf request object. - # Minor optimization to avoid making a copy if the user passes - # in a analytics_data_api.RunPivotReportRequest. - # There's no risk of modifying the input as we've already verified - # there are no flattened fields. - if not isinstance(request, analytics_data_api.RunPivotReportRequest): - request = analytics_data_api.RunPivotReportRequest(request) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.run_pivot_report] - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def batch_run_reports( - self, - request: Union[analytics_data_api.BatchRunReportsRequest, dict] = None, - *, - retry: retries.Retry = gapic_v1.method.DEFAULT, - timeout: float = None, - metadata: Sequence[Tuple[str, str]] = (), - ) -> analytics_data_api.BatchRunReportsResponse: - r"""Returns multiple reports in a batch. All reports must - be for the same Entity. - - Args: - request (Union[google.analytics.data_v1alpha.types.BatchRunReportsRequest, dict]): - The request object. The batch request containing - multiple report requests. - 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.analytics.data_v1alpha.types.BatchRunReportsResponse: - The batch response containing - multiple reports. - - """ - # Create or coerce a protobuf request object. - # Minor optimization to avoid making a copy if the user passes - # in a analytics_data_api.BatchRunReportsRequest. - # There's no risk of modifying the input as we've already verified - # there are no flattened fields. - if not isinstance(request, analytics_data_api.BatchRunReportsRequest): - request = analytics_data_api.BatchRunReportsRequest(request) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.batch_run_reports] - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def batch_run_pivot_reports( - self, - request: Union[analytics_data_api.BatchRunPivotReportsRequest, dict] = None, - *, - retry: retries.Retry = gapic_v1.method.DEFAULT, - timeout: float = None, - metadata: Sequence[Tuple[str, str]] = (), - ) -> analytics_data_api.BatchRunPivotReportsResponse: - r"""Returns multiple pivot reports in a batch. All - reports must be for the same Entity. - - Args: - request (Union[google.analytics.data_v1alpha.types.BatchRunPivotReportsRequest, dict]): - The request object. The batch request containing - multiple pivot report requests. - 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.analytics.data_v1alpha.types.BatchRunPivotReportsResponse: - The batch response containing - multiple pivot reports. - - """ - # Create or coerce a protobuf request object. - # Minor optimization to avoid making a copy if the user passes - # in a analytics_data_api.BatchRunPivotReportsRequest. - # There's no risk of modifying the input as we've already verified - # there are no flattened fields. - if not isinstance(request, analytics_data_api.BatchRunPivotReportsRequest): - request = analytics_data_api.BatchRunPivotReportsRequest(request) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.batch_run_pivot_reports] - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + ) -> analytics_data_api.RunFunnelReportResponse: + r"""Returns a customized funnel report of your Google Analytics + event data. The data returned from the API is as a table with + columns for the requested dimensions and metrics. + + Funnel exploration lets you visualize the steps your users take + to complete a task and quickly see how well they are succeeding + or failing at each step. For example, how do prospects become + shoppers and then become buyers? How do one time buyers become + repeat buyers? With this information, you can improve + inefficient or abandoned customer journeys. To learn more, see + `GA4 Funnel + Explorations `__. + + .. code-block:: python + + from google.analytics import data_v1alpha + + def sample_run_funnel_report(): + # Create a client + client = data_v1alpha.AlphaAnalyticsDataClient() + + # Initialize request argument(s) + request = data_v1alpha.RunFunnelReportRequest( + ) - # Done; return the response. - return response + # Make the request + response = client.run_funnel_report(request=request) - def get_metadata( - self, - request: Union[analytics_data_api.GetMetadataRequest, dict] = None, - *, - name: str = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, - timeout: float = None, - metadata: Sequence[Tuple[str, str]] = (), - ) -> analytics_data_api.Metadata: - r"""Returns metadata for dimensions and metrics available in - reporting methods. Used to explore the dimensions and metrics. - In this method, a Google Analytics GA4 Property Identifier is - specified in the request, and the metadata response includes - Custom dimensions and metrics as well as Universal metadata. - - For example if a custom metric with parameter name - ``levels_unlocked`` is registered to a property, the Metadata - response will contain ``customEvent:levels_unlocked``. Universal - metadata are dimensions and metrics applicable to any property - such as ``country`` and ``totalUsers``. + # Handle the response + print(response) Args: - request (Union[google.analytics.data_v1alpha.types.GetMetadataRequest, dict]): - The request object. Request for a property's dimension - and metric metadata. - name (str): - Required. The resource name of the metadata to retrieve. - This name field is specified in the URL path and not URL - parameters. Property is a numeric Google Analytics GA4 - Property identifier. To learn more, see `where to find - your Property - ID `__. - - Example: properties/1234/metadata - - Set the Property ID to 0 for dimensions and metrics - common to all properties. In this special mode, this - method will not return custom dimensions and metrics. - - This corresponds to the ``name`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. + request (Union[google.analytics.data_v1alpha.types.RunFunnelReportRequest, dict]): + The request object. The request for a funnel report. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -629,40 +453,29 @@ def get_metadata( sent along with the request as metadata. Returns: - google.analytics.data_v1alpha.types.Metadata: - The dimensions and metrics currently - accepted in reporting methods. + google.analytics.data_v1alpha.types.RunFunnelReportResponse: + The funnel report response contains + two sub reports. The two sub reports are + different combinations of dimensions and + metrics. """ # 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([name]) - 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 analytics_data_api.GetMetadataRequest. + # in a analytics_data_api.RunFunnelReportRequest. # There's no risk of modifying the input as we've already verified # there are no flattened fields. - if not isinstance(request, analytics_data_api.GetMetadataRequest): - request = analytics_data_api.GetMetadataRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if name is not None: - request.name = name + if not isinstance(request, analytics_data_api.RunFunnelReportRequest): + request = analytics_data_api.RunFunnelReportRequest(request) # Wrap the RPC method; this adds retry and timeout information, # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.get_metadata] + rpc = self._transport._wrapped_methods[self._transport.run_funnel_report] # Certain fields should be provided within the metadata header; # add these here. metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + gapic_v1.routing_header.to_grpc_metadata((("property", request.property),)), ) # Send the request. @@ -676,63 +489,18 @@ def get_metadata( # Done; return the response. return response - def run_realtime_report( - self, - request: Union[analytics_data_api.RunRealtimeReportRequest, dict] = None, - *, - retry: retries.Retry = gapic_v1.method.DEFAULT, - timeout: float = None, - metadata: Sequence[Tuple[str, str]] = (), - ) -> analytics_data_api.RunRealtimeReportResponse: - r"""The Google Analytics Realtime API returns a - customized report of realtime event data for your - property. These reports show events and usage from the - last 30 minutes. - - Args: - request (Union[google.analytics.data_v1alpha.types.RunRealtimeReportRequest, dict]): - The request object. The request to generate a realtime - report. - 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. + def __enter__(self): + return self - Returns: - google.analytics.data_v1alpha.types.RunRealtimeReportResponse: - The response realtime report table - corresponding to a request. + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! """ - # Create or coerce a protobuf request object. - # Minor optimization to avoid making a copy if the user passes - # in a analytics_data_api.RunRealtimeReportRequest. - # There's no risk of modifying the input as we've already verified - # there are no flattened fields. - if not isinstance(request, analytics_data_api.RunRealtimeReportRequest): - request = analytics_data_api.RunRealtimeReportRequest(request) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.run_realtime_report] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata((("property", request.property),)), - ) - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response + self.transport.close() try: diff --git a/google/analytics/data_v1alpha/services/alpha_analytics_data/transports/__init__.py b/google/analytics/data_v1alpha/services/alpha_analytics_data/transports/__init__.py index 6220a7a..b7bb07f 100644 --- a/google/analytics/data_v1alpha/services/alpha_analytics_data/transports/__init__.py +++ b/google/analytics/data_v1alpha/services/alpha_analytics_data/transports/__init__.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2020 Google LLC +# Copyright 2022 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/google/analytics/data_v1alpha/services/alpha_analytics_data/transports/base.py b/google/analytics/data_v1alpha/services/alpha_analytics_data/transports/base.py index 8998561..26eb85c 100644 --- a/google/analytics/data_v1alpha/services/alpha_analytics_data/transports/base.py +++ b/google/analytics/data_v1alpha/services/alpha_analytics_data/transports/base.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2020 Google LLC +# Copyright 2022 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,14 +15,13 @@ # import abc from typing import Awaitable, Callable, Dict, Optional, Sequence, Union -import packaging.version import pkg_resources import google.auth # type: ignore -import google.api_core # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore from google.oauth2 import service_account # type: ignore @@ -37,15 +36,6 @@ except pkg_resources.DistributionNotFound: DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() -try: - # google.auth.__version__ was added in 1.26.0 - _GOOGLE_AUTH_VERSION = google.auth.__version__ -except AttributeError: - try: # try pkg_resources if it is available - _GOOGLE_AUTH_VERSION = pkg_resources.get_distribution("google-auth").version - except pkg_resources.DistributionNotFound: # pragma: NO COVER - _GOOGLE_AUTH_VERSION = None - class AlphaAnalyticsDataTransport(abc.ABC): """Abstract transport class for AlphaAnalyticsData.""" @@ -93,12 +83,13 @@ def __init__( always_use_jwt_access (Optional[bool]): Whether self signed JWT should be used for service account credentials. """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. if ":" not in host: host += ":443" self._host = host - scopes_kwargs = self._get_scopes_kwargs(self._host, scopes) + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} # Save the scopes. self._scopes = scopes @@ -114,7 +105,6 @@ def __init__( credentials, _ = google.auth.load_credentials_from_file( credentials_file, **scopes_kwargs, quota_project_id=quota_project_id ) - elif credentials is None: credentials, _ = google.auth.default( **scopes_kwargs, quota_project_id=quota_project_id @@ -131,131 +121,39 @@ def __init__( # Save the credentials. self._credentials = credentials - # TODO(busunkim): This method is in the base transport - # to avoid duplicating code across the transport classes. These functions - # should be deleted once the minimum required versions of google-auth is increased. - - # TODO: Remove this function once google-auth >= 1.25.0 is required - @classmethod - def _get_scopes_kwargs( - cls, host: str, scopes: Optional[Sequence[str]] - ) -> Dict[str, Optional[Sequence[str]]]: - """Returns scopes kwargs to pass to google-auth methods depending on the google-auth version""" - - scopes_kwargs = {} - - if _GOOGLE_AUTH_VERSION and ( - packaging.version.parse(_GOOGLE_AUTH_VERSION) - >= packaging.version.parse("1.25.0") - ): - scopes_kwargs = {"scopes": scopes, "default_scopes": cls.AUTH_SCOPES} - else: - scopes_kwargs = {"scopes": scopes or cls.AUTH_SCOPES} - - return scopes_kwargs - def _prep_wrapped_messages(self, client_info): # Precompute the wrapped methods. self._wrapped_methods = { - self.run_report: gapic_v1.method.wrap_method( - self.run_report, - default_timeout=60.0, - client_info=client_info, - ), - self.run_pivot_report: gapic_v1.method.wrap_method( - self.run_pivot_report, - default_timeout=60.0, - client_info=client_info, - ), - self.batch_run_reports: gapic_v1.method.wrap_method( - self.batch_run_reports, + self.run_funnel_report: gapic_v1.method.wrap_method( + self.run_funnel_report, default_timeout=60.0, client_info=client_info, ), - self.batch_run_pivot_reports: gapic_v1.method.wrap_method( - self.batch_run_pivot_reports, - default_timeout=60.0, - client_info=client_info, - ), - self.get_metadata: gapic_v1.method.wrap_method( - self.get_metadata, - default_timeout=None, - client_info=client_info, - ), - self.run_realtime_report: gapic_v1.method.wrap_method( - self.run_realtime_report, - default_timeout=None, - client_info=client_info, - ), } - @property - def run_report( - self, - ) -> Callable[ - [analytics_data_api.RunReportRequest], - Union[ - analytics_data_api.RunReportResponse, - Awaitable[analytics_data_api.RunReportResponse], - ], - ]: - raise NotImplementedError() - - @property - def run_pivot_report( - self, - ) -> Callable[ - [analytics_data_api.RunPivotReportRequest], - Union[ - analytics_data_api.RunPivotReportResponse, - Awaitable[analytics_data_api.RunPivotReportResponse], - ], - ]: - raise NotImplementedError() + def close(self): + """Closes resources associated with the transport. - @property - def batch_run_reports( - self, - ) -> Callable[ - [analytics_data_api.BatchRunReportsRequest], - Union[ - analytics_data_api.BatchRunReportsResponse, - Awaitable[analytics_data_api.BatchRunReportsResponse], - ], - ]: + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ raise NotImplementedError() @property - def batch_run_pivot_reports( + def run_funnel_report( self, ) -> Callable[ - [analytics_data_api.BatchRunPivotReportsRequest], + [analytics_data_api.RunFunnelReportRequest], Union[ - analytics_data_api.BatchRunPivotReportsResponse, - Awaitable[analytics_data_api.BatchRunPivotReportsResponse], + analytics_data_api.RunFunnelReportResponse, + Awaitable[analytics_data_api.RunFunnelReportResponse], ], ]: raise NotImplementedError() @property - def get_metadata( - self, - ) -> Callable[ - [analytics_data_api.GetMetadataRequest], - Union[analytics_data_api.Metadata, Awaitable[analytics_data_api.Metadata]], - ]: - raise NotImplementedError() - - @property - def run_realtime_report( - self, - ) -> Callable[ - [analytics_data_api.RunRealtimeReportRequest], - Union[ - analytics_data_api.RunRealtimeReportResponse, - Awaitable[analytics_data_api.RunRealtimeReportResponse], - ], - ]: + def kind(self) -> str: raise NotImplementedError() diff --git a/google/analytics/data_v1alpha/services/alpha_analytics_data/transports/grpc.py b/google/analytics/data_v1alpha/services/alpha_analytics_data/transports/grpc.py index b44db39..2a901f4 100644 --- a/google/analytics/data_v1alpha/services/alpha_analytics_data/transports/grpc.py +++ b/google/analytics/data_v1alpha/services/alpha_analytics_data/transports/grpc.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2020 Google LLC +# Copyright 2022 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -16,8 +16,8 @@ import warnings from typing import Callable, Dict, Optional, Sequence, Tuple, Union -from google.api_core import grpc_helpers # type: ignore -from google.api_core import gapic_v1 # type: ignore +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 import google.auth # type: ignore from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore @@ -158,8 +158,11 @@ def __init__( if not self._grpc_channel: self._grpc_channel = type(self).create_channel( self._host, + # use the credentials which are saved credentials=self._credentials, - credentials_file=credentials_file, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, scopes=self._scopes, ssl_credentials=self._ssl_channel_credentials, quota_project_id=quota_project_id, @@ -225,120 +228,30 @@ def grpc_channel(self) -> grpc.Channel: return self._grpc_channel @property - def run_report( + def run_funnel_report( self, ) -> Callable[ - [analytics_data_api.RunReportRequest], analytics_data_api.RunReportResponse + [analytics_data_api.RunFunnelReportRequest], + analytics_data_api.RunFunnelReportResponse, ]: - r"""Return a callable for the run report method over gRPC. - - Returns a customized report of your Google Analytics - event data. Reports contain statistics derived from data - collected by the Google Analytics tracking code. The - data returned from the API is as a table with columns - for the requested dimensions and metrics. Metrics are - individual measurements of user activity on your - property, such as active users or event count. - Dimensions break down metrics across some common - criteria, such as country or event name. + r"""Return a callable for the run funnel report method over gRPC. - Returns: - Callable[[~.RunReportRequest], - ~.RunReportResponse]: - 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 "run_report" not in self._stubs: - self._stubs["run_report"] = self.grpc_channel.unary_unary( - "/google.analytics.data.v1alpha.AlphaAnalyticsData/RunReport", - request_serializer=analytics_data_api.RunReportRequest.serialize, - response_deserializer=analytics_data_api.RunReportResponse.deserialize, - ) - return self._stubs["run_report"] - - @property - def run_pivot_report( - self, - ) -> Callable[ - [analytics_data_api.RunPivotReportRequest], - analytics_data_api.RunPivotReportResponse, - ]: - r"""Return a callable for the run pivot report method over gRPC. - - Returns a customized pivot report of your Google - Analytics event data. Pivot reports are more advanced - and expressive formats than regular reports. In a pivot - report, dimensions are only visible if they are included - in a pivot. Multiple pivots can be specified to further - dissect your data. - - Returns: - Callable[[~.RunPivotReportRequest], - ~.RunPivotReportResponse]: - 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 "run_pivot_report" not in self._stubs: - self._stubs["run_pivot_report"] = self.grpc_channel.unary_unary( - "/google.analytics.data.v1alpha.AlphaAnalyticsData/RunPivotReport", - request_serializer=analytics_data_api.RunPivotReportRequest.serialize, - response_deserializer=analytics_data_api.RunPivotReportResponse.deserialize, - ) - return self._stubs["run_pivot_report"] - - @property - def batch_run_reports( - self, - ) -> Callable[ - [analytics_data_api.BatchRunReportsRequest], - analytics_data_api.BatchRunReportsResponse, - ]: - r"""Return a callable for the batch run reports method over gRPC. - - Returns multiple reports in a batch. All reports must - be for the same Entity. - - Returns: - Callable[[~.BatchRunReportsRequest], - ~.BatchRunReportsResponse]: - 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 "batch_run_reports" not in self._stubs: - self._stubs["batch_run_reports"] = self.grpc_channel.unary_unary( - "/google.analytics.data.v1alpha.AlphaAnalyticsData/BatchRunReports", - request_serializer=analytics_data_api.BatchRunReportsRequest.serialize, - response_deserializer=analytics_data_api.BatchRunReportsResponse.deserialize, - ) - return self._stubs["batch_run_reports"] - - @property - def batch_run_pivot_reports( - self, - ) -> Callable[ - [analytics_data_api.BatchRunPivotReportsRequest], - analytics_data_api.BatchRunPivotReportsResponse, - ]: - r"""Return a callable for the batch run pivot reports method over gRPC. + Returns a customized funnel report of your Google Analytics + event data. The data returned from the API is as a table with + columns for the requested dimensions and metrics. - Returns multiple pivot reports in a batch. All - reports must be for the same Entity. + Funnel exploration lets you visualize the steps your users take + to complete a task and quickly see how well they are succeeding + or failing at each step. For example, how do prospects become + shoppers and then become buyers? How do one time buyers become + repeat buyers? With this information, you can improve + inefficient or abandoned customer journeys. To learn more, see + `GA4 Funnel + Explorations `__. Returns: - Callable[[~.BatchRunPivotReportsRequest], - ~.BatchRunPivotReportsResponse]: + Callable[[~.RunFunnelReportRequest], + ~.RunFunnelReportResponse]: A function that, when called, will call the underlying RPC on the server. """ @@ -346,81 +259,20 @@ def batch_run_pivot_reports( # the request. # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. - if "batch_run_pivot_reports" not in self._stubs: - self._stubs["batch_run_pivot_reports"] = self.grpc_channel.unary_unary( - "/google.analytics.data.v1alpha.AlphaAnalyticsData/BatchRunPivotReports", - request_serializer=analytics_data_api.BatchRunPivotReportsRequest.serialize, - response_deserializer=analytics_data_api.BatchRunPivotReportsResponse.deserialize, + if "run_funnel_report" not in self._stubs: + self._stubs["run_funnel_report"] = self.grpc_channel.unary_unary( + "/google.analytics.data.v1alpha.AlphaAnalyticsData/RunFunnelReport", + request_serializer=analytics_data_api.RunFunnelReportRequest.serialize, + response_deserializer=analytics_data_api.RunFunnelReportResponse.deserialize, ) - return self._stubs["batch_run_pivot_reports"] + return self._stubs["run_funnel_report"] - @property - def get_metadata( - self, - ) -> Callable[[analytics_data_api.GetMetadataRequest], analytics_data_api.Metadata]: - r"""Return a callable for the get metadata method over gRPC. - - Returns metadata for dimensions and metrics available in - reporting methods. Used to explore the dimensions and metrics. - In this method, a Google Analytics GA4 Property Identifier is - specified in the request, and the metadata response includes - Custom dimensions and metrics as well as Universal metadata. - - For example if a custom metric with parameter name - ``levels_unlocked`` is registered to a property, the Metadata - response will contain ``customEvent:levels_unlocked``. Universal - metadata are dimensions and metrics applicable to any property - such as ``country`` and ``totalUsers``. - - Returns: - Callable[[~.GetMetadataRequest], - ~.Metadata]: - 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 "get_metadata" not in self._stubs: - self._stubs["get_metadata"] = self.grpc_channel.unary_unary( - "/google.analytics.data.v1alpha.AlphaAnalyticsData/GetMetadata", - request_serializer=analytics_data_api.GetMetadataRequest.serialize, - response_deserializer=analytics_data_api.Metadata.deserialize, - ) - return self._stubs["get_metadata"] + def close(self): + self.grpc_channel.close() @property - def run_realtime_report( - self, - ) -> Callable[ - [analytics_data_api.RunRealtimeReportRequest], - analytics_data_api.RunRealtimeReportResponse, - ]: - r"""Return a callable for the run realtime report method over gRPC. - - The Google Analytics Realtime API returns a - customized report of realtime event data for your - property. These reports show events and usage from the - last 30 minutes. - - Returns: - Callable[[~.RunRealtimeReportRequest], - ~.RunRealtimeReportResponse]: - 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 "run_realtime_report" not in self._stubs: - self._stubs["run_realtime_report"] = self.grpc_channel.unary_unary( - "/google.analytics.data.v1alpha.AlphaAnalyticsData/RunRealtimeReport", - request_serializer=analytics_data_api.RunRealtimeReportRequest.serialize, - response_deserializer=analytics_data_api.RunRealtimeReportResponse.deserialize, - ) - return self._stubs["run_realtime_report"] + def kind(self) -> str: + return "grpc" __all__ = ("AlphaAnalyticsDataGrpcTransport",) diff --git a/google/analytics/data_v1alpha/services/alpha_analytics_data/transports/grpc_asyncio.py b/google/analytics/data_v1alpha/services/alpha_analytics_data/transports/grpc_asyncio.py index 56912ac..88cac0a 100644 --- a/google/analytics/data_v1alpha/services/alpha_analytics_data/transports/grpc_asyncio.py +++ b/google/analytics/data_v1alpha/services/alpha_analytics_data/transports/grpc_asyncio.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2020 Google LLC +# Copyright 2022 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -16,11 +16,10 @@ import warnings from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union -from google.api_core import gapic_v1 # type: ignore -from google.api_core import grpc_helpers_async # type: ignore +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore -import packaging.version import grpc # type: ignore from grpc.experimental import aio # type: ignore @@ -204,8 +203,11 @@ def __init__( if not self._grpc_channel: self._grpc_channel = type(self).create_channel( self._host, + # use the credentials which are saved credentials=self._credentials, - credentials_file=credentials_file, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, scopes=self._scopes, ssl_credentials=self._ssl_channel_credentials, quota_project_id=quota_project_id, @@ -229,91 +231,30 @@ def grpc_channel(self) -> aio.Channel: return self._grpc_channel @property - def run_report( + def run_funnel_report( self, ) -> Callable[ - [analytics_data_api.RunReportRequest], - Awaitable[analytics_data_api.RunReportResponse], + [analytics_data_api.RunFunnelReportRequest], + Awaitable[analytics_data_api.RunFunnelReportResponse], ]: - r"""Return a callable for the run report method over gRPC. + r"""Return a callable for the run funnel report method over gRPC. - Returns a customized report of your Google Analytics - event data. Reports contain statistics derived from data - collected by the Google Analytics tracking code. The - data returned from the API is as a table with columns - for the requested dimensions and metrics. Metrics are - individual measurements of user activity on your - property, such as active users or event count. - Dimensions break down metrics across some common - criteria, such as country or event name. + Returns a customized funnel report of your Google Analytics + event data. The data returned from the API is as a table with + columns for the requested dimensions and metrics. - Returns: - Callable[[~.RunReportRequest], - Awaitable[~.RunReportResponse]]: - 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 "run_report" not in self._stubs: - self._stubs["run_report"] = self.grpc_channel.unary_unary( - "/google.analytics.data.v1alpha.AlphaAnalyticsData/RunReport", - request_serializer=analytics_data_api.RunReportRequest.serialize, - response_deserializer=analytics_data_api.RunReportResponse.deserialize, - ) - return self._stubs["run_report"] - - @property - def run_pivot_report( - self, - ) -> Callable[ - [analytics_data_api.RunPivotReportRequest], - Awaitable[analytics_data_api.RunPivotReportResponse], - ]: - r"""Return a callable for the run pivot report method over gRPC. - - Returns a customized pivot report of your Google - Analytics event data. Pivot reports are more advanced - and expressive formats than regular reports. In a pivot - report, dimensions are only visible if they are included - in a pivot. Multiple pivots can be specified to further - dissect your data. - - Returns: - Callable[[~.RunPivotReportRequest], - Awaitable[~.RunPivotReportResponse]]: - 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 "run_pivot_report" not in self._stubs: - self._stubs["run_pivot_report"] = self.grpc_channel.unary_unary( - "/google.analytics.data.v1alpha.AlphaAnalyticsData/RunPivotReport", - request_serializer=analytics_data_api.RunPivotReportRequest.serialize, - response_deserializer=analytics_data_api.RunPivotReportResponse.deserialize, - ) - return self._stubs["run_pivot_report"] - - @property - def batch_run_reports( - self, - ) -> Callable[ - [analytics_data_api.BatchRunReportsRequest], - Awaitable[analytics_data_api.BatchRunReportsResponse], - ]: - r"""Return a callable for the batch run reports method over gRPC. - - Returns multiple reports in a batch. All reports must - be for the same Entity. + Funnel exploration lets you visualize the steps your users take + to complete a task and quickly see how well they are succeeding + or failing at each step. For example, how do prospects become + shoppers and then become buyers? How do one time buyers become + repeat buyers? With this information, you can improve + inefficient or abandoned customer journeys. To learn more, see + `GA4 Funnel + Explorations `__. Returns: - Callable[[~.BatchRunReportsRequest], - Awaitable[~.BatchRunReportsResponse]]: + Callable[[~.RunFunnelReportRequest], + Awaitable[~.RunFunnelReportResponse]]: A function that, when called, will call the underlying RPC on the server. """ @@ -321,113 +262,16 @@ def batch_run_reports( # the request. # gRPC handles serialization and deserialization, so we just need # to pass in the functions for each. - if "batch_run_reports" not in self._stubs: - self._stubs["batch_run_reports"] = self.grpc_channel.unary_unary( - "/google.analytics.data.v1alpha.AlphaAnalyticsData/BatchRunReports", - request_serializer=analytics_data_api.BatchRunReportsRequest.serialize, - response_deserializer=analytics_data_api.BatchRunReportsResponse.deserialize, + if "run_funnel_report" not in self._stubs: + self._stubs["run_funnel_report"] = self.grpc_channel.unary_unary( + "/google.analytics.data.v1alpha.AlphaAnalyticsData/RunFunnelReport", + request_serializer=analytics_data_api.RunFunnelReportRequest.serialize, + response_deserializer=analytics_data_api.RunFunnelReportResponse.deserialize, ) - return self._stubs["batch_run_reports"] - - @property - def batch_run_pivot_reports( - self, - ) -> Callable[ - [analytics_data_api.BatchRunPivotReportsRequest], - Awaitable[analytics_data_api.BatchRunPivotReportsResponse], - ]: - r"""Return a callable for the batch run pivot reports method over gRPC. - - Returns multiple pivot reports in a batch. All - reports must be for the same Entity. + return self._stubs["run_funnel_report"] - Returns: - Callable[[~.BatchRunPivotReportsRequest], - Awaitable[~.BatchRunPivotReportsResponse]]: - 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 "batch_run_pivot_reports" not in self._stubs: - self._stubs["batch_run_pivot_reports"] = self.grpc_channel.unary_unary( - "/google.analytics.data.v1alpha.AlphaAnalyticsData/BatchRunPivotReports", - request_serializer=analytics_data_api.BatchRunPivotReportsRequest.serialize, - response_deserializer=analytics_data_api.BatchRunPivotReportsResponse.deserialize, - ) - return self._stubs["batch_run_pivot_reports"] - - @property - def get_metadata( - self, - ) -> Callable[ - [analytics_data_api.GetMetadataRequest], Awaitable[analytics_data_api.Metadata] - ]: - r"""Return a callable for the get metadata method over gRPC. - - Returns metadata for dimensions and metrics available in - reporting methods. Used to explore the dimensions and metrics. - In this method, a Google Analytics GA4 Property Identifier is - specified in the request, and the metadata response includes - Custom dimensions and metrics as well as Universal metadata. - - For example if a custom metric with parameter name - ``levels_unlocked`` is registered to a property, the Metadata - response will contain ``customEvent:levels_unlocked``. Universal - metadata are dimensions and metrics applicable to any property - such as ``country`` and ``totalUsers``. - - Returns: - Callable[[~.GetMetadataRequest], - Awaitable[~.Metadata]]: - 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 "get_metadata" not in self._stubs: - self._stubs["get_metadata"] = self.grpc_channel.unary_unary( - "/google.analytics.data.v1alpha.AlphaAnalyticsData/GetMetadata", - request_serializer=analytics_data_api.GetMetadataRequest.serialize, - response_deserializer=analytics_data_api.Metadata.deserialize, - ) - return self._stubs["get_metadata"] - - @property - def run_realtime_report( - self, - ) -> Callable[ - [analytics_data_api.RunRealtimeReportRequest], - Awaitable[analytics_data_api.RunRealtimeReportResponse], - ]: - r"""Return a callable for the run realtime report method over gRPC. - - The Google Analytics Realtime API returns a - customized report of realtime event data for your - property. These reports show events and usage from the - last 30 minutes. - - Returns: - Callable[[~.RunRealtimeReportRequest], - Awaitable[~.RunRealtimeReportResponse]]: - 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 "run_realtime_report" not in self._stubs: - self._stubs["run_realtime_report"] = self.grpc_channel.unary_unary( - "/google.analytics.data.v1alpha.AlphaAnalyticsData/RunRealtimeReport", - request_serializer=analytics_data_api.RunRealtimeReportRequest.serialize, - response_deserializer=analytics_data_api.RunRealtimeReportResponse.deserialize, - ) - return self._stubs["run_realtime_report"] + def close(self): + return self.grpc_channel.close() __all__ = ("AlphaAnalyticsDataGrpcAsyncIOTransport",) diff --git a/google/analytics/data_v1alpha/types/__init__.py b/google/analytics/data_v1alpha/types/__init__.py index 6ebcb97..0508a46 100644 --- a/google/analytics/data_v1alpha/types/__init__.py +++ b/google/analytics/data_v1alpha/types/__init__.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2020 Google LLC +# Copyright 2022 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -14,91 +14,139 @@ # limitations under the License. # from .analytics_data_api import ( - BatchRunPivotReportsRequest, - BatchRunPivotReportsResponse, - BatchRunReportsRequest, - BatchRunReportsResponse, - GetMetadataRequest, - Metadata, - RunPivotReportRequest, - RunPivotReportResponse, - RunRealtimeReportRequest, - RunRealtimeReportResponse, - RunReportRequest, - RunReportResponse, + RunFunnelReportRequest, + RunFunnelReportResponse, ) from .data import ( - Cohort, - CohortReportSettings, - CohortSpec, - CohortsRange, + BetweenFilter, DateRange, Dimension, DimensionExpression, DimensionHeader, - DimensionMetadata, DimensionValue, - Entity, + EventSegment, + EventSegmentConditionGroup, + EventSegmentCriteria, + EventSegmentExclusion, Filter, FilterExpression, FilterExpressionList, - Metric, + Funnel, + FunnelBreakdown, + FunnelEventFilter, + FunnelFilter, + FunnelFilterExpression, + FunnelFilterExpressionList, + FunnelNextAction, + FunnelParameterFilter, + FunnelParameterFilterExpression, + FunnelParameterFilterExpressionList, + FunnelResponseMetadata, + FunnelStep, + FunnelSubReport, + InListFilter, MetricHeader, - MetricMetadata, MetricValue, + NumericFilter, NumericValue, - OrderBy, - Pivot, - PivotDimensionHeader, - PivotHeader, PropertyQuota, QuotaStatus, - ResponseMetaData, Row, - MetricAggregation, + SamplingMetadata, + Segment, + SegmentEventFilter, + SegmentFilter, + SegmentFilterExpression, + SegmentFilterExpressionList, + SegmentFilterScoping, + SegmentParameterFilter, + SegmentParameterFilterExpression, + SegmentParameterFilterExpressionList, + SegmentParameterFilterScoping, + SessionSegment, + SessionSegmentConditionGroup, + SessionSegmentCriteria, + SessionSegmentExclusion, + StringFilter, + UserSegment, + UserSegmentConditionGroup, + UserSegmentCriteria, + UserSegmentExclusion, + UserSegmentSequenceGroup, + UserSequenceStep, + EventCriteriaScoping, + EventExclusionDuration, MetricType, + SessionCriteriaScoping, + SessionExclusionDuration, + UserCriteriaScoping, + UserExclusionDuration, ) __all__ = ( - "BatchRunPivotReportsRequest", - "BatchRunPivotReportsResponse", - "BatchRunReportsRequest", - "BatchRunReportsResponse", - "GetMetadataRequest", - "Metadata", - "RunPivotReportRequest", - "RunPivotReportResponse", - "RunRealtimeReportRequest", - "RunRealtimeReportResponse", - "RunReportRequest", - "RunReportResponse", - "Cohort", - "CohortReportSettings", - "CohortSpec", - "CohortsRange", + "RunFunnelReportRequest", + "RunFunnelReportResponse", + "BetweenFilter", "DateRange", "Dimension", "DimensionExpression", "DimensionHeader", - "DimensionMetadata", "DimensionValue", - "Entity", + "EventSegment", + "EventSegmentConditionGroup", + "EventSegmentCriteria", + "EventSegmentExclusion", "Filter", "FilterExpression", "FilterExpressionList", - "Metric", + "Funnel", + "FunnelBreakdown", + "FunnelEventFilter", + "FunnelFilter", + "FunnelFilterExpression", + "FunnelFilterExpressionList", + "FunnelNextAction", + "FunnelParameterFilter", + "FunnelParameterFilterExpression", + "FunnelParameterFilterExpressionList", + "FunnelResponseMetadata", + "FunnelStep", + "FunnelSubReport", + "InListFilter", "MetricHeader", - "MetricMetadata", "MetricValue", + "NumericFilter", "NumericValue", - "OrderBy", - "Pivot", - "PivotDimensionHeader", - "PivotHeader", "PropertyQuota", "QuotaStatus", - "ResponseMetaData", "Row", - "MetricAggregation", + "SamplingMetadata", + "Segment", + "SegmentEventFilter", + "SegmentFilter", + "SegmentFilterExpression", + "SegmentFilterExpressionList", + "SegmentFilterScoping", + "SegmentParameterFilter", + "SegmentParameterFilterExpression", + "SegmentParameterFilterExpressionList", + "SegmentParameterFilterScoping", + "SessionSegment", + "SessionSegmentConditionGroup", + "SessionSegmentCriteria", + "SessionSegmentExclusion", + "StringFilter", + "UserSegment", + "UserSegmentConditionGroup", + "UserSegmentCriteria", + "UserSegmentExclusion", + "UserSegmentSequenceGroup", + "UserSequenceStep", + "EventCriteriaScoping", + "EventExclusionDuration", "MetricType", + "SessionCriteriaScoping", + "SessionExclusionDuration", + "UserCriteriaScoping", + "UserExclusionDuration", ) diff --git a/google/analytics/data_v1alpha/types/analytics_data_api.py b/google/analytics/data_v1alpha/types/analytics_data_api.py index 8811722..0e5ecf0 100644 --- a/google/analytics/data_v1alpha/types/analytics_data_api.py +++ b/google/analytics/data_v1alpha/types/analytics_data_api.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2020 Google LLC +# Copyright 2022 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -21,755 +21,196 @@ __protobuf__ = proto.module( package="google.analytics.data.v1alpha", manifest={ - "Metadata", - "RunReportRequest", - "RunReportResponse", - "RunPivotReportRequest", - "RunPivotReportResponse", - "BatchRunReportsRequest", - "BatchRunReportsResponse", - "BatchRunPivotReportsRequest", - "BatchRunPivotReportsResponse", - "GetMetadataRequest", - "RunRealtimeReportRequest", - "RunRealtimeReportResponse", + "RunFunnelReportRequest", + "RunFunnelReportResponse", }, ) -class Metadata(proto.Message): - r"""The dimensions and metrics currently accepted in reporting - methods. +class RunFunnelReportRequest(proto.Message): + r"""The request for a funnel report. Attributes: - name (str): - Resource name of this metadata. - dimensions (Sequence[google.analytics.data_v1alpha.types.DimensionMetadata]): - The dimension descriptions. - metrics (Sequence[google.analytics.data_v1alpha.types.MetricMetadata]): - The metric descriptions. - """ - - name = proto.Field( - proto.STRING, - number=3, - ) - dimensions = proto.RepeatedField( - proto.MESSAGE, - number=1, - message=data.DimensionMetadata, - ) - metrics = proto.RepeatedField( - proto.MESSAGE, - number=2, - message=data.MetricMetadata, - ) - + property (str): + A Google Analytics GA4 property identifier whose events are + tracked. Specified in the URL path and not the body. To + learn more, see `where to find your Property + ID `__. + Within a batch request, this property should either be + unspecified or consistent with the batch-level property. -class RunReportRequest(proto.Message): - r"""The request to generate a report. - Attributes: - entity (google.analytics.data_v1alpha.types.Entity): - A property whose events are tracked. Within a - batch request, this entity should either be - unspecified or consistent with the batch-level - entity. - dimensions (Sequence[google.analytics.data_v1alpha.types.Dimension]): - The dimensions requested and displayed. - metrics (Sequence[google.analytics.data_v1alpha.types.Metric]): - The metrics requested and displayed. + Example: properties/1234 date_ranges (Sequence[google.analytics.data_v1alpha.types.DateRange]): - Date ranges of data to read. If multiple date ranges are - requested, each response row will contain a zero based date - range index. If two date ranges overlap, the event data for - the overlapping days is included in the response rows for - both date ranges. In a cohort request, this ``dateRanges`` - must be unspecified. - offset (int): - The row count of the start row. The first row is counted as - row 0. - - To learn more about this pagination parameter, see - `Pagination `__. + Date ranges of data to read. If multiple date + ranges are requested, each response row will + contain a zero based date range index. If two + date ranges overlap, the event data for the + overlapping days is included in the response + rows for both date ranges. + funnel (google.analytics.data_v1alpha.types.Funnel): + The configuration of this request's funnel. + This funnel configuration is required. + funnel_breakdown (google.analytics.data_v1alpha.types.FunnelBreakdown): + If specified, this breakdown adds a dimension to the funnel + table sub report response. This breakdown dimension expands + each funnel step to the unique values of the breakdown + dimension. For example, a breakdown by the + ``deviceCategory`` dimension will create rows for + ``mobile``, ``tablet``, ``desktop``, and the total. + funnel_next_action (google.analytics.data_v1alpha.types.FunnelNextAction): + If specified, next action adds a dimension to the funnel + visualization sub report response. This next action + dimension expands each funnel step to the unique values of + the next action. For example a breakdown by the + ``eventName`` dimension will create rows for several events + (i.e. ``session_start`` & ``click``) and the total. + funnel_visualization_type (google.analytics.data_v1alpha.types.RunFunnelReportRequest.FunnelVisualizationType): + The funnel visualization type controls the dimensions + present in the funnel visualization sub report response. If + not specified, ``STANDARD_FUNNEL`` is used. + segments (Sequence[google.analytics.data_v1alpha.types.Segment]): + The configurations of segments. Segments are + subsets of a property's data. In a funnel report + with segments, the funnel is evaluated in each + segment. + Each segment specified in this request + produces a separate row in the response; in the + response, each segment identified by its name. + + The segments parameter is optional. Requests are + limited to 4 segments. limit (int): - The number of rows to return. If unspecified, 10 rows are - returned. If -1, all rows are returned. - - To learn more about this pagination parameter, see - `Pagination `__. - metric_aggregations (Sequence[google.analytics.data_v1alpha.types.MetricAggregation]): - Aggregation of metrics. Aggregated metric values will be - shown in rows where the dimension_values are set to - "RESERVED_(MetricAggregation)". + The number of rows to return. If unspecified, 10,000 rows + are returned. The API returns a maximum of 100,000 rows per + request, no matter how many you ask for. ``limit`` must be + positive. + + The API can also return fewer rows than the requested + ``limit``, if there aren't as many dimension values as the + ``limit``. dimension_filter (google.analytics.data_v1alpha.types.FilterExpression): - The filter clause of dimensions. Dimensions - must be requested to be used in this filter. - Metrics cannot be used in this filter. - metric_filter (google.analytics.data_v1alpha.types.FilterExpression): - The filter clause of metrics. Applied at post - aggregation phase, similar to SQL having-clause. - Metrics must be requested to be used in this - filter. Dimensions cannot be used in this - filter. - order_bys (Sequence[google.analytics.data_v1alpha.types.OrderBy]): - Specifies how rows are ordered in the - response. - currency_code (str): - A currency code in ISO4217 format, such as - "AED", "USD", "JPY". If the field is empty, the - report uses the entity's default currency. - cohort_spec (google.analytics.data_v1alpha.types.CohortSpec): - Cohort group associated with this request. If - there is a cohort group in the request the - 'cohort' dimension must be present. - keep_empty_rows (bool): - If false or unspecified, each row with all - metrics equal to 0 will not be returned. If - true, these rows will be returned if they are - not separately removed by a filter. + Dimension filters allow you to ask for only specific + dimension values in the report. To learn more, see `Creating + a Report: Dimension + Filters `__ + for examples. Metrics cannot be used in this filter. return_property_quota (bool): Toggles whether to return the current state of this Analytics Property's quota. Quota is returned in `PropertyQuota <#PropertyQuota>`__. """ - entity = proto.Field( - proto.MESSAGE, - number=1, - message=data.Entity, - ) - dimensions = proto.RepeatedField( - proto.MESSAGE, - number=2, - message=data.Dimension, - ) - metrics = proto.RepeatedField( - proto.MESSAGE, - number=3, - message=data.Metric, - ) - date_ranges = proto.RepeatedField( - proto.MESSAGE, - number=4, - message=data.DateRange, - ) - offset = proto.Field( - proto.INT64, - number=5, - ) - limit = proto.Field( - proto.INT64, - number=6, - ) - metric_aggregations = proto.RepeatedField( - proto.ENUM, - number=7, - enum=data.MetricAggregation, - ) - dimension_filter = proto.Field( - proto.MESSAGE, - number=8, - message=data.FilterExpression, - ) - metric_filter = proto.Field( - proto.MESSAGE, - number=9, - message=data.FilterExpression, - ) - order_bys = proto.RepeatedField( - proto.MESSAGE, - number=10, - message=data.OrderBy, - ) - currency_code = proto.Field( - proto.STRING, - number=11, - ) - cohort_spec = proto.Field( - proto.MESSAGE, - number=12, - message=data.CohortSpec, - ) - keep_empty_rows = proto.Field( - proto.BOOL, - number=13, - ) - return_property_quota = proto.Field( - proto.BOOL, - number=14, - ) - - -class RunReportResponse(proto.Message): - r"""The response report table corresponding to a request. - Attributes: - dimension_headers (Sequence[google.analytics.data_v1alpha.types.DimensionHeader]): - Describes dimension columns. The number of - DimensionHeaders and ordering of - DimensionHeaders matches the dimensions present - in rows. - metric_headers (Sequence[google.analytics.data_v1alpha.types.MetricHeader]): - Describes metric columns. The number of - MetricHeaders and ordering of MetricHeaders - matches the metrics present in rows. - rows (Sequence[google.analytics.data_v1alpha.types.Row]): - Rows of dimension value combinations and - metric values in the report. - totals (Sequence[google.analytics.data_v1alpha.types.Row]): - If requested, the totaled values of metrics. - maximums (Sequence[google.analytics.data_v1alpha.types.Row]): - If requested, the maximum values of metrics. - minimums (Sequence[google.analytics.data_v1alpha.types.Row]): - If requested, the minimum values of metrics. - row_count (int): - The total number of rows in the query result, regardless of - the number of rows returned in the response. For example if - a query returns 175 rows and includes limit = 50 in the API - request, the response will contain row_count = 175 but only - 50 rows. + class FunnelVisualizationType(proto.Enum): + r"""Controls the dimensions present in the funnel visualization + sub report response. + """ + FUNNEL_VISUALIZATION_TYPE_UNSPECIFIED = 0 + STANDARD_FUNNEL = 1 + TRENDED_FUNNEL = 2 - To learn more about this pagination parameter, see - `Pagination `__. - metadata (google.analytics.data_v1alpha.types.ResponseMetaData): - Metadata for the report. - property_quota (google.analytics.data_v1alpha.types.PropertyQuota): - This Analytics Property's quota state - including this request. - """ - - dimension_headers = proto.RepeatedField( - proto.MESSAGE, - number=11, - message=data.DimensionHeader, - ) - metric_headers = proto.RepeatedField( - proto.MESSAGE, - number=1, - message=data.MetricHeader, - ) - rows = proto.RepeatedField( - proto.MESSAGE, - number=2, - message=data.Row, - ) - totals = proto.RepeatedField( - proto.MESSAGE, - number=8, - message=data.Row, - ) - maximums = proto.RepeatedField( - proto.MESSAGE, - number=9, - message=data.Row, - ) - minimums = proto.RepeatedField( - proto.MESSAGE, - number=10, - message=data.Row, - ) - row_count = proto.Field( - proto.INT32, - number=12, - ) - metadata = proto.Field( - proto.MESSAGE, - number=6, - message=data.ResponseMetaData, - ) - property_quota = proto.Field( - proto.MESSAGE, - number=7, - message=data.PropertyQuota, - ) - - -class RunPivotReportRequest(proto.Message): - r"""The request to generate a pivot report. - Attributes: - entity (google.analytics.data_v1alpha.types.Entity): - A property whose events are tracked. Within a - batch request, this entity should either be - unspecified or consistent with the batch-level - entity. - dimensions (Sequence[google.analytics.data_v1alpha.types.Dimension]): - The dimensions requested. All defined dimensions must be - used by one of the following: dimension_expression, - dimension_filter, pivots, order_bys. - metrics (Sequence[google.analytics.data_v1alpha.types.Metric]): - The metrics requested, at least one metric needs to be - specified. All defined metrics must be used by one of the - following: metric_expression, metric_filter, order_bys. - dimension_filter (google.analytics.data_v1alpha.types.FilterExpression): - The filter clause of dimensions. Dimensions - must be requested to be used in this filter. - Metrics cannot be used in this filter. - metric_filter (google.analytics.data_v1alpha.types.FilterExpression): - The filter clause of metrics. Applied at post - aggregation phase, similar to SQL having-clause. - Metrics must be requested to be used in this - filter. Dimensions cannot be used in this - filter. - pivots (Sequence[google.analytics.data_v1alpha.types.Pivot]): - Describes the visual format of the report's - dimensions in columns or rows. The union of the - fieldNames (dimension names) in all pivots must - be a subset of dimension names defined in - Dimensions. No two pivots can share a dimension. - A dimension is only visible if it appears in a - pivot. - date_ranges (Sequence[google.analytics.data_v1alpha.types.DateRange]): - The date range to retrieve event data for the report. If - multiple date ranges are specified, event data from each - date range is used in the report. A special dimension with - field name "dateRange" can be included in a Pivot's field - names; if included, the report compares between date ranges. - In a cohort request, this ``dateRanges`` must be - unspecified. - currency_code (str): - A currency code in ISO4217 format, such as - "AED", "USD", "JPY". If the field is empty, the - report uses the entity's default currency. - cohort_spec (google.analytics.data_v1alpha.types.CohortSpec): - Cohort group associated with this request. If - there is a cohort group in the request the - 'cohort' dimension must be present. - keep_empty_rows (bool): - If false or unspecified, each row with all - metrics equal to 0 will not be returned. If - true, these rows will be returned if they are - not separately removed by a filter. - return_property_quota (bool): - Toggles whether to return the current state of this - Analytics Property's quota. Quota is returned in - `PropertyQuota <#PropertyQuota>`__. - """ - - entity = proto.Field( - proto.MESSAGE, + property = proto.Field( + proto.STRING, number=1, - message=data.Entity, ) - dimensions = proto.RepeatedField( + date_ranges = proto.RepeatedField( proto.MESSAGE, number=2, - message=data.Dimension, + message=data.DateRange, ) - metrics = proto.RepeatedField( + funnel = proto.Field( proto.MESSAGE, number=3, - message=data.Metric, + message=data.Funnel, ) - dimension_filter = proto.Field( + funnel_breakdown = proto.Field( proto.MESSAGE, number=4, - message=data.FilterExpression, + message=data.FunnelBreakdown, ) - metric_filter = proto.Field( + funnel_next_action = proto.Field( proto.MESSAGE, number=5, - message=data.FilterExpression, + message=data.FunnelNextAction, ) - pivots = proto.RepeatedField( - proto.MESSAGE, + funnel_visualization_type = proto.Field( + proto.ENUM, number=6, - message=data.Pivot, + enum=FunnelVisualizationType, ) - date_ranges = proto.RepeatedField( + segments = proto.RepeatedField( proto.MESSAGE, number=7, - message=data.DateRange, - ) - currency_code = proto.Field( - proto.STRING, - number=8, + message=data.Segment, ) - cohort_spec = proto.Field( - proto.MESSAGE, + limit = proto.Field( + proto.INT64, number=9, - message=data.CohortSpec, ) - keep_empty_rows = proto.Field( - proto.BOOL, + dimension_filter = proto.Field( + proto.MESSAGE, number=10, + message=data.FilterExpression, ) return_property_quota = proto.Field( proto.BOOL, - number=11, + number=12, ) -class RunPivotReportResponse(proto.Message): - r"""The response pivot report table corresponding to a pivot - request. +class RunFunnelReportResponse(proto.Message): + r"""The funnel report response contains two sub reports. The two + sub reports are different combinations of dimensions and + metrics. Attributes: - pivot_headers (Sequence[google.analytics.data_v1alpha.types.PivotHeader]): - Summarizes the columns and rows created by a pivot. Each - pivot in the request produces one header in the response. If - we have a request like this: - - :: - - "pivots": [{ - "fieldNames": ["country", - "city"] - }, - { - "fieldNames": "eventName" - }] - - We will have the following ``pivotHeaders`` in the response: - - :: - - "pivotHeaders" : [{ - "dimensionHeaders": [{ - "dimensionValues": [ - { "value": "United Kingdom" }, - { "value": "London" } - ] - }, - { - "dimensionValues": [ - { "value": "Japan" }, - { "value": "Osaka" } - ] - }] - }, - { - "dimensionHeaders": [{ - "dimensionValues": [{ "value": "session_start" }] - }, - { - "dimensionValues": [{ "value": "scroll" }] - }] - }] - dimension_headers (Sequence[google.analytics.data_v1alpha.types.DimensionHeader]): - Describes dimension columns. The number of - DimensionHeaders and ordering of - DimensionHeaders matches the dimensions present - in rows. - metric_headers (Sequence[google.analytics.data_v1alpha.types.MetricHeader]): - Describes metric columns. The number of - MetricHeaders and ordering of MetricHeaders - matches the metrics present in rows. - rows (Sequence[google.analytics.data_v1alpha.types.Row]): - Rows of dimension value combinations and - metric values in the report. - aggregates (Sequence[google.analytics.data_v1alpha.types.Row]): - Aggregation of metric values. Can be totals, minimums, or - maximums. The returned aggregations are controlled by the - metric_aggregations in the pivot. The type of aggregation - returned in each row is shown by the dimension_values which - are set to "RESERVED\_". - metadata (google.analytics.data_v1alpha.types.ResponseMetaData): - Metadata for the report. + funnel_table (google.analytics.data_v1alpha.types.FunnelSubReport): + The funnel table is a report with the funnel + step, segment, breakdown dimension, active + users, completion rate, abandonments, and + abandonments rate. + + The segment dimension is only present in this + response if a segment was requested. The + breakdown dimension is only present in this + response if it was requested. + funnel_visualization (google.analytics.data_v1alpha.types.FunnelSubReport): + The funnel visualization is a report with the funnel step, + segment, date, next action dimension, and active users. + + The segment dimension is only present in this response if a + segment was requested. The date dimension is only present in + this response if it was requested via the ``TRENDED_FUNNEL`` + funnel type. The next action dimension is only present in + the response if it was requested. property_quota (google.analytics.data_v1alpha.types.PropertyQuota): This Analytics Property's quota state including this request. + kind (str): + Identifies what kind of resource this message is. This + ``kind`` is always the fixed string + "analyticsData#runFunnelReport". Useful to distinguish + between response types in JSON. """ - pivot_headers = proto.RepeatedField( + funnel_table = proto.Field( proto.MESSAGE, number=1, - message=data.PivotHeader, - ) - dimension_headers = proto.RepeatedField( - proto.MESSAGE, - number=7, - message=data.DimensionHeader, + message=data.FunnelSubReport, ) - metric_headers = proto.RepeatedField( + funnel_visualization = proto.Field( proto.MESSAGE, number=2, - message=data.MetricHeader, - ) - rows = proto.RepeatedField( - proto.MESSAGE, - number=3, - message=data.Row, - ) - aggregates = proto.RepeatedField( - proto.MESSAGE, - number=4, - message=data.Row, - ) - metadata = proto.Field( - proto.MESSAGE, - number=5, - message=data.ResponseMetaData, + message=data.FunnelSubReport, ) property_quota = proto.Field( proto.MESSAGE, - number=6, + number=3, message=data.PropertyQuota, ) - - -class BatchRunReportsRequest(proto.Message): - r"""The batch request containing multiple report requests. - Attributes: - entity (google.analytics.data_v1alpha.types.Entity): - A property whose events are tracked. This - entity must be specified for the batch. The - entity within RunReportRequest may either be - unspecified or consistent with this entity. - requests (Sequence[google.analytics.data_v1alpha.types.RunReportRequest]): - Individual requests. Each request has a - separate report response. Each batch request is - allowed up to 5 requests. - """ - - entity = proto.Field( - proto.MESSAGE, - number=1, - message=data.Entity, - ) - requests = proto.RepeatedField( - proto.MESSAGE, - number=2, - message="RunReportRequest", - ) - - -class BatchRunReportsResponse(proto.Message): - r"""The batch response containing multiple reports. - Attributes: - reports (Sequence[google.analytics.data_v1alpha.types.RunReportResponse]): - Individual responses. Each response has a - separate report request. - """ - - reports = proto.RepeatedField( - proto.MESSAGE, - number=1, - message="RunReportResponse", - ) - - -class BatchRunPivotReportsRequest(proto.Message): - r"""The batch request containing multiple pivot report requests. - Attributes: - entity (google.analytics.data_v1alpha.types.Entity): - A property whose events are tracked. This - entity must be specified for the batch. The - entity within RunPivotReportRequest may either - be unspecified or consistent with this entity. - requests (Sequence[google.analytics.data_v1alpha.types.RunPivotReportRequest]): - Individual requests. Each request has a - separate pivot report response. Each batch - request is allowed up to 5 requests. - """ - - entity = proto.Field( - proto.MESSAGE, - number=1, - message=data.Entity, - ) - requests = proto.RepeatedField( - proto.MESSAGE, - number=2, - message="RunPivotReportRequest", - ) - - -class BatchRunPivotReportsResponse(proto.Message): - r"""The batch response containing multiple pivot reports. - Attributes: - pivot_reports (Sequence[google.analytics.data_v1alpha.types.RunPivotReportResponse]): - Individual responses. Each response has a - separate pivot report request. - """ - - pivot_reports = proto.RepeatedField( - proto.MESSAGE, - number=1, - message="RunPivotReportResponse", - ) - - -class GetMetadataRequest(proto.Message): - r"""Request for a property's dimension and metric metadata. - Attributes: - name (str): - Required. The resource name of the metadata to retrieve. - This name field is specified in the URL path and not URL - parameters. Property is a numeric Google Analytics GA4 - Property identifier. To learn more, see `where to find your - Property - ID `__. - - Example: properties/1234/metadata - - Set the Property ID to 0 for dimensions and metrics common - to all properties. In this special mode, this method will - not return custom dimensions and metrics. - """ - - name = proto.Field( + kind = proto.Field( proto.STRING, - number=1, - ) - - -class RunRealtimeReportRequest(proto.Message): - r"""The request to generate a realtime report. - Attributes: - property (str): - A Google Analytics GA4 property identifier whose events are - tracked. Specified in the URL path and not the body. To - learn more, see `where to find your Property - ID `__. - - Example: properties/1234 - dimensions (Sequence[google.analytics.data_v1alpha.types.Dimension]): - The dimensions requested and displayed. - metrics (Sequence[google.analytics.data_v1alpha.types.Metric]): - The metrics requested and displayed. - limit (int): - The number of rows to return. If unspecified, - 10 rows are returned. If -1, all rows are - returned. - dimension_filter (google.analytics.data_v1alpha.types.FilterExpression): - The filter clause of dimensions. Dimensions - must be requested to be used in this filter. - Metrics cannot be used in this filter. - metric_filter (google.analytics.data_v1alpha.types.FilterExpression): - The filter clause of metrics. Applied at post - aggregation phase, similar to SQL having-clause. - Metrics must be requested to be used in this - filter. Dimensions cannot be used in this - filter. - metric_aggregations (Sequence[google.analytics.data_v1alpha.types.MetricAggregation]): - Aggregation of metrics. Aggregated metric values will be - shown in rows where the dimension_values are set to - "RESERVED_(MetricAggregation)". - order_bys (Sequence[google.analytics.data_v1alpha.types.OrderBy]): - Specifies how rows are ordered in the - response. - return_property_quota (bool): - Toggles whether to return the current state of this - Analytics Property's Realtime quota. Quota is returned in - `PropertyQuota <#PropertyQuota>`__. - """ - - property = proto.Field( - proto.STRING, - number=1, - ) - dimensions = proto.RepeatedField( - proto.MESSAGE, - number=2, - message=data.Dimension, - ) - metrics = proto.RepeatedField( - proto.MESSAGE, - number=3, - message=data.Metric, - ) - limit = proto.Field( - proto.INT64, number=4, ) - dimension_filter = proto.Field( - proto.MESSAGE, - number=5, - message=data.FilterExpression, - ) - metric_filter = proto.Field( - proto.MESSAGE, - number=6, - message=data.FilterExpression, - ) - metric_aggregations = proto.RepeatedField( - proto.ENUM, - number=7, - enum=data.MetricAggregation, - ) - order_bys = proto.RepeatedField( - proto.MESSAGE, - number=8, - message=data.OrderBy, - ) - return_property_quota = proto.Field( - proto.BOOL, - number=9, - ) - - -class RunRealtimeReportResponse(proto.Message): - r"""The response realtime report table corresponding to a - request. - - Attributes: - dimension_headers (Sequence[google.analytics.data_v1alpha.types.DimensionHeader]): - Describes dimension columns. The number of - DimensionHeaders and ordering of - DimensionHeaders matches the dimensions present - in rows. - metric_headers (Sequence[google.analytics.data_v1alpha.types.MetricHeader]): - Describes metric columns. The number of - MetricHeaders and ordering of MetricHeaders - matches the metrics present in rows. - rows (Sequence[google.analytics.data_v1alpha.types.Row]): - Rows of dimension value combinations and - metric values in the report. - totals (Sequence[google.analytics.data_v1alpha.types.Row]): - If requested, the totaled values of metrics. - maximums (Sequence[google.analytics.data_v1alpha.types.Row]): - If requested, the maximum values of metrics. - minimums (Sequence[google.analytics.data_v1alpha.types.Row]): - If requested, the minimum values of metrics. - row_count (int): - The total number of rows in the query result, regardless of - the number of rows returned in the response. For example if - a query returns 175 rows and includes limit = 50 in the API - request, the response will contain row_count = 175 but only - 50 rows. - property_quota (google.analytics.data_v1alpha.types.PropertyQuota): - This Analytics Property's Realtime quota - state including this request. - """ - - dimension_headers = proto.RepeatedField( - proto.MESSAGE, - number=1, - message=data.DimensionHeader, - ) - metric_headers = proto.RepeatedField( - proto.MESSAGE, - number=2, - message=data.MetricHeader, - ) - rows = proto.RepeatedField( - proto.MESSAGE, - number=3, - message=data.Row, - ) - totals = proto.RepeatedField( - proto.MESSAGE, - number=4, - message=data.Row, - ) - maximums = proto.RepeatedField( - proto.MESSAGE, - number=5, - message=data.Row, - ) - minimums = proto.RepeatedField( - proto.MESSAGE, - number=6, - message=data.Row, - ) - row_count = proto.Field( - proto.INT32, - number=7, - ) - property_quota = proto.Field( - proto.MESSAGE, - number=8, - message=data.PropertyQuota, - ) __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/analytics/data_v1alpha/types/data.py b/google/analytics/data_v1alpha/types/data.py index 7ad35e3..6bd7431 100644 --- a/google/analytics/data_v1alpha/types/data.py +++ b/google/analytics/data_v1alpha/types/data.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2020 Google LLC +# Copyright 2022 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,50 +15,130 @@ # import proto # type: ignore +from google.protobuf import duration_pb2 # type: ignore + __protobuf__ = proto.module( package="google.analytics.data.v1alpha", manifest={ - "MetricAggregation", + "UserCriteriaScoping", + "UserExclusionDuration", + "SessionCriteriaScoping", + "SessionExclusionDuration", + "EventCriteriaScoping", + "EventExclusionDuration", "MetricType", "DateRange", - "Entity", "Dimension", "DimensionExpression", - "Metric", "FilterExpression", "FilterExpressionList", "Filter", - "OrderBy", - "Pivot", - "CohortSpec", - "Cohort", - "CohortsRange", - "CohortReportSettings", - "ResponseMetaData", + "StringFilter", + "InListFilter", + "NumericFilter", + "BetweenFilter", + "NumericValue", "DimensionHeader", "MetricHeader", - "PivotHeader", - "PivotDimensionHeader", "Row", "DimensionValue", "MetricValue", - "NumericValue", "PropertyQuota", "QuotaStatus", - "DimensionMetadata", - "MetricMetadata", + "FunnelBreakdown", + "FunnelNextAction", + "Funnel", + "FunnelStep", + "FunnelSubReport", + "UserSegment", + "UserSegmentCriteria", + "UserSegmentConditionGroup", + "UserSegmentSequenceGroup", + "UserSequenceStep", + "UserSegmentExclusion", + "SessionSegment", + "SessionSegmentCriteria", + "SessionSegmentConditionGroup", + "SessionSegmentExclusion", + "EventSegment", + "EventSegmentCriteria", + "EventSegmentConditionGroup", + "EventSegmentExclusion", + "Segment", + "SegmentFilterExpression", + "SegmentFilterExpressionList", + "SegmentFilter", + "SegmentFilterScoping", + "SegmentEventFilter", + "SegmentParameterFilterExpression", + "SegmentParameterFilterExpressionList", + "SegmentParameterFilter", + "SegmentParameterFilterScoping", + "FunnelFilterExpression", + "FunnelFilterExpressionList", + "FunnelFilter", + "FunnelEventFilter", + "FunnelParameterFilterExpression", + "FunnelParameterFilterExpressionList", + "FunnelParameterFilter", + "FunnelResponseMetadata", + "SamplingMetadata", }, ) -class MetricAggregation(proto.Enum): - r"""Represents aggregation of metrics.""" - METRIC_AGGREGATION_UNSPECIFIED = 0 - TOTAL = 1 - MINIMUM = 5 - MAXIMUM = 6 - COUNT = 4 +class UserCriteriaScoping(proto.Enum): + r"""Scoping specifies which events are considered when evaluating + if a user meets a criteria. + """ + USER_CRITERIA_SCOPING_UNSPECIFIED = 0 + USER_CRITERIA_WITHIN_SAME_EVENT = 1 + USER_CRITERIA_WITHIN_SAME_SESSION = 2 + USER_CRITERIA_ACROSS_ALL_SESSIONS = 3 + + +class UserExclusionDuration(proto.Enum): + r"""Enumerates options for how long an exclusion will last if a user + matches the ``userExclusionCriteria``. + """ + USER_EXCLUSION_DURATION_UNSPECIFIED = 0 + USER_EXCLUSION_TEMPORARY = 1 + USER_EXCLUSION_PERMANENT = 2 + + +class SessionCriteriaScoping(proto.Enum): + r"""Scoping specifies which events are considered when evaluating + if a session meets a criteria. + """ + SESSION_CRITERIA_SCOPING_UNSPECIFIED = 0 + SESSION_CRITERIA_WITHIN_SAME_EVENT = 1 + SESSION_CRITERIA_WITHIN_SAME_SESSION = 2 + + +class SessionExclusionDuration(proto.Enum): + r"""Enumerates options for how long an exclusion will last if a session + matches the ``sessionExclusionCriteria``. + """ + SESSION_EXCLUSION_DURATION_UNSPECIFIED = 0 + SESSION_EXCLUSION_TEMPORARY = 1 + SESSION_EXCLUSION_PERMANENT = 2 + + +class EventCriteriaScoping(proto.Enum): + r"""Scoping specifies which events are considered when evaluating + if an event meets a criteria. + """ + EVENT_CRITERIA_SCOPING_UNSPECIFIED = 0 + EVENT_CRITERIA_WITHIN_SAME_EVENT = 1 + + +class EventExclusionDuration(proto.Enum): + r"""Enumerates options for how long an exclusion will last if an event + matches the ``eventExclusionCriteria``. + """ + EVENT_EXCLUSION_DURATION_UNSPECIFIED = 0 + EVENT_EXCLUSION_PERMANENT = 1 class MetricType(proto.Enum): @@ -117,29 +197,11 @@ class DateRange(proto.Message): ) -class Entity(proto.Message): - r"""The unique identifier of the property whose events are - tracked. - - Attributes: - property_id (str): - A Google Analytics GA4 property id. To learn more, see - `where to find your Property - ID `__. - """ - - property_id = proto.Field( - proto.STRING, - number=1, - ) - - class Dimension(proto.Message): r"""Dimensions are attributes of your data. For example, the dimension city indicates the city from which an event originates. Dimension values in report responses are strings; - for example, city could be "Paris" or "New York". Requests are - allowed up to 8 dimensions. + for example, the city could be "Paris" or "New York". Attributes: name (str): @@ -148,9 +210,11 @@ class Dimension(proto.Message): for the list of dimension names. If ``dimensionExpression`` is specified, ``name`` can be any - string that you would like. For example if a - ``dimensionExpression`` concatenates ``country`` and - ``city``, you could call that dimension ``countryAndCity``. + string that you would like within the allowed character set. + For example if a ``dimensionExpression`` concatenates + ``country`` and ``city``, you could call that dimension + ``countryAndCity``. Dimension names that you choose must + match the regular expression ``^[a-zA-Z0-9_]$``. Dimensions are referenced by ``name`` in ``dimensionFilter``, ``orderBys``, ``dimensionExpression``, @@ -180,21 +244,35 @@ class DimensionExpression(proto.Message): 1) lower_case(dimension) 2) concatenate(dimension1, symbol, dimension2). + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + Attributes: lower_case (google.analytics.data_v1alpha.types.DimensionExpression.CaseExpression): Used to convert a dimension value to lower case. + + This field is a member of `oneof`_ ``one_expression``. upper_case (google.analytics.data_v1alpha.types.DimensionExpression.CaseExpression): Used to convert a dimension value to upper case. + + This field is a member of `oneof`_ ``one_expression``. concatenate (google.analytics.data_v1alpha.types.DimensionExpression.ConcatenateExpression): Used to combine dimension values to a single dimension. For example, dimension "country, city": concatenate(country, ", ", city). + + This field is a member of `oneof`_ ``one_expression``. """ class CaseExpression(proto.Message): r"""Used to convert a dimension value to a single case. + Attributes: dimension_name (str): Name of a dimension. The name must refer back @@ -208,6 +286,7 @@ class CaseExpression(proto.Message): class ConcatenateExpression(proto.Message): r"""Used to combine dimension values to a single dimension. + Attributes: dimension_names (Sequence[str]): Names of dimensions. The names must refer @@ -253,65 +332,38 @@ class ConcatenateExpression(proto.Message): ) -class Metric(proto.Message): - r"""The quantitative measurements of a report. For example, the metric - ``eventCount`` is the total number of events. Requests are allowed - up to 10 metrics. - - Attributes: - name (str): - The name of the metric. See the `API - Metrics `__ - for the list of metric names. - - If ``expression`` is specified, ``name`` can be any string - that you would like. For example if ``expression`` is - ``screenPageViews/sessions``, you could call that metric's - name = ``viewsPerSession``. - - Metrics are referenced by ``name`` in ``metricFilter``, - ``orderBys``, and metric ``expression``. - expression (str): - A mathematical expression for derived metrics. For example, - the metric Event count per user is - ``eventCount/totalUsers``. - invisible (bool): - Indicates if a metric is invisible in the report response. - If a metric is invisible, the metric will not produce a - column in the response, but can be used in ``metricFilter``, - ``orderBys``, or a metric ``expression``. - """ - - name = proto.Field( - proto.STRING, - number=1, - ) - expression = proto.Field( - proto.STRING, - number=2, - ) - invisible = proto.Field( - proto.BOOL, - number=3, - ) +class FilterExpression(proto.Message): + r"""To express dimension or metric filters. The fields in the + same FilterExpression need to be either all dimensions or all + metrics. + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. -class FilterExpression(proto.Message): - r"""To express dimension or metric filters. - The fields in the same FilterExpression need to be either all - dimensions or all metrics. + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: and_group (google.analytics.data_v1alpha.types.FilterExpressionList): The FilterExpressions in and_group have an AND relationship. + + This field is a member of `oneof`_ ``expr``. or_group (google.analytics.data_v1alpha.types.FilterExpressionList): The FilterExpressions in or_group have an OR relationship. + + This field is a member of `oneof`_ ``expr``. not_expression (google.analytics.data_v1alpha.types.FilterExpression): The FilterExpression is NOT of not_expression. + + This field is a member of `oneof`_ ``expr``. filter (google.analytics.data_v1alpha.types.Filter): - A primitive filter. - All fields in filter in same FilterExpression - needs to be either all dimensions or metrics. + A primitive filter. In the same + FilterExpression, all of the filter's field + names need to be either all dimensions or all + metrics. + + This field is a member of `oneof`_ ``expr``. """ and_group = proto.Field( @@ -342,6 +394,7 @@ class FilterExpression(proto.Message): class FilterExpressionList(proto.Message): r"""A list of filter expressions. + Attributes: expressions (Sequence[google.analytics.data_v1alpha.types.FilterExpression]): A list of filter expressions. @@ -356,563 +409,208 @@ class FilterExpressionList(proto.Message): class Filter(proto.Message): r"""An expression to filter dimension or metric values. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + Attributes: field_name (str): The dimension name or metric name. Must be a name defined in dimensions or metrics. - null_filter (bool): - A filter for null values. If True, a null - dimension value is matched by this filter. Null - filter is commonly used inside a NOT filter - expression. For example, a NOT expression of a - null filter removes rows when a dimension is - null. - string_filter (google.analytics.data_v1alpha.types.Filter.StringFilter): + string_filter (google.analytics.data_v1alpha.types.StringFilter): Strings related filter. - in_list_filter (google.analytics.data_v1alpha.types.Filter.InListFilter): - A filter for in list values. - numeric_filter (google.analytics.data_v1alpha.types.Filter.NumericFilter): - A filter for numeric or date values. - between_filter (google.analytics.data_v1alpha.types.Filter.BetweenFilter): - A filter for two values. - """ - - class StringFilter(proto.Message): - r"""The filter for string - Attributes: - match_type (google.analytics.data_v1alpha.types.Filter.StringFilter.MatchType): - The match type for this filter. - value (str): - The string value used for the matching. - case_sensitive (bool): - If true, the string value is case sensitive. - """ - - class MatchType(proto.Enum): - r"""The match type of a string filter""" - MATCH_TYPE_UNSPECIFIED = 0 - EXACT = 1 - BEGINS_WITH = 2 - ENDS_WITH = 3 - CONTAINS = 4 - FULL_REGEXP = 5 - PARTIAL_REGEXP = 6 - - match_type = proto.Field( - proto.ENUM, - number=1, - enum="Filter.StringFilter.MatchType", - ) - value = proto.Field( - proto.STRING, - number=2, - ) - case_sensitive = proto.Field( - proto.BOOL, - number=3, - ) - - class InListFilter(proto.Message): - r"""The result needs to be in a list of string values. - Attributes: - values (Sequence[str]): - The list of string values. - Must be non-empty. - case_sensitive (bool): - If true, the string value is case sensitive. - """ - - values = proto.RepeatedField( - proto.STRING, - number=1, - ) - case_sensitive = proto.Field( - proto.BOOL, - number=2, - ) - - class NumericFilter(proto.Message): - r"""Filters for numeric or date values. - Attributes: - operation (google.analytics.data_v1alpha.types.Filter.NumericFilter.Operation): - The operation type for this filter. - value (google.analytics.data_v1alpha.types.NumericValue): - A numeric value or a date value. - """ - class Operation(proto.Enum): - r"""The operation applied to a numeric filter""" - OPERATION_UNSPECIFIED = 0 - EQUAL = 1 - LESS_THAN = 2 - LESS_THAN_OR_EQUAL = 3 - GREATER_THAN = 4 - GREATER_THAN_OR_EQUAL = 5 - - operation = proto.Field( - proto.ENUM, - number=1, - enum="Filter.NumericFilter.Operation", - ) - value = proto.Field( - proto.MESSAGE, - number=2, - message="NumericValue", - ) + This field is a member of `oneof`_ ``one_filter``. + in_list_filter (google.analytics.data_v1alpha.types.InListFilter): + A filter for in list values. - class BetweenFilter(proto.Message): - r"""To express that the result needs to be between two numbers - (inclusive). + This field is a member of `oneof`_ ``one_filter``. + numeric_filter (google.analytics.data_v1alpha.types.NumericFilter): + A filter for numeric or date values. - Attributes: - from_value (google.analytics.data_v1alpha.types.NumericValue): - Begins with this number. - to_value (google.analytics.data_v1alpha.types.NumericValue): - Ends with this number. - """ + This field is a member of `oneof`_ ``one_filter``. + between_filter (google.analytics.data_v1alpha.types.BetweenFilter): + A filter for between two values. - from_value = proto.Field( - proto.MESSAGE, - number=1, - message="NumericValue", - ) - to_value = proto.Field( - proto.MESSAGE, - number=2, - message="NumericValue", - ) + This field is a member of `oneof`_ ``one_filter``. + """ field_name = proto.Field( proto.STRING, number=1, ) - null_filter = proto.Field( - proto.BOOL, - number=2, - oneof="one_filter", - ) string_filter = proto.Field( proto.MESSAGE, - number=3, + number=2, oneof="one_filter", - message=StringFilter, + message="StringFilter", ) in_list_filter = proto.Field( proto.MESSAGE, - number=4, + number=3, oneof="one_filter", - message=InListFilter, + message="InListFilter", ) numeric_filter = proto.Field( proto.MESSAGE, - number=5, + number=4, oneof="one_filter", - message=NumericFilter, + message="NumericFilter", ) between_filter = proto.Field( proto.MESSAGE, - number=6, + number=5, oneof="one_filter", - message=BetweenFilter, + message="BetweenFilter", ) -class OrderBy(proto.Message): - r"""The sort options. +class StringFilter(proto.Message): + r"""The filter for string + Attributes: - metric (google.analytics.data_v1alpha.types.OrderBy.MetricOrderBy): - Sorts results by a metric's values. - dimension (google.analytics.data_v1alpha.types.OrderBy.DimensionOrderBy): - Sorts results by a dimension's values. - pivot (google.analytics.data_v1alpha.types.OrderBy.PivotOrderBy): - Sorts results by a metric's values within a - pivot column group. - desc (bool): - If true, sorts by descending order. + match_type (google.analytics.data_v1alpha.types.StringFilter.MatchType): + The match type for this filter. + value (str): + The string value used for the matching. + case_sensitive (bool): + If true, the string value is case sensitive. """ - class MetricOrderBy(proto.Message): - r"""Sorts by metric values. - Attributes: - metric_name (str): - A metric name in the request to order by. - """ - - metric_name = proto.Field( - proto.STRING, - number=1, - ) - - class DimensionOrderBy(proto.Message): - r"""Sorts by dimension values. - Attributes: - dimension_name (str): - A dimension name in the request to order by. - order_type (google.analytics.data_v1alpha.types.OrderBy.DimensionOrderBy.OrderType): - Controls the rule for dimension value - ordering. - """ - - class OrderType(proto.Enum): - r"""Rule to order the string dimension values by.""" - ORDER_TYPE_UNSPECIFIED = 0 - ALPHANUMERIC = 1 - CASE_INSENSITIVE_ALPHANUMERIC = 2 - NUMERIC = 3 - - dimension_name = proto.Field( - proto.STRING, - number=1, - ) - order_type = proto.Field( - proto.ENUM, - number=2, - enum="OrderBy.DimensionOrderBy.OrderType", - ) - - class PivotOrderBy(proto.Message): - r"""Sorts by a pivot column group. - Attributes: - metric_name (str): - In the response to order by, order rows by - this column. Must be a metric name from the - request. - pivot_selections (Sequence[google.analytics.data_v1alpha.types.OrderBy.PivotOrderBy.PivotSelection]): - Used to select a dimension name and value - pivot. If multiple pivot selections are given, - the sort occurs on rows where all pivot - selection dimension name and value pairs match - the row's dimension name and value pair. - """ - - class PivotSelection(proto.Message): - r"""A pair of dimension names and values. Rows with this dimension pivot - pair are ordered by the metric's value. - - For example if pivots = {{"browser", "Chrome"}} and metric_name = - "Sessions", then the rows will be sorted based on Sessions in - Chrome. - - :: - - ---------|----------|----------------|----------|---------------- - | Chrome | Chrome | Safari | Safari - ---------|----------|----------------|----------|---------------- - Country | Sessions | Pages/Sessions | Sessions | Pages/Sessions - ---------|----------|----------------|----------|---------------- - US | 2 | 2 | 3 | 1 - ---------|----------|----------------|----------|---------------- - Canada | 3 | 1 | 4 | 1 - ---------|----------|----------------|----------|---------------- - - Attributes: - dimension_name (str): - Must be a dimension name from the request. - dimension_value (str): - Order by only when the named dimension is - this value. - """ - - dimension_name = proto.Field( - proto.STRING, - number=1, - ) - dimension_value = proto.Field( - proto.STRING, - number=2, - ) - - metric_name = proto.Field( - proto.STRING, - number=1, - ) - pivot_selections = proto.RepeatedField( - proto.MESSAGE, - number=2, - message="OrderBy.PivotOrderBy.PivotSelection", - ) - - metric = proto.Field( - proto.MESSAGE, + class MatchType(proto.Enum): + r"""The match type of a string filter""" + MATCH_TYPE_UNSPECIFIED = 0 + EXACT = 1 + BEGINS_WITH = 2 + ENDS_WITH = 3 + CONTAINS = 4 + FULL_REGEXP = 5 + PARTIAL_REGEXP = 6 + + match_type = proto.Field( + proto.ENUM, number=1, - oneof="one_order_by", - message=MetricOrderBy, + enum=MatchType, ) - dimension = proto.Field( - proto.MESSAGE, + value = proto.Field( + proto.STRING, number=2, - oneof="one_order_by", - message=DimensionOrderBy, - ) - pivot = proto.Field( - proto.MESSAGE, - number=3, - oneof="one_order_by", - message=PivotOrderBy, ) - desc = proto.Field( + case_sensitive = proto.Field( proto.BOOL, - number=4, + number=3, ) -class Pivot(proto.Message): - r"""Describes the visible dimension columns and rows in the - report response. +class InListFilter(proto.Message): + r"""The result needs to be in a list of string values. Attributes: - field_names (Sequence[str]): - Dimension names for visible columns in the - report response. Including "dateRange" produces - a date range column; for each row in the - response, dimension values in the date range - column will indicate the corresponding date - range from the request. - order_bys (Sequence[google.analytics.data_v1alpha.types.OrderBy]): - Specifies how dimensions are ordered in the pivot. In the - first Pivot, the OrderBys determine Row and - PivotDimensionHeader ordering; in subsequent Pivots, the - OrderBys determine only PivotDimensionHeader ordering. - Dimensions specified in these OrderBys must be a subset of - Pivot.field_names. - offset (int): - The row count of the start row. The first row - is counted as row 0. - limit (int): - The number of rows to return in this pivot. - If unspecified, 10 rows are returned. If -1, all - rows are returned. - metric_aggregations (Sequence[google.analytics.data_v1alpha.types.MetricAggregation]): - Aggregate the metrics by dimensions in this pivot using the - specified metric_aggregations. + values (Sequence[str]): + The list of string values. + Must be non-empty. + case_sensitive (bool): + If true, the string value is case sensitive. """ - field_names = proto.RepeatedField( + values = proto.RepeatedField( proto.STRING, number=1, ) - order_bys = proto.RepeatedField( - proto.MESSAGE, + case_sensitive = proto.Field( + proto.BOOL, number=2, - message="OrderBy", - ) - offset = proto.Field( - proto.INT64, - number=3, - ) - limit = proto.Field( - proto.INT64, - number=4, - ) - metric_aggregations = proto.RepeatedField( - proto.ENUM, - number=5, - enum="MetricAggregation", ) -class CohortSpec(proto.Message): - r"""Specification of cohorts for a cohort report. Cohort reports can be - used for example to create a time series of user retention for the - cohort. For example, you could select the cohort of users that were - acquired in the first week of September and follow that cohort for - the next six weeks. Selecting the users acquired in the first week - of September cohort is specified in the ``cohort`` object. Following - that cohort for the next six weeks is specified in the - ``cohortsRange`` object. - - The report response could show a weekly time series where say your - app has retained 60% of this cohort after three weeks and 25% of - this cohort after six weeks. These two percentages can be calculated - by the metric ``cohortActiveUsers/cohortTotalUsers`` and will be - separate rows in the report. +class NumericFilter(proto.Message): + r"""Filters for numeric or date values. Attributes: - cohorts (Sequence[google.analytics.data_v1alpha.types.Cohort]): - Defines the selection criteria to group users - into cohorts. - Most cohort reports define only a single cohort. - If multiple cohorts are specified, each cohort - can be recognized in the report by their name. - cohorts_range (google.analytics.data_v1alpha.types.CohortsRange): - Cohort reports follow cohorts over an - extended reporting date range. This range - specifies an offset duration to follow the - cohorts over. - cohort_report_settings (google.analytics.data_v1alpha.types.CohortReportSettings): - Optional settings for a cohort report. + operation (google.analytics.data_v1alpha.types.NumericFilter.Operation): + The operation type for this filter. + value (google.analytics.data_v1alpha.types.NumericValue): + A numeric value or a date value. """ - cohorts = proto.RepeatedField( - proto.MESSAGE, + class Operation(proto.Enum): + r"""The operation applied to a numeric filter""" + OPERATION_UNSPECIFIED = 0 + EQUAL = 1 + LESS_THAN = 2 + LESS_THAN_OR_EQUAL = 3 + GREATER_THAN = 4 + GREATER_THAN_OR_EQUAL = 5 + + operation = proto.Field( + proto.ENUM, number=1, - message="Cohort", + enum=Operation, ) - cohorts_range = proto.Field( + value = proto.Field( proto.MESSAGE, number=2, - message="CohortsRange", - ) - cohort_report_settings = proto.Field( - proto.MESSAGE, - number=3, - message="CohortReportSettings", + message="NumericValue", ) -class Cohort(proto.Message): - r"""Defines a cohort selection criteria. A cohort is a group of users - who share a common characteristic. For example, users with the same - ``firstTouchDate`` belong to the same cohort. +class BetweenFilter(proto.Message): + r"""To express that the result needs to be between two numbers + (inclusive). Attributes: - name (str): - Assigns a name to this cohort. The dimension ``cohort`` is - valued to this name in a report response. If set, cannot - begin with ``cohort_`` or ``RESERVED_``. If not set, cohorts - are named by their zero based index ``cohort_0``, - ``cohort_1``, etc. - dimension (str): - Dimension used by the cohort. Required and only supports - ``firstTouchDate``. - date_range (google.analytics.data_v1alpha.types.DateRange): - The cohort selects users whose first touch date is between - start date and end date defined in the ``dateRange``. This - ``dateRange`` does not specify the full date range of event - data that is present in a cohort report. In a cohort report, - this ``dateRange`` is extended by the granularity and offset - present in the ``cohortsRange``; event data for the extended - reporting date range is present in a cohort report. - - In a cohort request, this ``dateRange`` is required and the - ``dateRanges`` in the ``RunReportRequest`` or - ``RunPivotReportRequest`` must be unspecified. - - This ``dateRange`` should generally be aligned with the - cohort's granularity. If ``CohortsRange`` uses daily - granularity, this ``dateRange`` can be a single day. If - ``CohortsRange`` uses weekly granularity, this ``dateRange`` - can be aligned to a week boundary, starting at Sunday and - ending Saturday. If ``CohortsRange`` uses monthly - granularity, this ``dateRange`` can be aligned to a month, - starting at the first and ending on the last day of the - month. + from_value (google.analytics.data_v1alpha.types.NumericValue): + Begins with this number. + to_value (google.analytics.data_v1alpha.types.NumericValue): + Ends with this number. """ - name = proto.Field( - proto.STRING, + from_value = proto.Field( + proto.MESSAGE, number=1, + message="NumericValue", ) - dimension = proto.Field( - proto.STRING, - number=2, - ) - date_range = proto.Field( + to_value = proto.Field( proto.MESSAGE, - number=3, - message="DateRange", + number=2, + message="NumericValue", ) -class CohortsRange(proto.Message): - r"""Configures the extended reporting date range for a cohort - report. Specifies an offset duration to follow the cohorts over. +class NumericValue(proto.Message): + r"""To represent a number. - Attributes: - granularity (google.analytics.data_v1alpha.types.CohortsRange.Granularity): - The granularity used to interpret the ``startOffset`` and - ``endOffset`` for the extended reporting date range for a - cohort report. - start_offset (int): - ``startOffset`` specifies the start date of the extended - reporting date range for a cohort report. ``startOffset`` is - commonly set to 0 so that reports contain data from the - acquisition of the cohort forward. - - If ``granularity`` is ``DAILY``, the ``startDate`` of the - extended reporting date range is ``startDate`` of the cohort - plus ``startOffset`` days. - - If ``granularity`` is ``WEEKLY``, the ``startDate`` of the - extended reporting date range is ``startDate`` of the cohort - plus ``startOffset * 7`` days. - - If ``granularity`` is ``MONTHLY``, the ``startDate`` of the - extended reporting date range is ``startDate`` of the cohort - plus ``startOffset * 30`` days. - end_offset (int): - ``endOffset`` specifies the end date of the extended - reporting date range for a cohort report. ``endOffset`` can - be any positive integer but is commonly set to 5 to 10 so - that reports contain data on the cohort for the next several - granularity time periods. - - If ``granularity`` is ``DAILY``, the ``endDate`` of the - extended reporting date range is ``endDate`` of the cohort - plus ``endOffset`` days. - - If ``granularity`` is ``WEEKLY``, the ``endDate`` of the - extended reporting date range is ``endDate`` of the cohort - plus ``endOffset * 7`` days. - - If ``granularity`` is ``MONTHLY``, the ``endDate`` of the - extended reporting date range is ``endDate`` of the cohort - plus ``endOffset * 30`` days. - """ + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. - class Granularity(proto.Enum): - r"""The granularity used to interpret the ``startOffset`` and - ``endOffset`` for the extended reporting date range for a cohort - report. - """ - GRANULARITY_UNSPECIFIED = 0 - DAILY = 1 - WEEKLY = 2 - MONTHLY = 3 + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields - granularity = proto.Field( - proto.ENUM, - number=1, - enum=Granularity, - ) - start_offset = proto.Field( - proto.INT32, - number=2, - ) - end_offset = proto.Field( - proto.INT32, - number=3, - ) + Attributes: + int64_value (int): + Integer value + This field is a member of `oneof`_ ``one_value``. + double_value (float): + Double value -class CohortReportSettings(proto.Message): - r"""Optional settings of a cohort report. - Attributes: - accumulate (bool): - If true, accumulates the result from first touch day to the - end day. Not supported in ``RunReportRequest``. + This field is a member of `oneof`_ ``one_value``. """ - accumulate = proto.Field( - proto.BOOL, + int64_value = proto.Field( + proto.INT64, number=1, + oneof="one_value", ) - - -class ResponseMetaData(proto.Message): - r"""Response's metadata carrying additional information about the - report content. - - Attributes: - data_loss_from_other_row (bool): - If true, indicates some buckets of dimension - combinations are rolled into "(other)" row. This - can happen for high cardinality reports. - """ - - data_loss_from_other_row = proto.Field( - proto.BOOL, - number=3, + double_value = proto.Field( + proto.DOUBLE, + number=2, + oneof="one_value", ) @@ -959,45 +657,6 @@ class MetricHeader(proto.Message): ) -class PivotHeader(proto.Message): - r"""Dimensions' values in a single pivot. - Attributes: - pivot_dimension_headers (Sequence[google.analytics.data_v1alpha.types.PivotDimensionHeader]): - The size is the same as the cardinality of - the corresponding dimension combinations. - row_count (int): - The cardinality of the pivot as if offset = 0 - and limit = -1. The total number of rows for - this pivot's fields regardless of how the - parameters offset and limit are specified in the - request. - """ - - pivot_dimension_headers = proto.RepeatedField( - proto.MESSAGE, - number=1, - message="PivotDimensionHeader", - ) - row_count = proto.Field( - proto.INT32, - number=2, - ) - - -class PivotDimensionHeader(proto.Message): - r"""Summarizes dimension values from a row for this pivot. - Attributes: - dimension_values (Sequence[google.analytics.data_v1alpha.types.DimensionValue]): - Values of multiple dimensions in a pivot. - """ - - dimension_values = proto.RepeatedField( - proto.MESSAGE, - number=1, - message="DimensionValue", - ) - - class Row(proto.Message): r"""Report data for each row. For example if RunReportRequest contains: @@ -1059,10 +718,15 @@ class Row(proto.Message): class DimensionValue(proto.Message): r"""The value of a dimension. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + Attributes: value (str): Value as a string if the dimension type is a string. + + This field is a member of `oneof`_ ``one_value``. """ value = proto.Field( @@ -1074,9 +738,14 @@ class DimensionValue(proto.Message): class MetricValue(proto.Message): r"""The value of a metric. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + Attributes: value (str): Measurement value. See MetricHeader for type. + + This field is a member of `oneof`_ ``one_value``. """ value = proto.Field( @@ -1086,32 +755,11 @@ class MetricValue(proto.Message): ) -class NumericValue(proto.Message): - r"""To represent a number. - Attributes: - int64_value (int): - Integer value - double_value (float): - Double value - """ - - int64_value = proto.Field( - proto.INT64, - number=1, - oneof="one_value", - ) - double_value = proto.Field( - proto.DOUBLE, - number=2, - oneof="one_value", - ) - - -class PropertyQuota(proto.Message): - r"""Current state of all quotas for this Analytics Property. If - any quota for a property is exhausted, all requests to that - property will return Resource Exhausted errors. - +class PropertyQuota(proto.Message): + r"""Current state of all quotas for this Analytics Property. If + any quota for a property is exhausted, all requests to that + property will return Resource Exhausted errors. + Attributes: tokens_per_day (google.analytics.data_v1alpha.types.QuotaStatus): Standard Analytics Properties can use up to @@ -1120,8 +768,8 @@ class PropertyQuota(proto.Message): consume fewer than 10 tokens. tokens_per_hour (google.analytics.data_v1alpha.types.QuotaStatus): Standard Analytics Properties can use up to - 5,000 tokens per day; Analytics 360 Properties - can use 50,000 tokens per day. An API request + 5,000 tokens per hour; Analytics 360 Properties + can use 50,000 tokens per hour. An API request consumes a single number of tokens, and that number is deducted from both the hourly and daily quotas. @@ -1135,6 +783,13 @@ class PropertyQuota(proto.Message): per hour; Analytics 360 Properties and cloud project pairs can have up to 50 server errors per hour. + potentially_thresholded_requests_per_hour (google.analytics.data_v1alpha.types.QuotaStatus): + Analytics Properties can send up to 120 + requests with potentially thresholded dimensions + per hour. In a batch request, each report + request is individually counted for this quota + if the request contains potentially thresholded + dimensions. """ tokens_per_day = proto.Field( @@ -1157,10 +812,16 @@ class PropertyQuota(proto.Message): number=4, message="QuotaStatus", ) + potentially_thresholded_requests_per_hour = proto.Field( + proto.MESSAGE, + number=5, + message="QuotaStatus", + ) class QuotaStatus(proto.Message): r"""Current state for a particular quota group. + Attributes: consumed (int): Quota consumed by this request. @@ -1178,110 +839,1561 @@ class QuotaStatus(proto.Message): ) -class DimensionMetadata(proto.Message): - r"""Explains a dimension. +class FunnelBreakdown(proto.Message): + r"""Breakdowns add a dimension to the funnel table sub report + response. + Attributes: - api_name (str): - This dimension's name. Useable in - `Dimension <#Dimension>`__'s ``name``. For example, - ``eventName``. - ui_name (str): - This dimension's name within the Google Analytics user - interface. For example, ``Event name``. - description (str): - Description of how this dimension is used and - calculated. - deprecated_api_names (Sequence[str]): - Still usable but deprecated names for this dimension. If - populated, this dimension is available by either ``apiName`` - or one of ``deprecatedApiNames`` for a period of time. After - the deprecation period, the dimension will be available only - by ``apiName``. - custom_definition (bool): - True if the dimension is a custom dimension - for this property. + breakdown_dimension (google.analytics.data_v1alpha.types.Dimension): + The dimension column added to the funnel table sub report + response. The breakdown dimension breaks down each funnel + step. A valid ``breakdownDimension`` is required if + ``funnelBreakdown`` is specified. + limit (int): + The maximum number of distinct values of the breakdown + dimension to return in the response. A ``limit`` of ``5`` is + used if limit is not specified. Limit must exceed zero and + cannot exceed 15. + + This field is a member of `oneof`_ ``_limit``. """ - api_name = proto.Field( - proto.STRING, + breakdown_dimension = proto.Field( + proto.MESSAGE, number=1, + message="Dimension", ) - ui_name = proto.Field( - proto.STRING, + limit = proto.Field( + proto.INT64, number=2, + optional=True, ) - description = proto.Field( - proto.STRING, - number=3, + + +class FunnelNextAction(proto.Message): + r"""Next actions state the value for a dimension after the user has + achieved a step but before the same user has achieved the next step. + For example if the ``nextActionDimension`` is ``eventName``, then + ``nextActionDimension`` in the ``i``\ th funnel step row will return + first event after the event that qualified the user into the + ``i``\ th funnel step but before the user achieved the ``i+1``\ th + funnel step. + + Attributes: + next_action_dimension (google.analytics.data_v1alpha.types.Dimension): + The dimension column added to the funnel visualization sub + report response. The next action dimension returns the next + dimension value of this dimension after the user has + attained the ``i``\ th funnel step. ``nextActionDimension`` + currently only supports the ``eventName`` dimension. + limit (int): + The maximum number of distinct values of the breakdown + dimension to return in the response. A ``limit`` of ``5`` is + used if limit is not specified. Limit must exceed zero and + cannot exceed 5. + + This field is a member of `oneof`_ ``_limit``. + """ + + next_action_dimension = proto.Field( + proto.MESSAGE, + number=1, + message="Dimension", ) - deprecated_api_names = proto.RepeatedField( - proto.STRING, - number=4, + limit = proto.Field( + proto.INT64, + number=2, + optional=True, ) - custom_definition = proto.Field( + + +class Funnel(proto.Message): + r"""Configures the funnel in a funnel report request. A funnel + reports on users as they pass through a sequence of steps. + Funnel exploration lets you visualize the steps your users take + to complete a task and quickly see how well they are succeeding + or failing at each step. For example, how do prospects become + shoppers and then become buyers? How do one time buyers become + repeat buyers? With this information, you can improve + inefficient or abandoned customer journeys. + + Attributes: + is_open_funnel (bool): + In an open funnel, users can enter the funnel + in any step, and in a closed funnel, users must + enter the funnel in the first step. Optional. If + unspecified, a closed funnel is used. + steps (Sequence[google.analytics.data_v1alpha.types.FunnelStep]): + The sequential steps of this funnel. + """ + + is_open_funnel = proto.Field( proto.BOOL, - number=5, + number=1, + ) + steps = proto.RepeatedField( + proto.MESSAGE, + number=2, + message="FunnelStep", ) -class MetricMetadata(proto.Message): - r"""Explains a metric. +class FunnelStep(proto.Message): + r"""Steps define the user journey you want to measure. Steps + contain one or more conditions that your users must meet to be + included in that step of the funnel journey. + Attributes: - api_name (str): - A metric name. Useable in `Metric <#Metric>`__'s ``name``. - For example, ``eventCount``. - ui_name (str): - This metric's name within the Google Analytics user - interface. For example, ``Event count``. - description (str): - Description of how this metric is used and - calculated. - deprecated_api_names (Sequence[str]): - Still usable but deprecated names for this metric. If - populated, this metric is available by either ``apiName`` or - one of ``deprecatedApiNames`` for a period of time. After - the deprecation period, the metric will be available only by - ``apiName``. - type_ (google.analytics.data_v1alpha.types.MetricType): - The type of this metric. - expression (str): - The mathematical expression for this derived metric. Can be - used in `Metric <#Metric>`__'s ``expression`` field for - equivalent reports. Most metrics are not expressions, and - for non-expressions, this field is empty. - custom_definition (bool): - True if the metric is a custom metric for - this property. + name (str): + The distinctive name for this step. If unspecified, steps + will be named by a 1 based indexed name (i.e. "0. ", "1. ", + etc.). This name defines string value returned by the + ``funnelStepName`` dimension. For example, specifying + ``name = Purchase`` in the request's third funnel step will + produce ``3. Purchase`` in the funnel report response. + is_directly_followed_by (bool): + If true, this step must directly follow the previous step. + If false, there can be events between the previous step and + this step. If unspecified, ``isDirectlyFollowedBy`` is + treated as false. + within_duration_from_prior_step (google.protobuf.duration_pb2.Duration): + If specified, this step must complete within this duration + of the completion of the prior step. + ``withinDurationFromPriorStep`` is inclusive of the endpoint + at the microsecond granularity. For example a duration of 5 + seconds can be completed at 4.9 or 5.0 seconds, but not 5 + seconds and 1 microsecond. + + ``withinDurationFromPriorStep`` is optional, and if + unspecified, steps may be separated by any time duration. + + This field is a member of `oneof`_ ``_within_duration_from_prior_step``. + filter_expression (google.analytics.data_v1alpha.types.FunnelFilterExpression): + The condition that your users must meet to be + included in this step of the funnel journey. """ - api_name = proto.Field( + name = proto.Field( proto.STRING, number=1, ) - ui_name = proto.Field( - proto.STRING, + is_directly_followed_by = proto.Field( + proto.BOOL, number=2, ) - description = proto.Field( - proto.STRING, + within_duration_from_prior_step = proto.Field( + proto.MESSAGE, number=3, + optional=True, + message=duration_pb2.Duration, ) - deprecated_api_names = proto.RepeatedField( - proto.STRING, + filter_expression = proto.Field( + proto.MESSAGE, number=4, + message="FunnelFilterExpression", ) - type_ = proto.Field( + + +class FunnelSubReport(proto.Message): + r"""Funnel sub reports contain the dimension and metric data + values. For example, 12 users reached the second step of the + funnel. + + Attributes: + dimension_headers (Sequence[google.analytics.data_v1alpha.types.DimensionHeader]): + Describes dimension columns. Funnel reports + always include the funnel step dimension in sub + report responses. Additional dimensions like + breakdowns, dates, and next actions may be + present in the response if requested. + metric_headers (Sequence[google.analytics.data_v1alpha.types.MetricHeader]): + Describes metric columns. Funnel reports + always include active users in sub report + responses. The funnel table includes additional + metrics like completion rate, abandonments, and + abandonments rate. + rows (Sequence[google.analytics.data_v1alpha.types.Row]): + Rows of dimension value combinations and + metric values in the report. + metadata (google.analytics.data_v1alpha.types.FunnelResponseMetadata): + Metadata for the funnel report. + """ + + dimension_headers = proto.RepeatedField( + proto.MESSAGE, + number=1, + message="DimensionHeader", + ) + metric_headers = proto.RepeatedField( + proto.MESSAGE, + number=2, + message="MetricHeader", + ) + rows = proto.RepeatedField( + proto.MESSAGE, + number=3, + message="Row", + ) + metadata = proto.Field( + proto.MESSAGE, + number=4, + message="FunnelResponseMetadata", + ) + + +class UserSegment(proto.Message): + r"""User segments are subsets of users who engaged with your site + or app. For example, users who have previously purchased; users + who added items to their shopping carts, but didn’t complete a + purchase. + + Attributes: + user_inclusion_criteria (google.analytics.data_v1alpha.types.UserSegmentCriteria): + Defines which users are included in this + segment. Optional. + exclusion (google.analytics.data_v1alpha.types.UserSegmentExclusion): + Defines which users are excluded in this + segment. Optional. + """ + + user_inclusion_criteria = proto.Field( + proto.MESSAGE, + number=1, + message="UserSegmentCriteria", + ) + exclusion = proto.Field( + proto.MESSAGE, + number=2, + message="UserSegmentExclusion", + ) + + +class UserSegmentCriteria(proto.Message): + r"""A user matches a criteria if the user's events meet the + conditions in the criteria. + + Attributes: + and_condition_groups (Sequence[google.analytics.data_v1alpha.types.UserSegmentConditionGroup]): + A user matches this criteria if the user matches each of + these ``andConditionGroups`` and each of the + ``andSequenceGroups``. ``andConditionGroups`` may be empty + if ``andSequenceGroups`` are specified. + and_sequence_groups (Sequence[google.analytics.data_v1alpha.types.UserSegmentSequenceGroup]): + A user matches this criteria if the user matches each of + these ``andSequenceGroups`` and each of the + ``andConditionGroups``. ``andSequenceGroups`` may be empty + if ``andConditionGroups`` are specified. + """ + + and_condition_groups = proto.RepeatedField( + proto.MESSAGE, + number=1, + message="UserSegmentConditionGroup", + ) + and_sequence_groups = proto.RepeatedField( + proto.MESSAGE, + number=2, + message="UserSegmentSequenceGroup", + ) + + +class UserSegmentConditionGroup(proto.Message): + r"""Conditions tell Analytics what data to include in or exclude + from the segment. + + Attributes: + condition_scoping (google.analytics.data_v1alpha.types.UserCriteriaScoping): + Data is included or excluded from the segment based on if it + matches the condition group. This scoping defines how many + events the ``segmentFilterExpression`` is evaluated on + before the condition group is determined to be matched or + not. For example if + ``conditionScoping = USER_CRITERIA_WITHIN_SAME_SESSION``, + the expression is evaluated on all events in a session, and + then, the condition group is determined to be matched or not + for this user. For example if + ``conditionScoping = USER_CRITERIA_WITHIN_SAME_EVENT``, the + expression is evaluated on a single event, and then, the + condition group is determined to be matched or not for this + user. + + Optional. If unspecified, + ``conditionScoping = ACROSS_ALL_SESSIONS`` is used. + segment_filter_expression (google.analytics.data_v1alpha.types.SegmentFilterExpression): + Data is included or excluded from the segment + based on if it matches this expression. + Expressions express criteria on dimension, + metrics, and/or parameters. + """ + + condition_scoping = proto.Field( proto.ENUM, - number=5, - enum="MetricType", + number=1, + enum="UserCriteriaScoping", ) - expression = proto.Field( - proto.STRING, - number=6, + segment_filter_expression = proto.Field( + proto.MESSAGE, + number=2, + message="SegmentFilterExpression", ) - custom_definition = proto.Field( + + +class UserSegmentSequenceGroup(proto.Message): + r"""Define conditions that must occur in a specific order for the + user to be a member of the segment. + + Attributes: + sequence_scoping (google.analytics.data_v1alpha.types.UserCriteriaScoping): + All sequence steps must be satisfied in the scoping for the + user to match the sequence. For example if + ``sequenceScoping = USER_CRITERIA_WITHIN_SAME_SESSION``, all + sequence steps must complete within one session for the user + to match the sequence. + ``sequenceScoping = USER_CRITERIA_WITHIN_SAME_EVENT`` is not + supported. + + Optional. If unspecified, + ``conditionScoping = ACROSS_ALL_SESSIONS`` is used. + sequence_maximum_duration (google.protobuf.duration_pb2.Duration): + Defines the time period in which the whole sequence must + occur; for example, 30 Minutes. ``sequenceMaximumDuration`` + is inclusive of the endpoint at the microsecond granularity. + For example a sequence with a maximum duration of 5 seconds + can be completed at 4.9 or 5.0 seconds, but not 5 seconds + and 1 microsecond. + + ``sequenceMaximumDuration`` is optional, and if unspecified, + sequences can be completed in any time duration. + user_sequence_steps (Sequence[google.analytics.data_v1alpha.types.UserSequenceStep]): + An ordered sequence of condition steps. A user's events must + complete each step in order for the user to match the + ``UserSegmentSequenceGroup``. + """ + + sequence_scoping = proto.Field( + proto.ENUM, + number=1, + enum="UserCriteriaScoping", + ) + sequence_maximum_duration = proto.Field( + proto.MESSAGE, + number=2, + message=duration_pb2.Duration, + ) + user_sequence_steps = proto.RepeatedField( + proto.MESSAGE, + number=3, + message="UserSequenceStep", + ) + + +class UserSequenceStep(proto.Message): + r"""A condition that must occur in the specified step order for + this user to match the sequence. + + Attributes: + is_directly_followed_by (bool): + If true, the event satisfying this step must be the very + next event after the event satifying the last step. If + false, this step indirectly follows the prior step; for + example, there may be events between the prior step and this + step. ``isDirectlyFollowedBy`` must be false for the first + step. + step_scoping (google.analytics.data_v1alpha.types.UserCriteriaScoping): + This sequence step must be satisfied in the scoping for the + user to match the sequence. For example if + ``sequenceScoping = WITHIN_SAME_SESSION``, this sequence + steps must complete within one session for the user to match + the sequence. ``stepScoping = ACROSS_ALL_SESSIONS`` is only + allowed if the ``sequenceScoping = ACROSS_ALL_SESSIONS``. + + Optional. If unspecified, ``stepScoping`` uses the same + ``UserCriteriaScoping`` as the ``sequenceScoping``. + segment_filter_expression (google.analytics.data_v1alpha.types.SegmentFilterExpression): + A user matches this sequence step if their + events match this expression. Expressions + express criteria on dimension, metrics, and/or + parameters. + """ + + is_directly_followed_by = proto.Field( proto.BOOL, - number=7, + number=1, + ) + step_scoping = proto.Field( + proto.ENUM, + number=2, + enum="UserCriteriaScoping", + ) + segment_filter_expression = proto.Field( + proto.MESSAGE, + number=3, + message="SegmentFilterExpression", + ) + + +class UserSegmentExclusion(proto.Message): + r"""Specifies which users are excluded in this segment. + + Attributes: + user_exclusion_duration (google.analytics.data_v1alpha.types.UserExclusionDuration): + Specifies how long an exclusion will last if a user matches + the ``userExclusionCriteria``. + + Optional. If unspecified, ``userExclusionDuration`` of + ``USER_EXCLUSION_TEMPORARY`` is used. + user_exclusion_criteria (google.analytics.data_v1alpha.types.UserSegmentCriteria): + If a user meets this condition, the user is excluded from + membership in the segment for the ``userExclusionDuration``. + """ + + user_exclusion_duration = proto.Field( + proto.ENUM, + number=1, + enum="UserExclusionDuration", + ) + user_exclusion_criteria = proto.Field( + proto.MESSAGE, + number=2, + message="UserSegmentCriteria", + ) + + +class SessionSegment(proto.Message): + r"""Session segments are subsets of the sessions that occurred on + your site or app: for example, all the sessions that originated + from a particular advertising campaign. + + Attributes: + session_inclusion_criteria (google.analytics.data_v1alpha.types.SessionSegmentCriteria): + Defines which sessions are included in this + segment. Optional. + exclusion (google.analytics.data_v1alpha.types.SessionSegmentExclusion): + Defines which sessions are excluded in this + segment. Optional. + """ + + session_inclusion_criteria = proto.Field( + proto.MESSAGE, + number=1, + message="SessionSegmentCriteria", + ) + exclusion = proto.Field( + proto.MESSAGE, + number=2, + message="SessionSegmentExclusion", + ) + + +class SessionSegmentCriteria(proto.Message): + r"""A session matches a criteria if the session's events meet the + conditions in the criteria. + + Attributes: + and_condition_groups (Sequence[google.analytics.data_v1alpha.types.SessionSegmentConditionGroup]): + A session matches this criteria if the session matches each + of these ``andConditionGroups``. + """ + + and_condition_groups = proto.RepeatedField( + proto.MESSAGE, + number=1, + message="SessionSegmentConditionGroup", + ) + + +class SessionSegmentConditionGroup(proto.Message): + r"""Conditions tell Analytics what data to include in or exclude + from the segment. + + Attributes: + condition_scoping (google.analytics.data_v1alpha.types.SessionCriteriaScoping): + Data is included or excluded from the segment based on if it + matches the condition group. This scoping defines how many + events the ``segmentFilterExpression`` is evaluated on + before the condition group is determined to be matched or + not. For example if + ``conditionScoping = SESSION_CRITERIA_WITHIN_SAME_SESSION``, + the expression is evaluated on all events in a session, and + then, the condition group is determined to be matched or not + for this session. For example if + ``conditionScoping = SESSION_CRITERIA_WITHIN_SAME_EVENT``, + the expression is evaluated on a single event, and then, the + condition group is determined to be matched or not for this + session. + + Optional. If unspecified, a ``conditionScoping`` of + ``WITHIN_SAME_SESSION`` is used. + segment_filter_expression (google.analytics.data_v1alpha.types.SegmentFilterExpression): + Data is included or excluded from the segment + based on if it matches this expression. + Expressions express criteria on dimension, + metrics, and/or parameters. + """ + + condition_scoping = proto.Field( + proto.ENUM, + number=1, + enum="SessionCriteriaScoping", + ) + segment_filter_expression = proto.Field( + proto.MESSAGE, + number=2, + message="SegmentFilterExpression", + ) + + +class SessionSegmentExclusion(proto.Message): + r"""Specifies which sessions are excluded in this segment. + + Attributes: + session_exclusion_duration (google.analytics.data_v1alpha.types.SessionExclusionDuration): + Specifies how long an exclusion will last if a session + matches the ``sessionExclusionCriteria``. + + Optional. If unspecified, a ``sessionExclusionDuration`` of + ``SESSION_EXCLUSION_TEMPORARY`` is used. + session_exclusion_criteria (google.analytics.data_v1alpha.types.SessionSegmentCriteria): + If a session meets this condition, the session is excluded + from membership in the segment for the + ``sessionExclusionDuration``. + """ + + session_exclusion_duration = proto.Field( + proto.ENUM, + number=1, + enum="SessionExclusionDuration", + ) + session_exclusion_criteria = proto.Field( + proto.MESSAGE, + number=2, + message="SessionSegmentCriteria", + ) + + +class EventSegment(proto.Message): + r"""Event segments are subsets of events that were triggered on your + site or app. for example, all purchase events made in a particular + location; app_exception events that occurred on a specific operating + system. + + Attributes: + event_inclusion_criteria (google.analytics.data_v1alpha.types.EventSegmentCriteria): + Defines which events are included in this + segment. Optional. + exclusion (google.analytics.data_v1alpha.types.EventSegmentExclusion): + Defines which events are excluded in this + segment. Optional. + """ + + event_inclusion_criteria = proto.Field( + proto.MESSAGE, + number=1, + message="EventSegmentCriteria", + ) + exclusion = proto.Field( + proto.MESSAGE, + number=2, + message="EventSegmentExclusion", + ) + + +class EventSegmentCriteria(proto.Message): + r"""An event matches a criteria if the event meet the conditions + in the criteria. + + Attributes: + and_condition_groups (Sequence[google.analytics.data_v1alpha.types.EventSegmentConditionGroup]): + An event matches this criteria if the event matches each of + these ``andConditionGroups``. + """ + + and_condition_groups = proto.RepeatedField( + proto.MESSAGE, + number=1, + message="EventSegmentConditionGroup", + ) + + +class EventSegmentConditionGroup(proto.Message): + r"""Conditions tell Analytics what data to include in or exclude + from the segment. + + Attributes: + condition_scoping (google.analytics.data_v1alpha.types.EventCriteriaScoping): + ``conditionScoping`` should always be + ``EVENT_CRITERIA_WITHIN_SAME_EVENT``. + + Optional. If unspecified, a ``conditionScoping`` of + ``EVENT_CRITERIA_WITHIN_SAME_EVENT`` is used. + segment_filter_expression (google.analytics.data_v1alpha.types.SegmentFilterExpression): + Data is included or excluded from the segment + based on if it matches this expression. + Expressions express criteria on dimension, + metrics, and/or parameters. + """ + + condition_scoping = proto.Field( + proto.ENUM, + number=1, + enum="EventCriteriaScoping", + ) + segment_filter_expression = proto.Field( + proto.MESSAGE, + number=2, + message="SegmentFilterExpression", + ) + + +class EventSegmentExclusion(proto.Message): + r"""Specifies which events are excluded in this segment. + + Attributes: + event_exclusion_duration (google.analytics.data_v1alpha.types.EventExclusionDuration): + ``eventExclusionDuration`` should always be + ``PERMANENTLY_EXCLUDE``. + + Optional. If unspecified, an ``eventExclusionDuration`` of + ``EVENT_EXCLUSION_PERMANENT`` is used. + event_exclusion_criteria (google.analytics.data_v1alpha.types.EventSegmentCriteria): + If an event meets this condition, the event is excluded from + membership in the segment for the + ``eventExclusionDuration``. + """ + + event_exclusion_duration = proto.Field( + proto.ENUM, + number=1, + enum="EventExclusionDuration", + ) + event_exclusion_criteria = proto.Field( + proto.MESSAGE, + number=2, + message="EventSegmentCriteria", + ) + + +class Segment(proto.Message): + r"""A segment is a subset of your Analytics data. For example, of your + entire set of users, one segment might be users from a particular + country or city. Another segment might be users who purchase a + particular line of products or who visit a specific part of your + site or trigger certain events in your app. + + To learn more, see `GA4 Segment + Builder `__. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + name (str): + The name for this segment. If unspecified, segments are + named "Segment". This name defines string value returned by + the ``segment`` dimension. The ``segment`` dimension + prefixes segment names by the 1-based index number of the + segment in the request (i.e. "1. Segment", "2. Segment", + etc.). + user_segment (google.analytics.data_v1alpha.types.UserSegment): + User segments are subsets of users who + engaged with your site or app. + + This field is a member of `oneof`_ ``one_segment_scope``. + session_segment (google.analytics.data_v1alpha.types.SessionSegment): + Session segments are subsets of the sessions + that occurred on your site or app. + + This field is a member of `oneof`_ ``one_segment_scope``. + event_segment (google.analytics.data_v1alpha.types.EventSegment): + Event segments are subsets of events that + were triggered on your site or app. + + This field is a member of `oneof`_ ``one_segment_scope``. + """ + + name = proto.Field( + proto.STRING, + number=1, + ) + user_segment = proto.Field( + proto.MESSAGE, + number=2, + oneof="one_segment_scope", + message="UserSegment", + ) + session_segment = proto.Field( + proto.MESSAGE, + number=3, + oneof="one_segment_scope", + message="SessionSegment", + ) + event_segment = proto.Field( + proto.MESSAGE, + number=4, + oneof="one_segment_scope", + message="EventSegment", + ) + + +class SegmentFilterExpression(proto.Message): + r"""Expresses combinations of segment filters. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + and_group (google.analytics.data_v1alpha.types.SegmentFilterExpressionList): + The SegmentFilterExpression in ``andGroup`` have an AND + relationship. + + This field is a member of `oneof`_ ``expr``. + or_group (google.analytics.data_v1alpha.types.SegmentFilterExpressionList): + The SegmentFilterExpression in ``orGroup`` have an OR + relationship. + + This field is a member of `oneof`_ ``expr``. + not_expression (google.analytics.data_v1alpha.types.SegmentFilterExpression): + The SegmentFilterExpression is NOT of ``notExpression``. + + This field is a member of `oneof`_ ``expr``. + segment_filter (google.analytics.data_v1alpha.types.SegmentFilter): + A primitive segment filter. + + This field is a member of `oneof`_ ``expr``. + segment_event_filter (google.analytics.data_v1alpha.types.SegmentEventFilter): + Creates a filter that matches events of a + single event name. If a parameter filter + expression is specified, only the subset of + events that match both the single event name and + the parameter filter expressions match this + event filter. + + This field is a member of `oneof`_ ``expr``. + """ + + and_group = proto.Field( + proto.MESSAGE, + number=1, + oneof="expr", + message="SegmentFilterExpressionList", + ) + or_group = proto.Field( + proto.MESSAGE, + number=2, + oneof="expr", + message="SegmentFilterExpressionList", + ) + not_expression = proto.Field( + proto.MESSAGE, + number=3, + oneof="expr", + message="SegmentFilterExpression", + ) + segment_filter = proto.Field( + proto.MESSAGE, + number=4, + oneof="expr", + message="SegmentFilter", + ) + segment_event_filter = proto.Field( + proto.MESSAGE, + number=5, + oneof="expr", + message="SegmentEventFilter", + ) + + +class SegmentFilterExpressionList(proto.Message): + r"""A list of segment filter expressions. + + Attributes: + expressions (Sequence[google.analytics.data_v1alpha.types.SegmentFilterExpression]): + The list of segment filter expressions + """ + + expressions = proto.RepeatedField( + proto.MESSAGE, + number=1, + message="SegmentFilterExpression", + ) + + +class SegmentFilter(proto.Message): + r"""An expression to filter dimension or metric values. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + field_name (str): + The dimension name or metric name. + string_filter (google.analytics.data_v1alpha.types.StringFilter): + Strings related filter. + + This field is a member of `oneof`_ ``one_filter``. + in_list_filter (google.analytics.data_v1alpha.types.InListFilter): + A filter for in list values. + + This field is a member of `oneof`_ ``one_filter``. + numeric_filter (google.analytics.data_v1alpha.types.NumericFilter): + A filter for numeric or date values. + + This field is a member of `oneof`_ ``one_filter``. + between_filter (google.analytics.data_v1alpha.types.BetweenFilter): + A filter for between two values. + + This field is a member of `oneof`_ ``one_filter``. + filter_scoping (google.analytics.data_v1alpha.types.SegmentFilterScoping): + Specifies the scope for the filter. + """ + + field_name = proto.Field( + proto.STRING, + number=1, + ) + string_filter = proto.Field( + proto.MESSAGE, + number=4, + oneof="one_filter", + message="StringFilter", + ) + in_list_filter = proto.Field( + proto.MESSAGE, + number=5, + oneof="one_filter", + message="InListFilter", + ) + numeric_filter = proto.Field( + proto.MESSAGE, + number=6, + oneof="one_filter", + message="NumericFilter", + ) + between_filter = proto.Field( + proto.MESSAGE, + number=7, + oneof="one_filter", + message="BetweenFilter", + ) + filter_scoping = proto.Field( + proto.MESSAGE, + number=8, + message="SegmentFilterScoping", + ) + + +class SegmentFilterScoping(proto.Message): + r"""Scopings specify how the dimensions & metrics of multiple + events should be considered when evaluating a segment filter. + + Attributes: + at_any_point_in_time (bool): + If ``atAnyPointInTime`` is true, this filter evaluates to + true for all events if it evaluates to true for any event in + the date range of the request. + + This ``atAnyPointInTime`` parameter does not extend the date + range of events in the report. If ``atAnyPointInTime`` is + true, only events within the report's date range are + considered when evaluating this filter. + + This ``atAnyPointInTime`` is only able to be specified if + the criteria scoping is ``ACROSS_ALL_SESSIONS`` and is not + able to be specified in sequences. + + If the criteria scoping is ``ACROSS_ALL_SESSIONS``, + ``atAnyPointInTime`` = false is used if unspecified. + + This field is a member of `oneof`_ ``_at_any_point_in_time``. + """ + + at_any_point_in_time = proto.Field( + proto.BOOL, + number=1, + optional=True, + ) + + +class SegmentEventFilter(proto.Message): + r"""Creates a filter that matches events of a single event name. + If a parameter filter expression is specified, only the subset + of events that match both the single event name and the + parameter filter expressions match this event filter. + + Attributes: + event_name (str): + This filter matches events of this single + event name. Event name is required. + + This field is a member of `oneof`_ ``_event_name``. + segment_parameter_filter_expression (google.analytics.data_v1alpha.types.SegmentParameterFilterExpression): + If specified, this filter matches events that + match both the single event name and the + parameter filter expressions. + Inside the parameter filter expression, only + parameter filters are available. + + This field is a member of `oneof`_ ``_segment_parameter_filter_expression``. + """ + + event_name = proto.Field( + proto.STRING, + number=1, + optional=True, + ) + segment_parameter_filter_expression = proto.Field( + proto.MESSAGE, + number=2, + optional=True, + message="SegmentParameterFilterExpression", + ) + + +class SegmentParameterFilterExpression(proto.Message): + r"""Expresses combinations of segment filter on parameters. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + and_group (google.analytics.data_v1alpha.types.SegmentParameterFilterExpressionList): + The SegmentParameterFilterExpression in ``andGroup`` have an + AND relationship. + + This field is a member of `oneof`_ ``expr``. + or_group (google.analytics.data_v1alpha.types.SegmentParameterFilterExpressionList): + The SegmentParameterFilterExpression in ``orGroup`` have an + OR relationship. + + This field is a member of `oneof`_ ``expr``. + not_expression (google.analytics.data_v1alpha.types.SegmentParameterFilterExpression): + The SegmentParameterFilterExpression is NOT of + ``notExpression``. + + This field is a member of `oneof`_ ``expr``. + segment_parameter_filter (google.analytics.data_v1alpha.types.SegmentParameterFilter): + A primitive segment parameter filter. + + This field is a member of `oneof`_ ``expr``. + """ + + and_group = proto.Field( + proto.MESSAGE, + number=1, + oneof="expr", + message="SegmentParameterFilterExpressionList", + ) + or_group = proto.Field( + proto.MESSAGE, + number=2, + oneof="expr", + message="SegmentParameterFilterExpressionList", + ) + not_expression = proto.Field( + proto.MESSAGE, + number=3, + oneof="expr", + message="SegmentParameterFilterExpression", + ) + segment_parameter_filter = proto.Field( + proto.MESSAGE, + number=4, + oneof="expr", + message="SegmentParameterFilter", + ) + + +class SegmentParameterFilterExpressionList(proto.Message): + r"""A list of segment parameter filter expressions. + + Attributes: + expressions (Sequence[google.analytics.data_v1alpha.types.SegmentParameterFilterExpression]): + The list of segment parameter filter + expressions. + """ + + expressions = proto.RepeatedField( + proto.MESSAGE, + number=1, + message="SegmentParameterFilterExpression", + ) + + +class SegmentParameterFilter(proto.Message): + r"""An expression to filter parameter values in a segment. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + event_parameter_name (str): + This filter will be evaluated on the specified event + parameter. Event parameters are logged as parameters of the + event. Event parameters include fields like + "firebase_screen" & "currency". + + Event parameters can only be used in segments & funnels and + can only be used in a descendent filter from an EventFilter. + In a descendent filter from an EventFilter either event or + item parameters should be used. + + This field is a member of `oneof`_ ``one_parameter``. + item_parameter_name (str): + This filter will be evaluated on the specified item + parameter. Item parameters are logged as parameters in the + item array. Item parameters include fields like "item_name" + & "item_category". + + Item parameters can only be used in segments & funnels and + can only be used in a descendent filter from an EventFilter. + In a descendent filter from an EventFilter either event or + item parameters should be used. + + Item parameters are only available in ecommerce events. To + learn more about ecommerce events, see the [Measure + ecommerce] + (https://developers.google.com/analytics/devguides/collection/ga4/ecommerce) + guide. + + This field is a member of `oneof`_ ``one_parameter``. + string_filter (google.analytics.data_v1alpha.types.StringFilter): + Strings related filter. + + This field is a member of `oneof`_ ``one_filter``. + in_list_filter (google.analytics.data_v1alpha.types.InListFilter): + A filter for in list values. + + This field is a member of `oneof`_ ``one_filter``. + numeric_filter (google.analytics.data_v1alpha.types.NumericFilter): + A filter for numeric or date values. + + This field is a member of `oneof`_ ``one_filter``. + between_filter (google.analytics.data_v1alpha.types.BetweenFilter): + A filter for between two values. + + This field is a member of `oneof`_ ``one_filter``. + filter_scoping (google.analytics.data_v1alpha.types.SegmentParameterFilterScoping): + Specifies the scope for the filter. + """ + + event_parameter_name = proto.Field( + proto.STRING, + number=1, + oneof="one_parameter", + ) + item_parameter_name = proto.Field( + proto.STRING, + number=2, + oneof="one_parameter", + ) + string_filter = proto.Field( + proto.MESSAGE, + number=4, + oneof="one_filter", + message="StringFilter", + ) + in_list_filter = proto.Field( + proto.MESSAGE, + number=5, + oneof="one_filter", + message="InListFilter", + ) + numeric_filter = proto.Field( + proto.MESSAGE, + number=6, + oneof="one_filter", + message="NumericFilter", + ) + between_filter = proto.Field( + proto.MESSAGE, + number=7, + oneof="one_filter", + message="BetweenFilter", + ) + filter_scoping = proto.Field( + proto.MESSAGE, + number=8, + message="SegmentParameterFilterScoping", + ) + + +class SegmentParameterFilterScoping(proto.Message): + r"""Scopings specify how multiple events should be considered + when evaluating a segment parameter filter. + + Attributes: + in_any_n_day_period (int): + Accumulates the parameter over the specified period of days + before applying the filter. Only supported if criteria + scoping is ``ACROSS_ALL_SESSIONS`` or + ``WITHIN_SAME_SESSION``. Only supported if the parameter is + ``event_count``. + + For example if ``inAnyNDayPeriod`` is 3, the event_name is + "purchase", the event parameter is "event_count", and the + Filter's criteria is greater than 5, this filter will + accumulate the event count of purchase events over every 3 + consecutive day period in the report's date range; a user + will pass this Filter's criteria to be included in this + segment if their count of purchase events exceeds 5 in any 3 + consecutive day period. For example, the periods 2021-11-01 + to 2021-11-03, 2021-11-02 to 2021-11-04, 2021-11-03 to + 2021-11-05, and etc. will be considered. + + The date range is not extended for the purpose of having a + full N day window near the start of the date range. For + example if a report is for 2021-11-01 to 2021-11-10 and + ``inAnyNDayPeriod`` = 3, the first two day period will be + effectively shortened because no event data outside the + report's date range will be read. For example, the first + four periods will effectively be: 2021-11-01 to 2021-11-01, + 2021-11-01 to 2021-11-02, 2021-11-01 to 2021-11-03, and + 2021-11-02 to 2021-11-04. + + ``inAnyNDayPeriod`` is optional. If not specified, the + ``segmentParameterFilter`` is applied to each event + individually. + + This field is a member of `oneof`_ ``_in_any_n_day_period``. + """ + + in_any_n_day_period = proto.Field( + proto.INT64, + number=1, + optional=True, + ) + + +class FunnelFilterExpression(proto.Message): + r"""Expresses combinations of funnel filters. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + and_group (google.analytics.data_v1alpha.types.FunnelFilterExpressionList): + The FunnelFilterExpression in ``andGroup`` have an AND + relationship. + + This field is a member of `oneof`_ ``expr``. + or_group (google.analytics.data_v1alpha.types.FunnelFilterExpressionList): + The FunnelFilterExpression in ``orGroup`` have an OR + relationship. + + This field is a member of `oneof`_ ``expr``. + not_expression (google.analytics.data_v1alpha.types.FunnelFilterExpression): + The FunnelFilterExpression is NOT of ``notExpression``. + + This field is a member of `oneof`_ ``expr``. + funnel_filter (google.analytics.data_v1alpha.types.FunnelFilter): + A primitive funnel filter. + + This field is a member of `oneof`_ ``expr``. + funnel_event_filter (google.analytics.data_v1alpha.types.FunnelEventFilter): + Creates a filter that matches events of a + single event name. If a parameter filter + expression is specified, only the subset of + events that match both the single event name and + the parameter filter expressions match this + event filter. + + This field is a member of `oneof`_ ``expr``. + """ + + and_group = proto.Field( + proto.MESSAGE, + number=1, + oneof="expr", + message="FunnelFilterExpressionList", + ) + or_group = proto.Field( + proto.MESSAGE, + number=2, + oneof="expr", + message="FunnelFilterExpressionList", + ) + not_expression = proto.Field( + proto.MESSAGE, + number=3, + oneof="expr", + message="FunnelFilterExpression", + ) + funnel_filter = proto.Field( + proto.MESSAGE, + number=4, + oneof="expr", + message="FunnelFilter", + ) + funnel_event_filter = proto.Field( + proto.MESSAGE, + number=5, + oneof="expr", + message="FunnelEventFilter", + ) + + +class FunnelFilterExpressionList(proto.Message): + r"""A list of funnel filter expressions. + + Attributes: + expressions (Sequence[google.analytics.data_v1alpha.types.FunnelFilterExpression]): + The list of funnel filter expressions. + """ + + expressions = proto.RepeatedField( + proto.MESSAGE, + number=1, + message="FunnelFilterExpression", + ) + + +class FunnelFilter(proto.Message): + r"""An expression to filter dimension or metric values. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + field_name (str): + The dimension name or metric name. + string_filter (google.analytics.data_v1alpha.types.StringFilter): + Strings related filter. + + This field is a member of `oneof`_ ``one_filter``. + in_list_filter (google.analytics.data_v1alpha.types.InListFilter): + A filter for in list values. + + This field is a member of `oneof`_ ``one_filter``. + numeric_filter (google.analytics.data_v1alpha.types.NumericFilter): + A filter for numeric or date values. + + This field is a member of `oneof`_ ``one_filter``. + between_filter (google.analytics.data_v1alpha.types.BetweenFilter): + A filter for between two values. + + This field is a member of `oneof`_ ``one_filter``. + """ + + field_name = proto.Field( + proto.STRING, + number=1, + ) + string_filter = proto.Field( + proto.MESSAGE, + number=4, + oneof="one_filter", + message="StringFilter", + ) + in_list_filter = proto.Field( + proto.MESSAGE, + number=5, + oneof="one_filter", + message="InListFilter", + ) + numeric_filter = proto.Field( + proto.MESSAGE, + number=6, + oneof="one_filter", + message="NumericFilter", + ) + between_filter = proto.Field( + proto.MESSAGE, + number=7, + oneof="one_filter", + message="BetweenFilter", + ) + + +class FunnelEventFilter(proto.Message): + r"""Creates a filter that matches events of a single event name. + If a parameter filter expression is specified, only the subset + of events that match both the single event name and the + parameter filter expressions match this event filter. + + Attributes: + event_name (str): + This filter matches events of this single + event name. Event name is required. + + This field is a member of `oneof`_ ``_event_name``. + funnel_parameter_filter_expression (google.analytics.data_v1alpha.types.FunnelParameterFilterExpression): + If specified, this filter matches events that + match both the single event name and the + parameter filter expressions. + Inside the parameter filter expression, only + parameter filters are available. + + This field is a member of `oneof`_ ``_funnel_parameter_filter_expression``. + """ + + event_name = proto.Field( + proto.STRING, + number=1, + optional=True, + ) + funnel_parameter_filter_expression = proto.Field( + proto.MESSAGE, + number=2, + optional=True, + message="FunnelParameterFilterExpression", + ) + + +class FunnelParameterFilterExpression(proto.Message): + r"""Expresses combinations of funnel filters on parameters. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + and_group (google.analytics.data_v1alpha.types.FunnelParameterFilterExpressionList): + The FunnelParameterFilterExpression in ``andGroup`` have an + AND relationship. + + This field is a member of `oneof`_ ``expr``. + or_group (google.analytics.data_v1alpha.types.FunnelParameterFilterExpressionList): + The FunnelParameterFilterExpression in ``orGroup`` have an + OR relationship. + + This field is a member of `oneof`_ ``expr``. + not_expression (google.analytics.data_v1alpha.types.FunnelParameterFilterExpression): + The FunnelParameterFilterExpression is NOT of + ``notExpression``. + + This field is a member of `oneof`_ ``expr``. + funnel_parameter_filter (google.analytics.data_v1alpha.types.FunnelParameterFilter): + A primitive funnel parameter filter. + + This field is a member of `oneof`_ ``expr``. + """ + + and_group = proto.Field( + proto.MESSAGE, + number=1, + oneof="expr", + message="FunnelParameterFilterExpressionList", + ) + or_group = proto.Field( + proto.MESSAGE, + number=2, + oneof="expr", + message="FunnelParameterFilterExpressionList", + ) + not_expression = proto.Field( + proto.MESSAGE, + number=3, + oneof="expr", + message="FunnelParameterFilterExpression", + ) + funnel_parameter_filter = proto.Field( + proto.MESSAGE, + number=4, + oneof="expr", + message="FunnelParameterFilter", + ) + + +class FunnelParameterFilterExpressionList(proto.Message): + r"""A list of funnel parameter filter expressions. + + Attributes: + expressions (Sequence[google.analytics.data_v1alpha.types.FunnelParameterFilterExpression]): + The list of funnel parameter filter + expressions. + """ + + expressions = proto.RepeatedField( + proto.MESSAGE, + number=1, + message="FunnelParameterFilterExpression", + ) + + +class FunnelParameterFilter(proto.Message): + r"""An expression to filter parameter values in a funnel. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + event_parameter_name (str): + This filter will be evaluated on the specified event + parameter. Event parameters are logged as parameters of the + event. Event parameters include fields like + "firebase_screen" & "currency". + + Event parameters can only be used in segments & funnels and + can only be used in a descendent filter from an EventFilter. + In a descendent filter from an EventFilter either event or + item parameters should be used. + + This field is a member of `oneof`_ ``one_parameter``. + item_parameter_name (str): + This filter will be evaluated on the specified item + parameter. Item parameters are logged as parameters in the + item array. Item parameters include fields like "item_name" + & "item_category". + + Item parameters can only be used in segments & funnels and + can only be used in a descendent filter from an EventFilter. + In a descendent filter from an EventFilter either event or + item parameters should be used. + + Item parameters are only available in ecommerce events. To + learn more about ecommerce events, see the [Measure + ecommerce] + (https://developers.google.com/analytics/devguides/collection/ga4/ecommerce) + guide. + + This field is a member of `oneof`_ ``one_parameter``. + string_filter (google.analytics.data_v1alpha.types.StringFilter): + Strings related filter. + + This field is a member of `oneof`_ ``one_filter``. + in_list_filter (google.analytics.data_v1alpha.types.InListFilter): + A filter for in list values. + + This field is a member of `oneof`_ ``one_filter``. + numeric_filter (google.analytics.data_v1alpha.types.NumericFilter): + A filter for numeric or date values. + + This field is a member of `oneof`_ ``one_filter``. + between_filter (google.analytics.data_v1alpha.types.BetweenFilter): + A filter for between two values. + + This field is a member of `oneof`_ ``one_filter``. + """ + + event_parameter_name = proto.Field( + proto.STRING, + number=1, + oneof="one_parameter", + ) + item_parameter_name = proto.Field( + proto.STRING, + number=2, + oneof="one_parameter", + ) + string_filter = proto.Field( + proto.MESSAGE, + number=4, + oneof="one_filter", + message="StringFilter", + ) + in_list_filter = proto.Field( + proto.MESSAGE, + number=5, + oneof="one_filter", + message="InListFilter", + ) + numeric_filter = proto.Field( + proto.MESSAGE, + number=6, + oneof="one_filter", + message="NumericFilter", + ) + between_filter = proto.Field( + proto.MESSAGE, + number=7, + oneof="one_filter", + message="BetweenFilter", + ) + + +class FunnelResponseMetadata(proto.Message): + r"""The funnel report's response metadata carries additional + information about the funnel report. + + Attributes: + sampling_metadatas (Sequence[google.analytics.data_v1alpha.types.SamplingMetadata]): + If funnel report results are + `sampled `__, + this describes what percentage of events were used in this + funnel report. One ``samplingMetadatas`` is populated for + each date range. Each ``samplingMetadatas`` corresponds to a + date range in order that date ranges were specified in the + request. + + However if the results are not sampled, this field will not + be defined. + """ + + sampling_metadatas = proto.RepeatedField( + proto.MESSAGE, + number=1, + message="SamplingMetadata", + ) + + +class SamplingMetadata(proto.Message): + r"""If funnel report results are + `sampled `__, + this metadata describes what percentage of events were used in this + funnel report for a date range. Sampling is the practice of + analyzing a subset of all data in order to uncover the meaningful + information in the larger data set. + + Attributes: + samples_read_count (int): + The total number of events read in this + sampled report for a date range. This is the + size of the subset this property's data that was + analyzed in this funnel report. + sampling_space_size (int): + The total number of events present in this property's data + that could have been analyzed in this funnel report for a + date range. Sampling uncovers the meaningful information + about the larger data set, and this is the size of the + larger data set. + + To calculate the percentage of available data that was used + in this funnel report, compute + ``samplesReadCount/samplingSpaceSize``. + """ + + samples_read_count = proto.Field( + proto.INT64, + number=1, + ) + sampling_space_size = proto.Field( + proto.INT64, + number=2, ) diff --git a/samples/generated_samples/analyticsdata_v1alpha_generated_alpha_analytics_data_run_funnel_report_async.py b/samples/generated_samples/analyticsdata_v1alpha_generated_alpha_analytics_data_run_funnel_report_async.py new file mode 100644 index 0000000..6267540 --- /dev/null +++ b/samples/generated_samples/analyticsdata_v1alpha_generated_alpha_analytics_data_run_funnel_report_async.py @@ -0,0 +1,44 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for RunFunnelReport +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-analytics-data + + +# [START analyticsdata_v1alpha_generated_AlphaAnalyticsData_RunFunnelReport_async] +from google.analytics import data_v1alpha + + +async def sample_run_funnel_report(): + # Create a client + client = data_v1alpha.AlphaAnalyticsDataAsyncClient() + + # Initialize request argument(s) + request = data_v1alpha.RunFunnelReportRequest( + ) + + # Make the request + response = await client.run_funnel_report(request=request) + + # Handle the response + print(response) + +# [END analyticsdata_v1alpha_generated_AlphaAnalyticsData_RunFunnelReport_async] diff --git a/samples/generated_samples/analyticsdata_v1alpha_generated_alpha_analytics_data_run_funnel_report_sync.py b/samples/generated_samples/analyticsdata_v1alpha_generated_alpha_analytics_data_run_funnel_report_sync.py new file mode 100644 index 0000000..59b27ef --- /dev/null +++ b/samples/generated_samples/analyticsdata_v1alpha_generated_alpha_analytics_data_run_funnel_report_sync.py @@ -0,0 +1,44 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for RunFunnelReport +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-analytics-data + + +# [START analyticsdata_v1alpha_generated_AlphaAnalyticsData_RunFunnelReport_sync] +from google.analytics import data_v1alpha + + +def sample_run_funnel_report(): + # Create a client + client = data_v1alpha.AlphaAnalyticsDataClient() + + # Initialize request argument(s) + request = data_v1alpha.RunFunnelReportRequest( + ) + + # Make the request + response = client.run_funnel_report(request=request) + + # Handle the response + print(response) + +# [END analyticsdata_v1alpha_generated_AlphaAnalyticsData_RunFunnelReport_sync] diff --git a/samples/generated_samples/snippet_metadata_data_v1alpha.json b/samples/generated_samples/snippet_metadata_data_v1alpha.json new file mode 100644 index 0000000..c7e6a3f --- /dev/null +++ b/samples/generated_samples/snippet_metadata_data_v1alpha.json @@ -0,0 +1,167 @@ +{ + "clientLibrary": { + "apis": [ + { + "id": "google.analytics.data.v1alpha", + "version": "v1alpha" + } + ], + "language": "PYTHON", + "name": "google-analytics-data" + }, + "snippets": [ + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.analytics.data_v1alpha.AlphaAnalyticsDataAsyncClient", + "shortName": "AlphaAnalyticsDataAsyncClient" + }, + "fullName": "google.analytics.data_v1alpha.AlphaAnalyticsDataAsyncClient.run_funnel_report", + "method": { + "fullName": "google.analytics.data.v1alpha.AlphaAnalyticsData.RunFunnelReport", + "service": { + "fullName": "google.analytics.data.v1alpha.AlphaAnalyticsData", + "shortName": "AlphaAnalyticsData" + }, + "shortName": "RunFunnelReport" + }, + "parameters": [ + { + "name": "request", + "type": "google.analytics.data_v1alpha.types.RunFunnelReportRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.analytics.data_v1alpha.types.RunFunnelReportResponse", + "shortName": "run_funnel_report" + }, + "description": "Sample for RunFunnelReport", + "file": "analyticsdata_v1alpha_generated_alpha_analytics_data_run_funnel_report_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "analyticsdata_v1alpha_generated_AlphaAnalyticsData_RunFunnelReport_async", + "segments": [ + { + "end": 43, + "start": 27, + "type": "FULL" + }, + { + "end": 43, + "start": 27, + "type": "SHORT" + }, + { + "end": 33, + "start": 31, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 37, + "start": 34, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 40, + "start": 38, + "type": "REQUEST_EXECUTION" + }, + { + "end": 44, + "start": 41, + "type": "RESPONSE_HANDLING" + } + ], + "title": "analyticsdata_v1alpha_generated_alpha_analytics_data_run_funnel_report_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.analytics.data_v1alpha.AlphaAnalyticsDataClient", + "shortName": "AlphaAnalyticsDataClient" + }, + "fullName": "google.analytics.data_v1alpha.AlphaAnalyticsDataClient.run_funnel_report", + "method": { + "fullName": "google.analytics.data.v1alpha.AlphaAnalyticsData.RunFunnelReport", + "service": { + "fullName": "google.analytics.data.v1alpha.AlphaAnalyticsData", + "shortName": "AlphaAnalyticsData" + }, + "shortName": "RunFunnelReport" + }, + "parameters": [ + { + "name": "request", + "type": "google.analytics.data_v1alpha.types.RunFunnelReportRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.analytics.data_v1alpha.types.RunFunnelReportResponse", + "shortName": "run_funnel_report" + }, + "description": "Sample for RunFunnelReport", + "file": "analyticsdata_v1alpha_generated_alpha_analytics_data_run_funnel_report_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "analyticsdata_v1alpha_generated_AlphaAnalyticsData_RunFunnelReport_sync", + "segments": [ + { + "end": 43, + "start": 27, + "type": "FULL" + }, + { + "end": 43, + "start": 27, + "type": "SHORT" + }, + { + "end": 33, + "start": 31, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 37, + "start": 34, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 40, + "start": 38, + "type": "REQUEST_EXECUTION" + }, + { + "end": 44, + "start": 41, + "type": "RESPONSE_HANDLING" + } + ], + "title": "analyticsdata_v1alpha_generated_alpha_analytics_data_run_funnel_report_sync.py" + } + ] +} diff --git a/tests/unit/gapic/data_v1alpha/__init__.py b/tests/unit/gapic/data_v1alpha/__init__.py index 4de6597..e8e1c38 100644 --- a/tests/unit/gapic/data_v1alpha/__init__.py +++ b/tests/unit/gapic/data_v1alpha/__init__.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2020 Google LLC +# Copyright 2022 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/tests/unit/gapic/data_v1alpha/test_alpha_analytics_data.py b/tests/unit/gapic/data_v1alpha/test_alpha_analytics_data.py index ecd8689..13d03c1 100644 --- a/tests/unit/gapic/data_v1alpha/test_alpha_analytics_data.py +++ b/tests/unit/gapic/data_v1alpha/test_alpha_analytics_data.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2020 Google LLC +# Copyright 2022 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,7 +15,6 @@ # import os import mock -import packaging.version import grpc from grpc.experimental import aio @@ -31,9 +30,6 @@ AlphaAnalyticsDataClient, ) from google.analytics.data_v1alpha.services.alpha_analytics_data import transports -from google.analytics.data_v1alpha.services.alpha_analytics_data.transports.base import ( - _GOOGLE_AUTH_VERSION, -) from google.analytics.data_v1alpha.types import analytics_data_api from google.analytics.data_v1alpha.types import data from google.api_core import client_options @@ -41,26 +37,14 @@ from google.api_core import gapic_v1 from google.api_core import grpc_helpers from google.api_core import grpc_helpers_async +from google.api_core import path_template from google.auth import credentials as ga_credentials from google.auth.exceptions import MutualTLSChannelError from google.oauth2 import service_account +from google.protobuf import duration_pb2 # type: ignore import google.auth -# TODO(busunkim): Once google-auth >= 1.25.0 is required transitively -# through google-api-core: -# - Delete the auth "less than" test cases -# - Delete these pytest markers (Make the "greater than or equal to" tests the default). -requires_google_auth_lt_1_25_0 = pytest.mark.skipif( - packaging.version.parse(_GOOGLE_AUTH_VERSION) >= packaging.version.parse("1.25.0"), - reason="This test requires google-auth < 1.25.0", -) -requires_google_auth_gte_1_25_0 = pytest.mark.skipif( - packaging.version.parse(_GOOGLE_AUTH_VERSION) < packaging.version.parse("1.25.0"), - reason="This test requires google-auth >= 1.25.0", -) - - def client_cert_source_callback(): return b"cert bytes", b"key bytes" @@ -107,24 +91,26 @@ def test__get_default_mtls_endpoint(): @pytest.mark.parametrize( - "client_class", + "client_class,transport_name", [ - AlphaAnalyticsDataClient, - AlphaAnalyticsDataAsyncClient, + (AlphaAnalyticsDataClient, "grpc"), + (AlphaAnalyticsDataAsyncClient, "grpc_asyncio"), ], ) -def test_alpha_analytics_data_client_from_service_account_info(client_class): +def test_alpha_analytics_data_client_from_service_account_info( + client_class, transport_name +): creds = ga_credentials.AnonymousCredentials() with mock.patch.object( service_account.Credentials, "from_service_account_info" ) as factory: factory.return_value = creds info = {"valid": True} - client = client_class.from_service_account_info(info) + client = client_class.from_service_account_info(info, transport=transport_name) assert client.transport._credentials == creds assert isinstance(client, client_class) - assert client.transport._host == "analyticsdata.googleapis.com:443" + assert client.transport._host == ("analyticsdata.googleapis.com:443") @pytest.mark.parametrize( @@ -153,27 +139,33 @@ def test_alpha_analytics_data_client_service_account_always_use_jwt( @pytest.mark.parametrize( - "client_class", + "client_class,transport_name", [ - AlphaAnalyticsDataClient, - AlphaAnalyticsDataAsyncClient, + (AlphaAnalyticsDataClient, "grpc"), + (AlphaAnalyticsDataAsyncClient, "grpc_asyncio"), ], ) -def test_alpha_analytics_data_client_from_service_account_file(client_class): +def test_alpha_analytics_data_client_from_service_account_file( + client_class, transport_name +): creds = ga_credentials.AnonymousCredentials() with mock.patch.object( service_account.Credentials, "from_service_account_file" ) as factory: factory.return_value = creds - client = client_class.from_service_account_file("dummy/file/path.json") + client = client_class.from_service_account_file( + "dummy/file/path.json", transport=transport_name + ) assert client.transport._credentials == creds assert isinstance(client, client_class) - client = client_class.from_service_account_json("dummy/file/path.json") + client = client_class.from_service_account_json( + "dummy/file/path.json", transport=transport_name + ) assert client.transport._credentials == creds assert isinstance(client, client_class) - assert client.transport._host == "analyticsdata.googleapis.com:443" + assert client.transport._host == ("analyticsdata.googleapis.com:443") def test_alpha_analytics_data_client_get_transport_class(): @@ -226,7 +218,7 @@ def test_alpha_analytics_data_client_client_options( options = client_options.ClientOptions(api_endpoint="squid.clam.whelk") with mock.patch.object(transport_class, "__init__") as patched: patched.return_value = None - client = client_class(client_options=options) + client = client_class(transport=transport_name, client_options=options) patched.assert_called_once_with( credentials=None, credentials_file=None, @@ -243,7 +235,7 @@ def test_alpha_analytics_data_client_client_options( with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): with mock.patch.object(transport_class, "__init__") as patched: patched.return_value = None - client = client_class() + client = client_class(transport=transport_name) patched.assert_called_once_with( credentials=None, credentials_file=None, @@ -260,7 +252,7 @@ def test_alpha_analytics_data_client_client_options( with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): with mock.patch.object(transport_class, "__init__") as patched: patched.return_value = None - client = client_class() + client = client_class(transport=transport_name) patched.assert_called_once_with( credentials=None, credentials_file=None, @@ -276,20 +268,20 @@ def test_alpha_analytics_data_client_client_options( # unsupported value. with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): with pytest.raises(MutualTLSChannelError): - client = client_class() + client = client_class(transport=transport_name) # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. with mock.patch.dict( os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} ): with pytest.raises(ValueError): - client = client_class() + client = client_class(transport=transport_name) # Check the case quota_project_id is provided options = client_options.ClientOptions(quota_project_id="octopus") with mock.patch.object(transport_class, "__init__") as patched: patched.return_value = None - client = client_class(client_options=options) + client = client_class(client_options=options, transport=transport_name) patched.assert_called_once_with( credentials=None, credentials_file=None, @@ -358,7 +350,7 @@ def test_alpha_analytics_data_client_mtls_env_auto( ) with mock.patch.object(transport_class, "__init__") as patched: patched.return_value = None - client = client_class(client_options=options) + client = client_class(client_options=options, transport=transport_name) if use_client_cert_env == "false": expected_client_cert_source = None @@ -400,7 +392,7 @@ def test_alpha_analytics_data_client_mtls_env_auto( expected_client_cert_source = client_cert_source_callback patched.return_value = None - client = client_class() + client = client_class(transport=transport_name) patched.assert_called_once_with( credentials=None, credentials_file=None, @@ -422,7 +414,7 @@ def test_alpha_analytics_data_client_mtls_env_auto( return_value=False, ): patched.return_value = None - client = client_class() + client = client_class(transport=transport_name) patched.assert_called_once_with( credentials=None, credentials_file=None, @@ -435,6 +427,87 @@ def test_alpha_analytics_data_client_mtls_env_auto( ) +@pytest.mark.parametrize( + "client_class", [AlphaAnalyticsDataClient, AlphaAnalyticsDataAsyncClient] +) +@mock.patch.object( + AlphaAnalyticsDataClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(AlphaAnalyticsDataClient), +) +@mock.patch.object( + AlphaAnalyticsDataAsyncClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(AlphaAnalyticsDataAsyncClient), +) +def test_alpha_analytics_data_client_get_mtls_endpoint_and_cert_source(client_class): + mock_client_cert_source = mock.Mock() + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "true". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + mock_api_endpoint = "foo" + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint + ) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( + options + ) + assert api_endpoint == mock_api_endpoint + assert cert_source == mock_client_cert_source + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "false". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + mock_client_cert_source = mock.Mock() + mock_api_endpoint = "foo" + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint + ) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( + options + ) + assert api_endpoint == mock_api_endpoint + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert doesn't exist. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, + ): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert exists. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=mock_client_cert_source, + ): + ( + api_endpoint, + cert_source, + ) = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source == mock_client_cert_source + + @pytest.mark.parametrize( "client_class,transport_class,transport_name", [ @@ -455,7 +528,7 @@ def test_alpha_analytics_data_client_client_options_scopes( ) with mock.patch.object(transport_class, "__init__") as patched: patched.return_value = None - client = client_class(client_options=options) + client = client_class(client_options=options, transport=transport_name) patched.assert_called_once_with( credentials=None, credentials_file=None, @@ -469,635 +542,140 @@ def test_alpha_analytics_data_client_client_options_scopes( @pytest.mark.parametrize( - "client_class,transport_class,transport_name", + "client_class,transport_class,transport_name,grpc_helpers", [ - (AlphaAnalyticsDataClient, transports.AlphaAnalyticsDataGrpcTransport, "grpc"), ( - AlphaAnalyticsDataAsyncClient, - transports.AlphaAnalyticsDataGrpcAsyncIOTransport, - "grpc_asyncio", - ), - ], -) -def test_alpha_analytics_data_client_client_options_credentials_file( - client_class, transport_class, transport_name -): - # Check the case credentials file is provided. - options = client_options.ClientOptions(credentials_file="credentials.json") - with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(client_options=options) - patched.assert_called_once_with( - credentials=None, - credentials_file="credentials.json", - host=client.DEFAULT_ENDPOINT, - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - ) - - -def test_alpha_analytics_data_client_client_options_from_dict(): - with mock.patch( - "google.analytics.data_v1alpha.services.alpha_analytics_data.transports.AlphaAnalyticsDataGrpcTransport.__init__" - ) as grpc_transport: - grpc_transport.return_value = None - client = AlphaAnalyticsDataClient( - client_options={"api_endpoint": "squid.clam.whelk"} - ) - grpc_transport.assert_called_once_with( - credentials=None, - credentials_file=None, - host="squid.clam.whelk", - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - ) - - -def test_run_report( - transport: str = "grpc", request_type=analytics_data_api.RunReportRequest -): - client = AlphaAnalyticsDataClient( - 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.run_report), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = analytics_data_api.RunReportResponse( - row_count=992, - ) - response = client.run_report(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == analytics_data_api.RunReportRequest() - - # Establish that the response is the type that we expect. - assert isinstance(response, analytics_data_api.RunReportResponse) - assert response.row_count == 992 - - -def test_run_report_from_dict(): - test_run_report(request_type=dict) - - -def test_run_report_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 = AlphaAnalyticsDataClient( - 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.run_report), "__call__") as call: - client.run_report() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == analytics_data_api.RunReportRequest() - - -@pytest.mark.asyncio -async def test_run_report_async( - transport: str = "grpc_asyncio", request_type=analytics_data_api.RunReportRequest -): - client = AlphaAnalyticsDataAsyncClient( - 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.run_report), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - analytics_data_api.RunReportResponse( - row_count=992, - ) - ) - response = await client.run_report(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - assert args[0] == analytics_data_api.RunReportRequest() - - # Establish that the response is the type that we expect. - assert isinstance(response, analytics_data_api.RunReportResponse) - assert response.row_count == 992 - - -@pytest.mark.asyncio -async def test_run_report_async_from_dict(): - await test_run_report_async(request_type=dict) - - -def test_run_pivot_report( - transport: str = "grpc", request_type=analytics_data_api.RunPivotReportRequest -): - client = AlphaAnalyticsDataClient( - 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.run_pivot_report), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = analytics_data_api.RunPivotReportResponse() - response = client.run_pivot_report(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == analytics_data_api.RunPivotReportRequest() - - # Establish that the response is the type that we expect. - assert isinstance(response, analytics_data_api.RunPivotReportResponse) - - -def test_run_pivot_report_from_dict(): - test_run_pivot_report(request_type=dict) - - -def test_run_pivot_report_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 = AlphaAnalyticsDataClient( - 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.run_pivot_report), "__call__") as call: - client.run_pivot_report() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == analytics_data_api.RunPivotReportRequest() - - -@pytest.mark.asyncio -async def test_run_pivot_report_async( - transport: str = "grpc_asyncio", - request_type=analytics_data_api.RunPivotReportRequest, -): - client = AlphaAnalyticsDataAsyncClient( - 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.run_pivot_report), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - analytics_data_api.RunPivotReportResponse() - ) - response = await client.run_pivot_report(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - assert args[0] == analytics_data_api.RunPivotReportRequest() - - # Establish that the response is the type that we expect. - assert isinstance(response, analytics_data_api.RunPivotReportResponse) - - -@pytest.mark.asyncio -async def test_run_pivot_report_async_from_dict(): - await test_run_pivot_report_async(request_type=dict) - - -def test_batch_run_reports( - transport: str = "grpc", request_type=analytics_data_api.BatchRunReportsRequest -): - client = AlphaAnalyticsDataClient( - 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.batch_run_reports), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = analytics_data_api.BatchRunReportsResponse() - response = client.batch_run_reports(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == analytics_data_api.BatchRunReportsRequest() - - # Establish that the response is the type that we expect. - assert isinstance(response, analytics_data_api.BatchRunReportsResponse) - - -def test_batch_run_reports_from_dict(): - test_batch_run_reports(request_type=dict) - - -def test_batch_run_reports_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 = AlphaAnalyticsDataClient( - 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.batch_run_reports), "__call__" - ) as call: - client.batch_run_reports() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == analytics_data_api.BatchRunReportsRequest() - - -@pytest.mark.asyncio -async def test_batch_run_reports_async( - transport: str = "grpc_asyncio", - request_type=analytics_data_api.BatchRunReportsRequest, -): - client = AlphaAnalyticsDataAsyncClient( - 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.batch_run_reports), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - analytics_data_api.BatchRunReportsResponse() - ) - response = await client.batch_run_reports(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - assert args[0] == analytics_data_api.BatchRunReportsRequest() - - # Establish that the response is the type that we expect. - assert isinstance(response, analytics_data_api.BatchRunReportsResponse) - - -@pytest.mark.asyncio -async def test_batch_run_reports_async_from_dict(): - await test_batch_run_reports_async(request_type=dict) - - -def test_batch_run_pivot_reports( - transport: str = "grpc", request_type=analytics_data_api.BatchRunPivotReportsRequest -): - client = AlphaAnalyticsDataClient( - 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.batch_run_pivot_reports), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = analytics_data_api.BatchRunPivotReportsResponse() - response = client.batch_run_pivot_reports(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == analytics_data_api.BatchRunPivotReportsRequest() - - # Establish that the response is the type that we expect. - assert isinstance(response, analytics_data_api.BatchRunPivotReportsResponse) - - -def test_batch_run_pivot_reports_from_dict(): - test_batch_run_pivot_reports(request_type=dict) - - -def test_batch_run_pivot_reports_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 = AlphaAnalyticsDataClient( - 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.batch_run_pivot_reports), "__call__" - ) as call: - client.batch_run_pivot_reports() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == analytics_data_api.BatchRunPivotReportsRequest() - - -@pytest.mark.asyncio -async def test_batch_run_pivot_reports_async( - transport: str = "grpc_asyncio", - request_type=analytics_data_api.BatchRunPivotReportsRequest, -): - client = AlphaAnalyticsDataAsyncClient( - 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.batch_run_pivot_reports), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - analytics_data_api.BatchRunPivotReportsResponse() - ) - response = await client.batch_run_pivot_reports(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - assert args[0] == analytics_data_api.BatchRunPivotReportsRequest() - - # Establish that the response is the type that we expect. - assert isinstance(response, analytics_data_api.BatchRunPivotReportsResponse) - - -@pytest.mark.asyncio -async def test_batch_run_pivot_reports_async_from_dict(): - await test_batch_run_pivot_reports_async(request_type=dict) - - -def test_get_metadata( - transport: str = "grpc", request_type=analytics_data_api.GetMetadataRequest -): - client = AlphaAnalyticsDataClient( - 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.get_metadata), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = analytics_data_api.Metadata( - name="name_value", - ) - response = client.get_metadata(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == analytics_data_api.GetMetadataRequest() - - # Establish that the response is the type that we expect. - assert isinstance(response, analytics_data_api.Metadata) - assert response.name == "name_value" - - -def test_get_metadata_from_dict(): - test_get_metadata(request_type=dict) - - -def test_get_metadata_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 = AlphaAnalyticsDataClient( - 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.get_metadata), "__call__") as call: - client.get_metadata() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == analytics_data_api.GetMetadataRequest() - - -@pytest.mark.asyncio -async def test_get_metadata_async( - transport: str = "grpc_asyncio", request_type=analytics_data_api.GetMetadataRequest -): - client = AlphaAnalyticsDataAsyncClient( - 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.get_metadata), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - analytics_data_api.Metadata( - name="name_value", - ) - ) - response = await client.get_metadata(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - assert args[0] == analytics_data_api.GetMetadataRequest() - - # Establish that the response is the type that we expect. - assert isinstance(response, analytics_data_api.Metadata) - assert response.name == "name_value" - - -@pytest.mark.asyncio -async def test_get_metadata_async_from_dict(): - await test_get_metadata_async(request_type=dict) - - -def test_get_metadata_field_headers(): - client = AlphaAnalyticsDataClient( - 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 = analytics_data_api.GetMetadataRequest() - - request.name = "name/value" - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_metadata), "__call__") as call: - call.return_value = analytics_data_api.Metadata() - client.get_metadata(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", - "name=name/value", - ) in kw["metadata"] - - -@pytest.mark.asyncio -async def test_get_metadata_field_headers_async(): - client = AlphaAnalyticsDataAsyncClient( - 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 = analytics_data_api.GetMetadataRequest() - - request.name = "name/value" - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_metadata), "__call__") as call: - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - analytics_data_api.Metadata() - ) - await client.get_metadata(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", - "name=name/value", - ) in kw["metadata"] - - -def test_get_metadata_flattened(): - client = AlphaAnalyticsDataClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_metadata), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = analytics_data_api.Metadata() - # Call the method with a truthy value for each flattened field, - # using the keyword arguments to the method. - client.get_metadata( - name="name_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].name == "name_value" - - -def test_get_metadata_flattened_error(): - client = AlphaAnalyticsDataClient( - credentials=ga_credentials.AnonymousCredentials(), - ) + AlphaAnalyticsDataClient, + transports.AlphaAnalyticsDataGrpcTransport, + "grpc", + grpc_helpers, + ), + ( + AlphaAnalyticsDataAsyncClient, + transports.AlphaAnalyticsDataGrpcAsyncIOTransport, + "grpc_asyncio", + grpc_helpers_async, + ), + ], +) +def test_alpha_analytics_data_client_client_options_credentials_file( + client_class, transport_class, transport_name, grpc_helpers +): + # Check the case credentials file is provided. + options = client_options.ClientOptions(credentials_file="credentials.json") - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.get_metadata( - analytics_data_api.GetMetadataRequest(), - name="name_value", + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file="credentials.json", + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, ) -@pytest.mark.asyncio -async def test_get_metadata_flattened_async(): - client = AlphaAnalyticsDataAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_metadata), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = analytics_data_api.Metadata() - - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - analytics_data_api.Metadata() +def test_alpha_analytics_data_client_client_options_from_dict(): + with mock.patch( + "google.analytics.data_v1alpha.services.alpha_analytics_data.transports.AlphaAnalyticsDataGrpcTransport.__init__" + ) as grpc_transport: + grpc_transport.return_value = None + client = AlphaAnalyticsDataClient( + client_options={"api_endpoint": "squid.clam.whelk"} ) - # Call the method with a truthy value for each flattened field, - # using the keyword arguments to the method. - response = await client.get_metadata( - name="name_value", + grpc_transport.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, ) - # 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].name == "name_value" +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,grpc_helpers", + [ + ( + AlphaAnalyticsDataClient, + transports.AlphaAnalyticsDataGrpcTransport, + "grpc", + grpc_helpers, + ), + ( + AlphaAnalyticsDataAsyncClient, + transports.AlphaAnalyticsDataGrpcAsyncIOTransport, + "grpc_asyncio", + grpc_helpers_async, + ), + ], +) +def test_alpha_analytics_data_client_create_channel_credentials_file( + client_class, transport_class, transport_name, grpc_helpers +): + # Check the case credentials file is provided. + options = client_options.ClientOptions(credentials_file="credentials.json") -@pytest.mark.asyncio -async def test_get_metadata_flattened_error_async(): - client = AlphaAnalyticsDataAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file="credentials.json", + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + ) - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - await client.get_metadata( - analytics_data_api.GetMetadataRequest(), - name="name_value", + # test that the credentials from file are saved and used as the credentials. + with mock.patch.object( + google.auth, "load_credentials_from_file", autospec=True + ) as load_creds, mock.patch.object( + google.auth, "default", autospec=True + ) as adc, mock.patch.object( + grpc_helpers, "create_channel" + ) as create_channel: + creds = ga_credentials.AnonymousCredentials() + file_creds = ga_credentials.AnonymousCredentials() + load_creds.return_value = (file_creds, None) + adc.return_value = (creds, None) + client = client_class(client_options=options, transport=transport_name) + create_channel.assert_called_with( + "analyticsdata.googleapis.com:443", + credentials=file_creds, + credentials_file=None, + quota_project_id=None, + default_scopes=( + "https://www.googleapis.com/auth/analytics", + "https://www.googleapis.com/auth/analytics.readonly", + ), + scopes=None, + default_host="analyticsdata.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], ) -def test_run_realtime_report( - transport: str = "grpc", request_type=analytics_data_api.RunRealtimeReportRequest -): +@pytest.mark.parametrize( + "request_type", + [ + analytics_data_api.RunFunnelReportRequest, + dict, + ], +) +def test_run_funnel_report(request_type, transport: str = "grpc"): client = AlphaAnalyticsDataClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -1109,29 +687,25 @@ def test_run_realtime_report( # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.run_realtime_report), "__call__" + type(client.transport.run_funnel_report), "__call__" ) as call: # Designate an appropriate return value for the call. - call.return_value = analytics_data_api.RunRealtimeReportResponse( - row_count=992, + call.return_value = analytics_data_api.RunFunnelReportResponse( + kind="kind_value", ) - response = client.run_realtime_report(request) + response = client.run_funnel_report(request) # Establish that the underlying gRPC stub method was called. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0] == analytics_data_api.RunRealtimeReportRequest() + assert args[0] == analytics_data_api.RunFunnelReportRequest() # Establish that the response is the type that we expect. - assert isinstance(response, analytics_data_api.RunRealtimeReportResponse) - assert response.row_count == 992 - + assert isinstance(response, analytics_data_api.RunFunnelReportResponse) + assert response.kind == "kind_value" -def test_run_realtime_report_from_dict(): - test_run_realtime_report(request_type=dict) - -def test_run_realtime_report_empty_call(): +def test_run_funnel_report_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 = AlphaAnalyticsDataClient( @@ -1141,18 +715,18 @@ def test_run_realtime_report_empty_call(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.run_realtime_report), "__call__" + type(client.transport.run_funnel_report), "__call__" ) as call: - client.run_realtime_report() + client.run_funnel_report() call.assert_called() _, args, _ = call.mock_calls[0] - assert args[0] == analytics_data_api.RunRealtimeReportRequest() + assert args[0] == analytics_data_api.RunFunnelReportRequest() @pytest.mark.asyncio -async def test_run_realtime_report_async( +async def test_run_funnel_report_async( transport: str = "grpc_asyncio", - request_type=analytics_data_api.RunRealtimeReportRequest, + request_type=analytics_data_api.RunFunnelReportRequest, ): client = AlphaAnalyticsDataAsyncClient( credentials=ga_credentials.AnonymousCredentials(), @@ -1165,48 +739,48 @@ async def test_run_realtime_report_async( # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.run_realtime_report), "__call__" + type(client.transport.run_funnel_report), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - analytics_data_api.RunRealtimeReportResponse( - row_count=992, + analytics_data_api.RunFunnelReportResponse( + kind="kind_value", ) ) - response = await client.run_realtime_report(request) + response = await client.run_funnel_report(request) # Establish that the underlying gRPC stub method was called. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == analytics_data_api.RunRealtimeReportRequest() + assert args[0] == analytics_data_api.RunFunnelReportRequest() # Establish that the response is the type that we expect. - assert isinstance(response, analytics_data_api.RunRealtimeReportResponse) - assert response.row_count == 992 + assert isinstance(response, analytics_data_api.RunFunnelReportResponse) + assert response.kind == "kind_value" @pytest.mark.asyncio -async def test_run_realtime_report_async_from_dict(): - await test_run_realtime_report_async(request_type=dict) +async def test_run_funnel_report_async_from_dict(): + await test_run_funnel_report_async(request_type=dict) -def test_run_realtime_report_field_headers(): +def test_run_funnel_report_field_headers(): client = AlphaAnalyticsDataClient( 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 = analytics_data_api.RunRealtimeReportRequest() + request = analytics_data_api.RunFunnelReportRequest() - request.property = "property/value" + request.property = "property_value" # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.run_realtime_report), "__call__" + type(client.transport.run_funnel_report), "__call__" ) as call: - call.return_value = analytics_data_api.RunRealtimeReportResponse() - client.run_realtime_report(request) + call.return_value = analytics_data_api.RunFunnelReportResponse() + client.run_funnel_report(request) # Establish that the underlying gRPC stub method was called. assert len(call.mock_calls) == 1 @@ -1217,30 +791,30 @@ def test_run_realtime_report_field_headers(): _, _, kw = call.mock_calls[0] assert ( "x-goog-request-params", - "property=property/value", + "property=property_value", ) in kw["metadata"] @pytest.mark.asyncio -async def test_run_realtime_report_field_headers_async(): +async def test_run_funnel_report_field_headers_async(): client = AlphaAnalyticsDataAsyncClient( 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 = analytics_data_api.RunRealtimeReportRequest() + request = analytics_data_api.RunFunnelReportRequest() - request.property = "property/value" + request.property = "property_value" # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client.transport.run_realtime_report), "__call__" + type(client.transport.run_funnel_report), "__call__" ) as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - analytics_data_api.RunRealtimeReportResponse() + analytics_data_api.RunFunnelReportResponse() ) - await client.run_realtime_report(request) + await client.run_funnel_report(request) # Establish that the underlying gRPC stub method was called. assert len(call.mock_calls) @@ -1251,7 +825,7 @@ async def test_run_realtime_report_field_headers_async(): _, _, kw = call.mock_calls[0] assert ( "x-goog-request-params", - "property=property/value", + "property=property_value", ) in kw["metadata"] @@ -1276,6 +850,26 @@ def test_credentials_transport_error(): transport=transport, ) + # It is an error to provide an api_key and a transport instance. + transport = transports.AlphaAnalyticsDataGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = AlphaAnalyticsDataClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = mock.Mock() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = AlphaAnalyticsDataClient( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + # It is an error to provide scopes and a transport instance. transport = transports.AlphaAnalyticsDataGrpcTransport( credentials=ga_credentials.AnonymousCredentials(), @@ -1326,6 +920,19 @@ def test_transport_adc(transport_class): adc.assert_called_once() +@pytest.mark.parametrize( + "transport_name", + [ + "grpc", + ], +) +def test_transport_kind(transport_name): + transport = AlphaAnalyticsDataClient.get_transport_class(transport_name)( + credentials=ga_credentials.AnonymousCredentials(), + ) + assert transport.kind == transport_name + + def test_transport_grpc_default(): # A client should use the gRPC transport by default. client = AlphaAnalyticsDataClient( @@ -1358,20 +965,23 @@ def test_alpha_analytics_data_base_transport(): # Every method on the transport should just blindly # raise NotImplementedError. - methods = ( - "run_report", - "run_pivot_report", - "batch_run_reports", - "batch_run_pivot_reports", - "get_metadata", - "run_realtime_report", - ) + methods = ("run_funnel_report",) for method in methods: with pytest.raises(NotImplementedError): getattr(transport, method)(request=object()) + with pytest.raises(NotImplementedError): + transport.close() + + # Catch all for all remaining methods and properties + remainder = [ + "kind", + ] + for r in remainder: + with pytest.raises(NotImplementedError): + getattr(transport, r)() + -@requires_google_auth_gte_1_25_0 def test_alpha_analytics_data_base_transport_with_credentials_file(): # Instantiate the base transport with a credentials file with mock.patch.object( @@ -1396,30 +1006,6 @@ def test_alpha_analytics_data_base_transport_with_credentials_file(): ) -@requires_google_auth_lt_1_25_0 -def test_alpha_analytics_data_base_transport_with_credentials_file_old_google_auth(): - # Instantiate the base transport with a credentials file - with mock.patch.object( - google.auth, "load_credentials_from_file", autospec=True - ) as load_creds, mock.patch( - "google.analytics.data_v1alpha.services.alpha_analytics_data.transports.AlphaAnalyticsDataTransport._prep_wrapped_messages" - ) as Transport: - Transport.return_value = None - load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) - transport = transports.AlphaAnalyticsDataTransport( - credentials_file="credentials.json", - quota_project_id="octopus", - ) - load_creds.assert_called_once_with( - "credentials.json", - scopes=( - "https://www.googleapis.com/auth/analytics", - "https://www.googleapis.com/auth/analytics.readonly", - ), - quota_project_id="octopus", - ) - - def test_alpha_analytics_data_base_transport_with_adc(): # Test the default credentials are used if credentials and credentials_file are None. with mock.patch.object(google.auth, "default", autospec=True) as adc, mock.patch( @@ -1431,7 +1017,6 @@ def test_alpha_analytics_data_base_transport_with_adc(): adc.assert_called_once() -@requires_google_auth_gte_1_25_0 def test_alpha_analytics_data_auth_adc(): # If no credentials are provided, we should use ADC credentials. with mock.patch.object(google.auth, "default", autospec=True) as adc: @@ -1447,21 +1032,6 @@ def test_alpha_analytics_data_auth_adc(): ) -@requires_google_auth_lt_1_25_0 -def test_alpha_analytics_data_auth_adc_old_google_auth(): - # If no credentials are provided, we should use ADC credentials. - with mock.patch.object(google.auth, "default", autospec=True) as adc: - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - AlphaAnalyticsDataClient() - adc.assert_called_once_with( - scopes=( - "https://www.googleapis.com/auth/analytics", - "https://www.googleapis.com/auth/analytics.readonly", - ), - quota_project_id=None, - ) - - @pytest.mark.parametrize( "transport_class", [ @@ -1469,7 +1039,6 @@ def test_alpha_analytics_data_auth_adc_old_google_auth(): transports.AlphaAnalyticsDataGrpcAsyncIOTransport, ], ) -@requires_google_auth_gte_1_25_0 def test_alpha_analytics_data_transport_auth_adc(transport_class): # If credentials and host are not provided, the transport class should use # ADC credentials. @@ -1486,29 +1055,6 @@ def test_alpha_analytics_data_transport_auth_adc(transport_class): ) -@pytest.mark.parametrize( - "transport_class", - [ - transports.AlphaAnalyticsDataGrpcTransport, - transports.AlphaAnalyticsDataGrpcAsyncIOTransport, - ], -) -@requires_google_auth_lt_1_25_0 -def test_alpha_analytics_data_transport_auth_adc_old_google_auth(transport_class): - # If credentials and host are not provided, the transport class should use - # ADC credentials. - with mock.patch.object(google.auth, "default", autospec=True) as adc: - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport_class(quota_project_id="octopus") - adc.assert_called_once_with( - scopes=( - "https://www.googleapis.com/auth/analytics", - "https://www.googleapis.com/auth/analytics.readonly", - ), - quota_project_id="octopus", - ) - - @pytest.mark.parametrize( "transport_class,grpc_helpers", [ @@ -1594,24 +1140,40 @@ def test_alpha_analytics_data_grpc_transport_client_cert_source_for_mtls( ) -def test_alpha_analytics_data_host_no_port(): +@pytest.mark.parametrize( + "transport_name", + [ + "grpc", + "grpc_asyncio", + ], +) +def test_alpha_analytics_data_host_no_port(transport_name): client = AlphaAnalyticsDataClient( credentials=ga_credentials.AnonymousCredentials(), client_options=client_options.ClientOptions( api_endpoint="analyticsdata.googleapis.com" ), + transport=transport_name, ) - assert client.transport._host == "analyticsdata.googleapis.com:443" + assert client.transport._host == ("analyticsdata.googleapis.com:443") -def test_alpha_analytics_data_host_with_port(): +@pytest.mark.parametrize( + "transport_name", + [ + "grpc", + "grpc_asyncio", + ], +) +def test_alpha_analytics_data_host_with_port(transport_name): client = AlphaAnalyticsDataClient( credentials=ga_credentials.AnonymousCredentials(), client_options=client_options.ClientOptions( api_endpoint="analyticsdata.googleapis.com:8000" ), + transport=transport_name, ) - assert client.transport._host == "analyticsdata.googleapis.com:8000" + assert client.transport._host == ("analyticsdata.googleapis.com:8000") def test_alpha_analytics_data_grpc_transport_channel(): @@ -1740,28 +1302,8 @@ def test_alpha_analytics_data_transport_channel_mtls_with_adc(transport_class): assert transport.grpc_channel == mock_grpc_channel -def test_metadata_path(): - property = "squid" - expected = "properties/{property}/metadata".format( - property=property, - ) - actual = AlphaAnalyticsDataClient.metadata_path(property) - assert expected == actual - - -def test_parse_metadata_path(): - expected = { - "property": "clam", - } - path = AlphaAnalyticsDataClient.metadata_path(**expected) - - # Check that the path construction is reversible. - actual = AlphaAnalyticsDataClient.parse_metadata_path(path) - assert expected == actual - - def test_common_billing_account_path(): - billing_account = "whelk" + billing_account = "squid" expected = "billingAccounts/{billing_account}".format( billing_account=billing_account, ) @@ -1771,7 +1313,7 @@ def test_common_billing_account_path(): def test_parse_common_billing_account_path(): expected = { - "billing_account": "octopus", + "billing_account": "clam", } path = AlphaAnalyticsDataClient.common_billing_account_path(**expected) @@ -1781,7 +1323,7 @@ def test_parse_common_billing_account_path(): def test_common_folder_path(): - folder = "oyster" + folder = "whelk" expected = "folders/{folder}".format( folder=folder, ) @@ -1791,7 +1333,7 @@ def test_common_folder_path(): def test_parse_common_folder_path(): expected = { - "folder": "nudibranch", + "folder": "octopus", } path = AlphaAnalyticsDataClient.common_folder_path(**expected) @@ -1801,7 +1343,7 @@ def test_parse_common_folder_path(): def test_common_organization_path(): - organization = "cuttlefish" + organization = "oyster" expected = "organizations/{organization}".format( organization=organization, ) @@ -1811,7 +1353,7 @@ def test_common_organization_path(): def test_parse_common_organization_path(): expected = { - "organization": "mussel", + "organization": "nudibranch", } path = AlphaAnalyticsDataClient.common_organization_path(**expected) @@ -1821,7 +1363,7 @@ def test_parse_common_organization_path(): def test_common_project_path(): - project = "winkle" + project = "cuttlefish" expected = "projects/{project}".format( project=project, ) @@ -1831,7 +1373,7 @@ def test_common_project_path(): def test_parse_common_project_path(): expected = { - "project": "nautilus", + "project": "mussel", } path = AlphaAnalyticsDataClient.common_project_path(**expected) @@ -1841,8 +1383,8 @@ def test_parse_common_project_path(): def test_common_location_path(): - project = "scallop" - location = "abalone" + project = "winkle" + location = "nautilus" expected = "projects/{project}/locations/{location}".format( project=project, location=location, @@ -1853,8 +1395,8 @@ def test_common_location_path(): def test_parse_common_location_path(): expected = { - "project": "squid", - "location": "clam", + "project": "scallop", + "location": "abalone", } path = AlphaAnalyticsDataClient.common_location_path(**expected) @@ -1863,7 +1405,7 @@ def test_parse_common_location_path(): assert expected == actual -def test_client_withDEFAULT_CLIENT_INFO(): +def test_client_with_default_client_info(): client_info = gapic_v1.client_info.ClientInfo() with mock.patch.object( @@ -1884,3 +1426,83 @@ def test_client_withDEFAULT_CLIENT_INFO(): client_info=client_info, ) prep.assert_called_once_with(client_info) + + +@pytest.mark.asyncio +async def test_transport_close_async(): + client = AlphaAnalyticsDataAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc_asyncio", + ) + with mock.patch.object( + type(getattr(client.transport, "grpc_channel")), "close" + ) as close: + async with client: + close.assert_not_called() + close.assert_called_once() + + +def test_transport_close(): + transports = { + "grpc": "_grpc_channel", + } + + for transport, close_name in transports.items(): + client = AlphaAnalyticsDataClient( + credentials=ga_credentials.AnonymousCredentials(), transport=transport + ) + with mock.patch.object( + type(getattr(client.transport, close_name)), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + +def test_client_ctx(): + transports = [ + "grpc", + ] + for transport in transports: + client = AlphaAnalyticsDataClient( + credentials=ga_credentials.AnonymousCredentials(), transport=transport + ) + # Test client calls underlying transport. + with mock.patch.object(type(client.transport), "close") as close: + close.assert_not_called() + with client: + pass + close.assert_called() + + +@pytest.mark.parametrize( + "client_class,transport_class", + [ + (AlphaAnalyticsDataClient, transports.AlphaAnalyticsDataGrpcTransport), + ( + AlphaAnalyticsDataAsyncClient, + transports.AlphaAnalyticsDataGrpcAsyncIOTransport, + ), + ], +) +def test_api_key_credentials(client_class, transport_class): + with mock.patch.object( + google.auth._default, "get_api_key_credentials", create=True + ) as get_api_key_credentials: + mock_cred = mock.Mock() + get_api_key_credentials.return_value = mock_cred + options = client_options.ClientOptions() + options.api_key = "api_key" + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=mock_cred, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + )