diff --git a/CHANGELOG.md b/CHANGELOG.md index d1ee825..482d154 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,17 @@ # Changelog +## [0.6.0](https://www.github.com/googleapis/python-analytics-data/compare/v0.5.1...v0.6.0) (2021-06-08) + + +### Features + +* support self-signed JWT flow for service accounts ([ff2beb8](https://www.github.com/googleapis/python-analytics-data/commit/ff2beb8f923570a78772712dc140fc7ba99148d6)) + + +### Bug Fixes + +* add async client to %name_%version/init.py ([ff2beb8](https://www.github.com/googleapis/python-analytics-data/commit/ff2beb8f923570a78772712dc140fc7ba99148d6)) + ### [0.5.1](https://www.github.com/googleapis/python-analytics-data/compare/v0.5.0...v0.5.1) (2021-05-28) diff --git a/google/analytics/data/__init__.py b/google/analytics/data/__init__.py index f8a2f05..7f10e59 100644 --- a/google/analytics/data/__init__.py +++ b/google/analytics/data/__init__.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -15,12 +14,13 @@ # limitations under the License. # -from google.analytics.data_v1beta.services.beta_analytics_data.async_client import ( - BetaAnalyticsDataAsyncClient, -) from google.analytics.data_v1beta.services.beta_analytics_data.client import ( BetaAnalyticsDataClient, ) +from google.analytics.data_v1beta.services.beta_analytics_data.async_client import ( + BetaAnalyticsDataAsyncClient, +) + from google.analytics.data_v1beta.types.analytics_data_api import ( BatchRunPivotReportsRequest, ) @@ -57,10 +57,8 @@ from google.analytics.data_v1beta.types.data import FilterExpression from google.analytics.data_v1beta.types.data import FilterExpressionList from google.analytics.data_v1beta.types.data import Metric -from google.analytics.data_v1beta.types.data import MetricAggregation from google.analytics.data_v1beta.types.data import MetricHeader from google.analytics.data_v1beta.types.data import MetricMetadata -from google.analytics.data_v1beta.types.data import MetricType from google.analytics.data_v1beta.types.data import MetricValue from google.analytics.data_v1beta.types.data import NumericValue from google.analytics.data_v1beta.types.data import OrderBy @@ -71,14 +69,24 @@ from google.analytics.data_v1beta.types.data import QuotaStatus from google.analytics.data_v1beta.types.data import ResponseMetaData from google.analytics.data_v1beta.types.data import Row +from google.analytics.data_v1beta.types.data import MetricAggregation +from google.analytics.data_v1beta.types.data import MetricType __all__ = ( + "BetaAnalyticsDataClient", + "BetaAnalyticsDataAsyncClient", "BatchRunPivotReportsRequest", "BatchRunPivotReportsResponse", "BatchRunReportsRequest", "BatchRunReportsResponse", - "BetaAnalyticsDataAsyncClient", - "BetaAnalyticsDataClient", + "GetMetadataRequest", + "Metadata", + "RunPivotReportRequest", + "RunPivotReportResponse", + "RunRealtimeReportRequest", + "RunRealtimeReportResponse", + "RunReportRequest", + "RunReportResponse", "Cohort", "CohortReportSettings", "CohortSpec", @@ -92,13 +100,9 @@ "Filter", "FilterExpression", "FilterExpressionList", - "GetMetadataRequest", - "Metadata", "Metric", - "MetricAggregation", "MetricHeader", "MetricMetadata", - "MetricType", "MetricValue", "NumericValue", "OrderBy", @@ -109,10 +113,6 @@ "QuotaStatus", "ResponseMetaData", "Row", - "RunPivotReportRequest", - "RunPivotReportResponse", - "RunRealtimeReportRequest", - "RunRealtimeReportResponse", - "RunReportRequest", - "RunReportResponse", + "MetricAggregation", + "MetricType", ) diff --git a/google/analytics/data_v1alpha/__init__.py b/google/analytics/data_v1alpha/__init__.py index 63ad392..8674d50 100644 --- a/google/analytics/data_v1alpha/__init__.py +++ b/google/analytics/data_v1alpha/__init__.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,6 +15,8 @@ # 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 @@ -43,10 +44,8 @@ from .types.data import FilterExpression from .types.data import FilterExpressionList from .types.data import Metric -from .types.data import MetricAggregation from .types.data import MetricHeader from .types.data import MetricMetadata -from .types.data import MetricType from .types.data import MetricValue from .types.data import NumericValue from .types.data import OrderBy @@ -57,9 +56,12 @@ from .types.data import QuotaStatus from .types.data import ResponseMetaData from .types.data import Row - +from .types.data import MetricAggregation +from .types.data import MetricType __all__ = ( + "AlphaAnalyticsDataAsyncClient", + "AlphaAnalyticsDataClient", "BatchRunPivotReportsRequest", "BatchRunPivotReportsResponse", "BatchRunReportsRequest", @@ -101,5 +103,4 @@ "RunRealtimeReportResponse", "RunReportRequest", "RunReportResponse", - "AlphaAnalyticsDataClient", ) diff --git a/google/analytics/data_v1alpha/gapic_metadata.json b/google/analytics/data_v1alpha/gapic_metadata.json new file mode 100644 index 0000000..013b073 --- /dev/null +++ b/google/analytics/data_v1alpha/gapic_metadata.json @@ -0,0 +1,83 @@ + { + "comment": "This file maps proto services/RPCs to the corresponding library clients/methods", + "language": "python", + "libraryPackage": "google.analytics.data_v1alpha", + "protoPackage": "google.analytics.data.v1alpha", + "schema": "1.0", + "services": { + "AlphaAnalyticsData": { + "clients": { + "grpc": { + "libraryClient": "AlphaAnalyticsDataClient", + "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": { + "methods": [ + "run_report" + ] + } + } + }, + "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": { + "methods": [ + "run_report" + ] + } + } + } + } + } + } +} diff --git a/google/analytics/data_v1alpha/services/__init__.py b/google/analytics/data_v1alpha/services/__init__.py index 42ffdf2..4de6597 100644 --- a/google/analytics/data_v1alpha/services/__init__.py +++ b/google/analytics/data_v1alpha/services/__init__.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (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 9414ea0..57d375c 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,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,7 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # - from .client import AlphaAnalyticsDataClient from .async_client import AlphaAnalyticsDataAsyncClient 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 7d5a1fe..25dab26 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,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,7 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # - from collections import OrderedDict import functools import re @@ -22,15 +20,14 @@ import pkg_resources import google.api_core.client_options as ClientOptions # type: ignore -from google.api_core import exceptions # 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.auth import credentials # type: ignore +from google.auth import credentials as ga_credentials # type: ignore from google.oauth2 import service_account # 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 from .transports.grpc_asyncio import AlphaAnalyticsDataGrpcAsyncIOTransport from .client import AlphaAnalyticsDataClient @@ -46,31 +43,26 @@ class AlphaAnalyticsDataAsyncClient: metadata_path = staticmethod(AlphaAnalyticsDataClient.metadata_path) parse_metadata_path = staticmethod(AlphaAnalyticsDataClient.parse_metadata_path) - common_billing_account_path = staticmethod( AlphaAnalyticsDataClient.common_billing_account_path ) parse_common_billing_account_path = staticmethod( AlphaAnalyticsDataClient.parse_common_billing_account_path ) - common_folder_path = staticmethod(AlphaAnalyticsDataClient.common_folder_path) parse_common_folder_path = staticmethod( AlphaAnalyticsDataClient.parse_common_folder_path ) - common_organization_path = staticmethod( AlphaAnalyticsDataClient.common_organization_path ) parse_common_organization_path = staticmethod( AlphaAnalyticsDataClient.parse_common_organization_path ) - common_project_path = staticmethod(AlphaAnalyticsDataClient.common_project_path) parse_common_project_path = staticmethod( AlphaAnalyticsDataClient.parse_common_project_path ) - common_location_path = staticmethod(AlphaAnalyticsDataClient.common_location_path) parse_common_location_path = staticmethod( AlphaAnalyticsDataClient.parse_common_location_path @@ -78,7 +70,8 @@ class AlphaAnalyticsDataAsyncClient: @classmethod def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials info. + """Creates an instance of this client using the provided credentials + info. Args: info (dict): The service account private key info. @@ -93,7 +86,7 @@ def from_service_account_info(cls, info: dict, *args, **kwargs): @classmethod def from_service_account_file(cls, filename: str, *args, **kwargs): """Creates an instance of this client using the provided credentials - file. + file. Args: filename (str): The path to the service account private key json @@ -110,7 +103,7 @@ def from_service_account_file(cls, filename: str, *args, **kwargs): @property def transport(self) -> AlphaAnalyticsDataTransport: - """Return the transport used by the client instance. + """Returns the transport used by the client instance. Returns: AlphaAnalyticsDataTransport: The transport used by the client instance. @@ -125,12 +118,12 @@ def transport(self) -> AlphaAnalyticsDataTransport: def __init__( self, *, - credentials: credentials.Credentials = None, + credentials: ga_credentials.Credentials = None, transport: Union[str, AlphaAnalyticsDataTransport] = "grpc_asyncio", client_options: ClientOptions = None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: - """Instantiate the alpha analytics data client. + """Instantiates the alpha analytics data client. Args: credentials (Optional[google.auth.credentials.Credentials]): The @@ -162,7 +155,6 @@ def __init__( google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport creation failed for any reason. """ - self._client = AlphaAnalyticsDataClient( credentials=credentials, transport=transport, @@ -191,7 +183,6 @@ async def run_report( 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. @@ -205,7 +196,6 @@ async def run_report( """ # Create or coerce a protobuf request object. - request = analytics_data_api.RunReportRequest(request) # Wrap the RPC method; this adds retry and timeout information, @@ -241,7 +231,6 @@ async def run_pivot_report( 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. @@ -255,7 +244,6 @@ async def run_pivot_report( """ # Create or coerce a protobuf request object. - request = analytics_data_api.RunPivotReportRequest(request) # Wrap the RPC method; this adds retry and timeout information, @@ -287,7 +275,6 @@ async def batch_run_reports( 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. @@ -301,7 +288,6 @@ async def batch_run_reports( """ # Create or coerce a protobuf request object. - request = analytics_data_api.BatchRunReportsRequest(request) # Wrap the RPC method; this adds retry and timeout information, @@ -333,7 +319,6 @@ async def batch_run_pivot_reports( request (:class:`google.analytics.data_v1alpha.types.BatchRunPivotReportsRequest`): 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. @@ -347,7 +332,6 @@ async def batch_run_pivot_reports( """ # Create or coerce a protobuf request object. - request = analytics_data_api.BatchRunPivotReportsRequest(request) # Wrap the RPC method; this adds retry and timeout information, @@ -406,7 +390,6 @@ async def get_metadata( 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. @@ -433,7 +416,6 @@ async def get_metadata( # If we have keyword arguments corresponding to fields on the # request, apply these. - if name is not None: request.name = name @@ -474,7 +456,6 @@ async def run_realtime_report( 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. @@ -488,7 +469,6 @@ async def run_realtime_report( """ # Create or coerce a protobuf request object. - request = analytics_data_api.RunRealtimeReportRequest(request) # Wrap the RPC method; this adds retry and timeout information, 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 ddd0301..ac31ffb 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,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,7 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # - from collections import OrderedDict from distutils import util import os @@ -23,10 +21,10 @@ import pkg_resources from google.api_core import client_options as client_options_lib # type: ignore -from google.api_core import exceptions # 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.auth import credentials # type: ignore +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 @@ -34,7 +32,6 @@ 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 from .transports.grpc import AlphaAnalyticsDataGrpcTransport from .transports.grpc_asyncio import AlphaAnalyticsDataGrpcAsyncIOTransport @@ -57,7 +54,7 @@ class AlphaAnalyticsDataClientMeta(type): def get_transport_class( cls, label: str = None, ) -> Type[AlphaAnalyticsDataTransport]: - """Return an appropriate transport class. + """Returns an appropriate transport class. Args: label: The name of the desired transport. If none is @@ -80,7 +77,8 @@ class AlphaAnalyticsDataClient(metaclass=AlphaAnalyticsDataClientMeta): @staticmethod def _get_default_mtls_endpoint(api_endpoint): - """Convert api endpoint to mTLS endpoint. + """Converts api endpoint to mTLS endpoint. + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. Args: @@ -114,7 +112,8 @@ def _get_default_mtls_endpoint(api_endpoint): @classmethod def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials info. + """Creates an instance of this client using the provided credentials + info. Args: info (dict): The service account private key info. @@ -131,7 +130,7 @@ def from_service_account_info(cls, info: dict, *args, **kwargs): @classmethod def from_service_account_file(cls, filename: str, *args, **kwargs): """Creates an instance of this client using the provided credentials - file. + file. Args: filename (str): The path to the service account private key json @@ -150,27 +149,28 @@ def from_service_account_file(cls, filename: str, *args, **kwargs): @property def transport(self) -> AlphaAnalyticsDataTransport: - """Return the transport used by the client instance. + """Returns the transport used by the client instance. Returns: - AlphaAnalyticsDataTransport: The transport used by the client instance. + AlphaAnalyticsDataTransport: The transport used by the client + instance. """ return self._transport @staticmethod def metadata_path(property: str,) -> str: - """Return a fully-qualified metadata string.""" + """Returns a fully-qualified metadata string.""" return "properties/{property}/metadata".format(property=property,) @staticmethod def parse_metadata_path(path: str) -> Dict[str, str]: - """Parse a metadata path into its component segments.""" + """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,) -> str: - """Return a fully-qualified billing_account string.""" + """Returns a fully-qualified billing_account string.""" return "billingAccounts/{billing_account}".format( billing_account=billing_account, ) @@ -183,7 +183,7 @@ def parse_common_billing_account_path(path: str) -> Dict[str, str]: @staticmethod def common_folder_path(folder: str,) -> str: - """Return a fully-qualified folder string.""" + """Returns a fully-qualified folder string.""" return "folders/{folder}".format(folder=folder,) @staticmethod @@ -194,7 +194,7 @@ def parse_common_folder_path(path: str) -> Dict[str, str]: @staticmethod def common_organization_path(organization: str,) -> str: - """Return a fully-qualified organization string.""" + """Returns a fully-qualified organization string.""" return "organizations/{organization}".format(organization=organization,) @staticmethod @@ -205,7 +205,7 @@ def parse_common_organization_path(path: str) -> Dict[str, str]: @staticmethod def common_project_path(project: str,) -> str: - """Return a fully-qualified project string.""" + """Returns a fully-qualified project string.""" return "projects/{project}".format(project=project,) @staticmethod @@ -216,7 +216,7 @@ def parse_common_project_path(path: str) -> Dict[str, str]: @staticmethod def common_location_path(project: str, location: str,) -> str: - """Return a fully-qualified location string.""" + """Returns a fully-qualified location string.""" return "projects/{project}/locations/{location}".format( project=project, location=location, ) @@ -230,12 +230,12 @@ def parse_common_location_path(path: str) -> Dict[str, str]: def __init__( self, *, - credentials: Optional[credentials.Credentials] = None, + credentials: Optional[ga_credentials.Credentials] = None, transport: Union[str, AlphaAnalyticsDataTransport, None] = None, client_options: Optional[client_options_lib.ClientOptions] = None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: - """Instantiate the alpha analytics data client. + """Instantiates the alpha analytics data client. Args: credentials (Optional[google.auth.credentials.Credentials]): The @@ -290,9 +290,10 @@ def __init__( client_cert_source_func = client_options.client_cert_source else: is_mtls = mtls.has_default_client_cert_source() - client_cert_source_func = ( - mtls.default_client_cert_source() if is_mtls else None - ) + 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: @@ -304,12 +305,14 @@ def __init__( elif use_mtls_env == "always": api_endpoint = self.DEFAULT_MTLS_ENDPOINT elif use_mtls_env == "auto": - api_endpoint = ( - self.DEFAULT_MTLS_ENDPOINT if is_mtls else self.DEFAULT_ENDPOINT - ) + 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" + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" ) # Save or instantiate the transport. @@ -324,8 +327,8 @@ def __init__( ) if client_options.scopes: raise ValueError( - "When providing a transport instance, " - "provide its scopes directly." + "When providing a transport instance, provide its scopes " + "directly." ) self._transport = transport else: @@ -361,7 +364,6 @@ def run_report( Args: request (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. @@ -375,7 +377,6 @@ def run_report( """ # 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 @@ -412,7 +413,6 @@ def run_pivot_report( request (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. @@ -426,7 +426,6 @@ def run_pivot_report( """ # 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 @@ -459,7 +458,6 @@ def batch_run_reports( request (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. @@ -473,7 +471,6 @@ def batch_run_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 @@ -506,7 +503,6 @@ def batch_run_pivot_reports( request (google.analytics.data_v1alpha.types.BatchRunPivotReportsRequest): 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. @@ -520,7 +516,6 @@ def batch_run_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 @@ -580,7 +575,6 @@ def get_metadata( 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. @@ -609,10 +603,8 @@ def get_metadata( # 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 @@ -649,7 +641,6 @@ def run_realtime_report( request (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. @@ -663,7 +654,6 @@ def run_realtime_report( """ # 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 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 77f8bc5..6220a7a 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,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,7 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # - from collections import OrderedDict from typing import Dict, Type 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 f45d8d2..db59832 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,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,20 +13,20 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import abc -import typing +from typing import Awaitable, Callable, Dict, Optional, Sequence, Union +import packaging.version import pkg_resources -from google import auth # type: ignore -from google.api_core import exceptions # type: ignore +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore from google.api_core import gapic_v1 # type: ignore from google.api_core import retry as retries # type: ignore -from google.auth import credentials # type: ignore +from google.auth import credentials as ga_credentials # type: ignore from google.analytics.data_v1alpha.types import analytics_data_api - try: DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( gapic_version=pkg_resources.get_distribution("google-analytics-data",).version, @@ -35,6 +34,17 @@ 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 + +_API_CORE_VERSION = google.api_core.__version__ + class AlphaAnalyticsDataTransport(abc.ABC): """Abstract transport class for AlphaAnalyticsData.""" @@ -44,21 +54,24 @@ class AlphaAnalyticsDataTransport(abc.ABC): "https://www.googleapis.com/auth/analytics.readonly", ) + DEFAULT_HOST: str = "analyticsdata.googleapis.com" + def __init__( self, *, - host: str = "analyticsdata.googleapis.com", - credentials: credentials.Credentials = None, - credentials_file: typing.Optional[str] = None, - scopes: typing.Optional[typing.Sequence[str]] = AUTH_SCOPES, - quota_project_id: typing.Optional[str] = None, + host: str = DEFAULT_HOST, + credentials: ga_credentials.Credentials = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, **kwargs, ) -> None: """Instantiate the transport. Args: - host (Optional[str]): The hostname to connect to. + host (Optional[str]): + The hostname to connect to. credentials (Optional[google.auth.credentials.Credentials]): The authorization credentials to attach to requests. These credentials identify the application to the service; if none @@ -67,7 +80,7 @@ def __init__( credentials_file (Optional[str]): A file with credentials that can be loaded with :func:`google.auth.load_credentials_from_file`. This argument is mutually exclusive with credentials. - scope (Optional[Sequence[str]]): A list of scopes. + scopes (Optional[Sequence[str]]): A list of scopes. quota_project_id (Optional[str]): An optional project to use for billing and quota. client_info (google.api_core.gapic_v1.client_info.ClientInfo): @@ -81,29 +94,76 @@ def __init__( host += ":443" self._host = host + scopes_kwargs = self._get_scopes_kwargs(self._host, scopes) + # Save the scopes. self._scopes = scopes or self.AUTH_SCOPES # If no credentials are provided, then determine the appropriate # defaults. if credentials and credentials_file: - raise exceptions.DuplicateCredentialArgs( + raise core_exceptions.DuplicateCredentialArgs( "'credentials_file' and 'credentials' are mutually exclusive" ) if credentials_file is not None: - credentials, _ = auth.load_credentials_from_file( - credentials_file, scopes=self._scopes, quota_project_id=quota_project_id + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, **scopes_kwargs, quota_project_id=quota_project_id ) elif credentials is None: - credentials, _ = auth.default( - scopes=self._scopes, quota_project_id=quota_project_id + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id ) # Save the credentials. self._credentials = credentials + # TODO(busunkim): These two class methods are in the base transport + # to avoid duplicating code across the transport classes. These functions + # should be deleted once the minimum required versions of google-api-core + # and google-auth are 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 + + # TODO: Remove this function once google-api-core >= 1.26.0 is required + @classmethod + def _get_self_signed_jwt_kwargs( + cls, host: str, scopes: Optional[Sequence[str]] + ) -> Dict[str, Union[Optional[Sequence[str]], str]]: + """Returns kwargs to pass to grpc_helpers.create_channel depending on the google-api-core version""" + + self_signed_jwt_kwargs: Dict[str, Union[Optional[Sequence[str]], str]] = {} + + if _API_CORE_VERSION and ( + packaging.version.parse(_API_CORE_VERSION) + >= packaging.version.parse("1.26.0") + ): + self_signed_jwt_kwargs["default_scopes"] = cls.AUTH_SCOPES + self_signed_jwt_kwargs["scopes"] = scopes + self_signed_jwt_kwargs["default_host"] = cls.DEFAULT_HOST + else: + self_signed_jwt_kwargs["scopes"] = scopes or cls.AUTH_SCOPES + + return self_signed_jwt_kwargs + def _prep_wrapped_messages(self, client_info): # Precompute the wrapped methods. self._wrapped_methods = { @@ -132,11 +192,11 @@ def _prep_wrapped_messages(self, client_info): @property def run_report( self, - ) -> typing.Callable[ + ) -> Callable[ [analytics_data_api.RunReportRequest], - typing.Union[ + Union[ analytics_data_api.RunReportResponse, - typing.Awaitable[analytics_data_api.RunReportResponse], + Awaitable[analytics_data_api.RunReportResponse], ], ]: raise NotImplementedError() @@ -144,11 +204,11 @@ def run_report( @property def run_pivot_report( self, - ) -> typing.Callable[ + ) -> Callable[ [analytics_data_api.RunPivotReportRequest], - typing.Union[ + Union[ analytics_data_api.RunPivotReportResponse, - typing.Awaitable[analytics_data_api.RunPivotReportResponse], + Awaitable[analytics_data_api.RunPivotReportResponse], ], ]: raise NotImplementedError() @@ -156,11 +216,11 @@ def run_pivot_report( @property def batch_run_reports( self, - ) -> typing.Callable[ + ) -> Callable[ [analytics_data_api.BatchRunReportsRequest], - typing.Union[ + Union[ analytics_data_api.BatchRunReportsResponse, - typing.Awaitable[analytics_data_api.BatchRunReportsResponse], + Awaitable[analytics_data_api.BatchRunReportsResponse], ], ]: raise NotImplementedError() @@ -168,11 +228,11 @@ def batch_run_reports( @property def batch_run_pivot_reports( self, - ) -> typing.Callable[ + ) -> Callable[ [analytics_data_api.BatchRunPivotReportsRequest], - typing.Union[ + Union[ analytics_data_api.BatchRunPivotReportsResponse, - typing.Awaitable[analytics_data_api.BatchRunPivotReportsResponse], + Awaitable[analytics_data_api.BatchRunPivotReportsResponse], ], ]: raise NotImplementedError() @@ -180,22 +240,20 @@ def batch_run_pivot_reports( @property def get_metadata( self, - ) -> typing.Callable[ + ) -> Callable[ [analytics_data_api.GetMetadataRequest], - typing.Union[ - analytics_data_api.Metadata, typing.Awaitable[analytics_data_api.Metadata] - ], + Union[analytics_data_api.Metadata, Awaitable[analytics_data_api.Metadata]], ]: raise NotImplementedError() @property def run_realtime_report( self, - ) -> typing.Callable[ + ) -> Callable[ [analytics_data_api.RunRealtimeReportRequest], - typing.Union[ + Union[ analytics_data_api.RunRealtimeReportResponse, - typing.Awaitable[analytics_data_api.RunRealtimeReportResponse], + Awaitable[analytics_data_api.RunRealtimeReportResponse], ], ]: 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 5a08f8f..3e6e1b8 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,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,20 +13,18 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple +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 import auth # type: ignore -from google.auth import credentials # type: ignore +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore import grpc # type: ignore from google.analytics.data_v1alpha.types import analytics_data_api - from .base import AlphaAnalyticsDataTransport, DEFAULT_CLIENT_INFO @@ -50,7 +47,7 @@ def __init__( self, *, host: str = "analyticsdata.googleapis.com", - credentials: credentials.Credentials = None, + credentials: ga_credentials.Credentials = None, credentials_file: str = None, scopes: Sequence[str] = None, channel: grpc.Channel = None, @@ -64,7 +61,8 @@ def __init__( """Instantiate the transport. Args: - host (Optional[str]): The hostname to connect to. + host (Optional[str]): + The hostname to connect to. credentials (Optional[google.auth.credentials.Credentials]): The authorization credentials to attach to requests. These credentials identify the application to the service; if none @@ -174,7 +172,7 @@ def __init__( def create_channel( cls, host: str = "analyticsdata.googleapis.com", - credentials: credentials.Credentials = None, + credentials: ga_credentials.Credentials = None, credentials_file: str = None, scopes: Optional[Sequence[str]] = None, quota_project_id: Optional[str] = None, @@ -205,13 +203,15 @@ def create_channel( google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` and ``credentials_file`` are passed. """ - scopes = scopes or cls.AUTH_SCOPES + + self_signed_jwt_kwargs = cls._get_self_signed_jwt_kwargs(host, scopes) + return grpc_helpers.create_channel( host, credentials=credentials, credentials_file=credentials_file, - scopes=scopes, quota_project_id=quota_project_id, + **self_signed_jwt_kwargs, **kwargs, ) 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 031af21..c63da4a 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,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,21 +13,19 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple +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 import auth # type: ignore -from google.auth import credentials # type: ignore +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 from google.analytics.data_v1alpha.types import analytics_data_api - from .base import AlphaAnalyticsDataTransport, DEFAULT_CLIENT_INFO from .grpc import AlphaAnalyticsDataGrpcTransport @@ -53,7 +50,7 @@ class AlphaAnalyticsDataGrpcAsyncIOTransport(AlphaAnalyticsDataTransport): def create_channel( cls, host: str = "analyticsdata.googleapis.com", - credentials: credentials.Credentials = None, + credentials: ga_credentials.Credentials = None, credentials_file: Optional[str] = None, scopes: Optional[Sequence[str]] = None, quota_project_id: Optional[str] = None, @@ -80,13 +77,15 @@ def create_channel( Returns: aio.Channel: A gRPC AsyncIO channel object. """ - scopes = scopes or cls.AUTH_SCOPES + + self_signed_jwt_kwargs = cls._get_self_signed_jwt_kwargs(host, scopes) + return grpc_helpers_async.create_channel( host, credentials=credentials, credentials_file=credentials_file, - scopes=scopes, quota_project_id=quota_project_id, + **self_signed_jwt_kwargs, **kwargs, ) @@ -94,7 +93,7 @@ def __init__( self, *, host: str = "analyticsdata.googleapis.com", - credentials: credentials.Credentials = None, + credentials: ga_credentials.Credentials = None, credentials_file: Optional[str] = None, scopes: Optional[Sequence[str]] = None, channel: aio.Channel = None, @@ -108,7 +107,8 @@ def __init__( """Instantiate the transport. Args: - host (Optional[str]): The hostname to connect to. + host (Optional[str]): + The hostname to connect to. credentials (Optional[google.auth.credentials.Credentials]): The authorization credentials to attach to requests. These credentials identify the application to the service; if none @@ -166,7 +166,6 @@ def __init__( # If a channel was explicitly provided, set it. self._grpc_channel = channel self._ssl_channel_credentials = None - else: if api_mtls_endpoint: host = api_mtls_endpoint diff --git a/google/analytics/data_v1alpha/types/__init__.py b/google/analytics/data_v1alpha/types/__init__.py index 298cbc2..6ebcb97 100644 --- a/google/analytics/data_v1alpha/types/__init__.py +++ b/google/analytics/data_v1alpha/types/__init__.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,7 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # - from .analytics_data_api import ( BatchRunPivotReportsRequest, BatchRunPivotReportsResponse, diff --git a/google/analytics/data_v1alpha/types/analytics_data_api.py b/google/analytics/data_v1alpha/types/analytics_data_api.py index 30a98d8..a57f8e5 100644 --- a/google/analytics/data_v1alpha/types/analytics_data_api.py +++ b/google/analytics/data_v1alpha/types/analytics_data_api.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,10 +13,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import proto # type: ignore - from google.analytics.data_v1alpha.types import data @@ -53,18 +50,15 @@ class Metadata(proto.Message): The metric descriptions. """ - name = proto.Field(proto.STRING, number=3) - + 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,) 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 @@ -131,41 +125,27 @@ class RunReportRequest(proto.Message): """ 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) - + 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) - + 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) + 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 @@ -204,29 +184,20 @@ class RunReportResponse(proto.Message): 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) - + 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 @@ -287,28 +258,18 @@ class RunPivotReportRequest(proto.Message): """ 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,) - dimension_filter = proto.Field( proto.MESSAGE, number=4, message=data.FilterExpression, ) - metric_filter = proto.Field(proto.MESSAGE, number=5, message=data.FilterExpression,) - pivots = proto.RepeatedField(proto.MESSAGE, number=6, message=data.Pivot,) - date_ranges = proto.RepeatedField(proto.MESSAGE, number=7, message=data.DateRange,) - - currency_code = proto.Field(proto.STRING, number=8) - + currency_code = proto.Field(proto.STRING, number=8,) cohort_spec = proto.Field(proto.MESSAGE, number=9, message=data.CohortSpec,) - - keep_empty_rows = proto.Field(proto.BOOL, number=10) - - return_property_quota = proto.Field(proto.BOOL, number=11) + keep_empty_rows = proto.Field(proto.BOOL, number=10,) + return_property_quota = proto.Field(proto.BOOL, number=11,) class RunPivotReportResponse(proto.Message): @@ -385,27 +346,20 @@ class RunPivotReportResponse(proto.Message): pivot_headers = proto.RepeatedField( proto.MESSAGE, number=1, message=data.PivotHeader, ) - dimension_headers = proto.RepeatedField( proto.MESSAGE, number=7, message=data.DimensionHeader, ) - metric_headers = proto.RepeatedField( 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,) - property_quota = proto.Field(proto.MESSAGE, number=6, 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 @@ -419,13 +373,11 @@ class BatchRunReportsRequest(proto.Message): """ 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 @@ -437,7 +389,6 @@ class BatchRunReportsResponse(proto.Message): 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 @@ -451,7 +402,6 @@ class BatchRunPivotReportsRequest(proto.Message): """ entity = proto.Field(proto.MESSAGE, number=1, message=data.Entity,) - requests = proto.RepeatedField( proto.MESSAGE, number=2, message="RunPivotReportRequest", ) @@ -459,7 +409,6 @@ class BatchRunPivotReportsRequest(proto.Message): 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 @@ -473,7 +422,6 @@ class BatchRunPivotReportsResponse(proto.Message): 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. @@ -490,12 +438,11 @@ class GetMetadataRequest(proto.Message): not return custom dimensions and metrics. """ - name = proto.Field(proto.STRING, number=1) + name = 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 @@ -535,27 +482,19 @@ class RunRealtimeReportRequest(proto.Message): `PropertyQuota <#PropertyQuota>`__. """ - property = proto.Field(proto.STRING, number=1) - + 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) - + 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) + return_property_quota = proto.Field(proto.BOOL, number=9,) class RunRealtimeReportResponse(proto.Message): @@ -595,21 +534,14 @@ class RunRealtimeReportResponse(proto.Message): 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) - + row_count = proto.Field(proto.INT32, number=7,) property_quota = proto.Field(proto.MESSAGE, number=8, message=data.PropertyQuota,) diff --git a/google/analytics/data_v1alpha/types/data.py b/google/analytics/data_v1alpha/types/data.py index 05606cb..5361526 100644 --- a/google/analytics/data_v1alpha/types/data.py +++ b/google/analytics/data_v1alpha/types/data.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,7 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import proto # type: ignore @@ -105,11 +103,9 @@ class DateRange(proto.Message): in the request: ``date_range_0``, ``date_range_1``, etc. """ - start_date = proto.Field(proto.STRING, number=1) - - end_date = proto.Field(proto.STRING, number=2) - - name = proto.Field(proto.STRING, number=3) + start_date = proto.Field(proto.STRING, number=1,) + end_date = proto.Field(proto.STRING, number=2,) + name = proto.Field(proto.STRING, number=3,) class Entity(proto.Message): @@ -123,7 +119,7 @@ class Entity(proto.Message): ID `__. """ - property_id = proto.Field(proto.STRING, number=1) + property_id = proto.Field(proto.STRING, number=1,) class Dimension(proto.Message): @@ -154,8 +150,7 @@ class Dimension(proto.Message): ", ", city). """ - name = proto.Field(proto.STRING, number=1) - + name = proto.Field(proto.STRING, number=1,) dimension_expression = proto.Field( proto.MESSAGE, number=2, message="DimensionExpression", ) @@ -183,18 +178,16 @@ class DimensionExpression(proto.Message): 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 to a name in dimensions field of the request. """ - dimension_name = proto.Field(proto.STRING, number=1) + dimension_name = proto.Field(proto.STRING, number=1,) 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 @@ -211,18 +204,15 @@ class ConcatenateExpression(proto.Message): response will contain "US,FR,JP". """ - dimension_names = proto.RepeatedField(proto.STRING, number=1) - - delimiter = proto.Field(proto.STRING, number=2) + dimension_names = proto.RepeatedField(proto.STRING, number=1,) + delimiter = proto.Field(proto.STRING, number=2,) lower_case = proto.Field( proto.MESSAGE, number=4, oneof="one_expression", message=CaseExpression, ) - upper_case = proto.Field( proto.MESSAGE, number=5, oneof="one_expression", message=CaseExpression, ) - concatenate = proto.Field( proto.MESSAGE, number=6, oneof="one_expression", message=ConcatenateExpression, ) @@ -257,11 +247,9 @@ class Metric(proto.Message): ``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) + 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): @@ -285,21 +273,17 @@ class FilterExpression(proto.Message): and_group = proto.Field( proto.MESSAGE, number=1, oneof="expr", message="FilterExpressionList", ) - or_group = proto.Field( proto.MESSAGE, number=2, oneof="expr", message="FilterExpressionList", ) - not_expression = proto.Field( proto.MESSAGE, number=3, oneof="expr", message="FilterExpression", ) - filter = proto.Field(proto.MESSAGE, number=4, oneof="expr", message="Filter",) class FilterExpressionList(proto.Message): r"""A list of filter expressions. - Attributes: expressions (Sequence[google.analytics.data_v1alpha.types.FilterExpression]): A list of filter expressions. @@ -312,7 +296,6 @@ class FilterExpressionList(proto.Message): class Filter(proto.Message): r"""An expression to filter dimension or metric values. - Attributes: field_name (str): The dimension name or metric name. Must be a @@ -336,7 +319,6 @@ class Filter(proto.Message): 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. @@ -359,14 +341,11 @@ class MatchType(proto.Enum): 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) + 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. @@ -375,13 +354,11 @@ class InListFilter(proto.Message): If true, the string value is case sensitive. """ - values = proto.RepeatedField(proto.STRING, number=1) - - case_sensitive = proto.Field(proto.BOOL, number=2) + 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. @@ -401,7 +378,6 @@ class Operation(proto.Enum): operation = proto.Field( proto.ENUM, number=1, enum="Filter.NumericFilter.Operation", ) - value = proto.Field(proto.MESSAGE, number=2, message="NumericValue",) class BetweenFilter(proto.Message): @@ -416,25 +392,19 @@ class BetweenFilter(proto.Message): """ from_value = proto.Field(proto.MESSAGE, number=1, message="NumericValue",) - to_value = proto.Field(proto.MESSAGE, number=2, message="NumericValue",) - field_name = proto.Field(proto.STRING, number=1) - - null_filter = proto.Field(proto.BOOL, number=2, 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, oneof="one_filter", message=StringFilter, ) - in_list_filter = proto.Field( proto.MESSAGE, number=4, oneof="one_filter", message=InListFilter, ) - numeric_filter = proto.Field( proto.MESSAGE, number=5, oneof="one_filter", message=NumericFilter, ) - between_filter = proto.Field( proto.MESSAGE, number=6, oneof="one_filter", message=BetweenFilter, ) @@ -442,7 +412,6 @@ class BetweenFilter(proto.Message): class OrderBy(proto.Message): r"""The sort options. - Attributes: metric (google.analytics.data_v1alpha.types.OrderBy.MetricOrderBy): Sorts results by a metric's values. @@ -457,17 +426,15 @@ class OrderBy(proto.Message): 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) + 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. @@ -483,15 +450,13 @@ class OrderType(proto.Enum): CASE_INSENSITIVE_ALPHANUMERIC = 2 NUMERIC = 3 - dimension_name = proto.Field(proto.STRING, number=1) - + 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 @@ -533,12 +498,10 @@ class PivotSelection(proto.Message): 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) + 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", ) @@ -546,16 +509,13 @@ class PivotSelection(proto.Message): metric = proto.Field( proto.MESSAGE, number=1, oneof="one_order_by", message=MetricOrderBy, ) - dimension = proto.Field( proto.MESSAGE, number=2, oneof="one_order_by", message=DimensionOrderBy, ) - pivot = proto.Field( proto.MESSAGE, number=3, oneof="one_order_by", message=PivotOrderBy, ) - - desc = proto.Field(proto.BOOL, number=4) + desc = proto.Field(proto.BOOL, number=4,) class Pivot(proto.Message): @@ -589,14 +549,10 @@ class Pivot(proto.Message): specified metric_aggregations. """ - field_names = proto.RepeatedField(proto.STRING, number=1) - + field_names = proto.RepeatedField(proto.STRING, number=1,) order_bys = proto.RepeatedField(proto.MESSAGE, number=2, message="OrderBy",) - - offset = proto.Field(proto.INT64, number=3) - - limit = proto.Field(proto.INT64, number=4) - + offset = proto.Field(proto.INT64, number=3,) + limit = proto.Field(proto.INT64, number=4,) metric_aggregations = proto.RepeatedField( proto.ENUM, number=5, enum="MetricAggregation", ) @@ -635,9 +591,7 @@ class CohortSpec(proto.Message): """ cohorts = proto.RepeatedField(proto.MESSAGE, number=1, message="Cohort",) - cohorts_range = proto.Field(proto.MESSAGE, number=2, message="CohortsRange",) - cohort_report_settings = proto.Field( proto.MESSAGE, number=3, message="CohortReportSettings", ) @@ -682,10 +636,8 @@ class Cohort(proto.Message): month. """ - name = proto.Field(proto.STRING, number=1) - - dimension = proto.Field(proto.STRING, number=2) - + name = proto.Field(proto.STRING, number=1,) + dimension = proto.Field(proto.STRING, number=2,) date_range = proto.Field(proto.MESSAGE, number=3, message="DateRange",) @@ -746,22 +698,19 @@ class Granularity(proto.Enum): MONTHLY = 3 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) + start_offset = proto.Field(proto.INT32, number=2,) + end_offset = proto.Field(proto.INT32, number=3,) 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``. """ - accumulate = proto.Field(proto.BOOL, number=1) + accumulate = proto.Field(proto.BOOL, number=1,) class ResponseMetaData(proto.Message): @@ -775,7 +724,7 @@ class ResponseMetaData(proto.Message): can happen for high cardinality reports. """ - data_loss_from_other_row = proto.Field(proto.BOOL, number=3) + data_loss_from_other_row = proto.Field(proto.BOOL, number=3,) class DimensionHeader(proto.Message): @@ -790,7 +739,7 @@ class DimensionHeader(proto.Message): The dimension's name. """ - name = proto.Field(proto.STRING, number=1) + name = proto.Field(proto.STRING, number=1,) class MetricHeader(proto.Message): @@ -807,14 +756,12 @@ class MetricHeader(proto.Message): The metric's data type. """ - name = proto.Field(proto.STRING, number=1) - + name = proto.Field(proto.STRING, number=1,) type_ = proto.Field(proto.ENUM, number=2, enum="MetricType",) 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 @@ -830,13 +777,11 @@ class PivotHeader(proto.Message): pivot_dimension_headers = proto.RepeatedField( proto.MESSAGE, number=1, message="PivotDimensionHeader", ) - - row_count = proto.Field(proto.INT32, number=2) + 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. @@ -897,36 +842,32 @@ class Row(proto.Message): dimension_values = proto.RepeatedField( proto.MESSAGE, number=1, message="DimensionValue", ) - metric_values = proto.RepeatedField(proto.MESSAGE, number=2, message="MetricValue",) class DimensionValue(proto.Message): r"""The value of a dimension. - Attributes: value (str): Value as a string if the dimension type is a string. """ - value = proto.Field(proto.STRING, number=1, oneof="one_value") + value = proto.Field(proto.STRING, number=1, oneof="one_value",) class MetricValue(proto.Message): r"""The value of a metric. - Attributes: value (str): Measurement value. See MetricHeader for type. """ - value = proto.Field(proto.STRING, number=4, oneof="one_value") + value = proto.Field(proto.STRING, number=4, oneof="one_value",) class NumericValue(proto.Message): r"""To represent a number. - Attributes: int64_value (int): Integer value @@ -934,9 +875,8 @@ class NumericValue(proto.Message): Double value """ - int64_value = proto.Field(proto.INT64, number=1, oneof="one_value") - - double_value = proto.Field(proto.DOUBLE, number=2, oneof="one_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): @@ -970,11 +910,8 @@ class PropertyQuota(proto.Message): """ tokens_per_day = proto.Field(proto.MESSAGE, number=1, message="QuotaStatus",) - tokens_per_hour = proto.Field(proto.MESSAGE, number=2, message="QuotaStatus",) - concurrent_requests = proto.Field(proto.MESSAGE, number=3, message="QuotaStatus",) - server_errors_per_project_per_hour = proto.Field( proto.MESSAGE, number=4, message="QuotaStatus", ) @@ -982,7 +919,6 @@ class PropertyQuota(proto.Message): class QuotaStatus(proto.Message): r"""Current state for a particular quota group. - Attributes: consumed (int): Quota consumed by this request. @@ -990,14 +926,12 @@ class QuotaStatus(proto.Message): Quota remaining after this request. """ - consumed = proto.Field(proto.INT32, number=1) - - remaining = proto.Field(proto.INT32, number=2) + consumed = proto.Field(proto.INT32, number=1,) + remaining = proto.Field(proto.INT32, number=2,) class DimensionMetadata(proto.Message): r"""Explains a dimension. - Attributes: api_name (str): This dimension's name. Useable in @@ -1020,20 +954,15 @@ class DimensionMetadata(proto.Message): for this property. """ - api_name = proto.Field(proto.STRING, number=1) - - ui_name = proto.Field(proto.STRING, number=2) - - description = proto.Field(proto.STRING, number=3) - - deprecated_api_names = proto.RepeatedField(proto.STRING, number=4) - - custom_definition = proto.Field(proto.BOOL, number=5) + api_name = proto.Field(proto.STRING, number=1,) + ui_name = proto.Field(proto.STRING, number=2,) + description = proto.Field(proto.STRING, number=3,) + deprecated_api_names = proto.RepeatedField(proto.STRING, number=4,) + custom_definition = proto.Field(proto.BOOL, number=5,) class MetricMetadata(proto.Message): r"""Explains a metric. - Attributes: api_name (str): A metric name. Useable in `Metric <#Metric>`__'s ``name``. @@ -1062,19 +991,13 @@ class MetricMetadata(proto.Message): this property. """ - api_name = proto.Field(proto.STRING, number=1) - - ui_name = proto.Field(proto.STRING, number=2) - - description = proto.Field(proto.STRING, number=3) - - deprecated_api_names = proto.RepeatedField(proto.STRING, number=4) - + api_name = proto.Field(proto.STRING, number=1,) + ui_name = proto.Field(proto.STRING, number=2,) + description = proto.Field(proto.STRING, number=3,) + deprecated_api_names = proto.RepeatedField(proto.STRING, number=4,) type_ = proto.Field(proto.ENUM, number=5, enum="MetricType",) - - expression = proto.Field(proto.STRING, number=6) - - custom_definition = proto.Field(proto.BOOL, number=7) + expression = proto.Field(proto.STRING, number=6,) + custom_definition = proto.Field(proto.BOOL, number=7,) __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/analytics/data_v1beta/__init__.py b/google/analytics/data_v1beta/__init__.py index 40584d8..b7282cc 100644 --- a/google/analytics/data_v1beta/__init__.py +++ b/google/analytics/data_v1beta/__init__.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,6 +15,8 @@ # from .services.beta_analytics_data import BetaAnalyticsDataClient +from .services.beta_analytics_data import BetaAnalyticsDataAsyncClient + from .types.analytics_data_api import BatchRunPivotReportsRequest from .types.analytics_data_api import BatchRunPivotReportsResponse from .types.analytics_data_api import BatchRunReportsRequest @@ -42,10 +43,8 @@ from .types.data import FilterExpression from .types.data import FilterExpressionList from .types.data import Metric -from .types.data import MetricAggregation from .types.data import MetricHeader from .types.data import MetricMetadata -from .types.data import MetricType from .types.data import MetricValue from .types.data import NumericValue from .types.data import OrderBy @@ -56,13 +55,16 @@ from .types.data import QuotaStatus from .types.data import ResponseMetaData from .types.data import Row - +from .types.data import MetricAggregation +from .types.data import MetricType __all__ = ( + "BetaAnalyticsDataAsyncClient", "BatchRunPivotReportsRequest", "BatchRunPivotReportsResponse", "BatchRunReportsRequest", "BatchRunReportsResponse", + "BetaAnalyticsDataClient", "Cohort", "CohortReportSettings", "CohortSpec", @@ -99,5 +101,4 @@ "RunRealtimeReportResponse", "RunReportRequest", "RunReportResponse", - "BetaAnalyticsDataClient", ) diff --git a/google/analytics/data_v1beta/gapic_metadata.json b/google/analytics/data_v1beta/gapic_metadata.json new file mode 100644 index 0000000..b515c4d --- /dev/null +++ b/google/analytics/data_v1beta/gapic_metadata.json @@ -0,0 +1,83 @@ + { + "comment": "This file maps proto services/RPCs to the corresponding library clients/methods", + "language": "python", + "libraryPackage": "google.analytics.data_v1beta", + "protoPackage": "google.analytics.data.v1beta", + "schema": "1.0", + "services": { + "BetaAnalyticsData": { + "clients": { + "grpc": { + "libraryClient": "BetaAnalyticsDataClient", + "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": { + "methods": [ + "run_report" + ] + } + } + }, + "grpc-async": { + "libraryClient": "BetaAnalyticsDataAsyncClient", + "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": { + "methods": [ + "run_report" + ] + } + } + } + } + } + } +} diff --git a/google/analytics/data_v1beta/services/__init__.py b/google/analytics/data_v1beta/services/__init__.py index 42ffdf2..4de6597 100644 --- a/google/analytics/data_v1beta/services/__init__.py +++ b/google/analytics/data_v1beta/services/__init__.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/google/analytics/data_v1beta/services/beta_analytics_data/__init__.py b/google/analytics/data_v1beta/services/beta_analytics_data/__init__.py index 2bae762..526cdcd 100644 --- a/google/analytics/data_v1beta/services/beta_analytics_data/__init__.py +++ b/google/analytics/data_v1beta/services/beta_analytics_data/__init__.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,7 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # - from .client import BetaAnalyticsDataClient from .async_client import BetaAnalyticsDataAsyncClient diff --git a/google/analytics/data_v1beta/services/beta_analytics_data/async_client.py b/google/analytics/data_v1beta/services/beta_analytics_data/async_client.py index a23ad74..c8be304 100644 --- a/google/analytics/data_v1beta/services/beta_analytics_data/async_client.py +++ b/google/analytics/data_v1beta/services/beta_analytics_data/async_client.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,7 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # - from collections import OrderedDict import functools import re @@ -22,15 +20,14 @@ import pkg_resources import google.api_core.client_options as ClientOptions # type: ignore -from google.api_core import exceptions # 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.auth import credentials # type: ignore +from google.auth import credentials as ga_credentials # type: ignore from google.oauth2 import service_account # type: ignore from google.analytics.data_v1beta.types import analytics_data_api from google.analytics.data_v1beta.types import data - from .transports.base import BetaAnalyticsDataTransport, DEFAULT_CLIENT_INFO from .transports.grpc_asyncio import BetaAnalyticsDataGrpcAsyncIOTransport from .client import BetaAnalyticsDataClient @@ -46,31 +43,26 @@ class BetaAnalyticsDataAsyncClient: metadata_path = staticmethod(BetaAnalyticsDataClient.metadata_path) parse_metadata_path = staticmethod(BetaAnalyticsDataClient.parse_metadata_path) - common_billing_account_path = staticmethod( BetaAnalyticsDataClient.common_billing_account_path ) parse_common_billing_account_path = staticmethod( BetaAnalyticsDataClient.parse_common_billing_account_path ) - common_folder_path = staticmethod(BetaAnalyticsDataClient.common_folder_path) parse_common_folder_path = staticmethod( BetaAnalyticsDataClient.parse_common_folder_path ) - common_organization_path = staticmethod( BetaAnalyticsDataClient.common_organization_path ) parse_common_organization_path = staticmethod( BetaAnalyticsDataClient.parse_common_organization_path ) - common_project_path = staticmethod(BetaAnalyticsDataClient.common_project_path) parse_common_project_path = staticmethod( BetaAnalyticsDataClient.parse_common_project_path ) - common_location_path = staticmethod(BetaAnalyticsDataClient.common_location_path) parse_common_location_path = staticmethod( BetaAnalyticsDataClient.parse_common_location_path @@ -78,7 +70,8 @@ class BetaAnalyticsDataAsyncClient: @classmethod def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials info. + """Creates an instance of this client using the provided credentials + info. Args: info (dict): The service account private key info. @@ -93,7 +86,7 @@ def from_service_account_info(cls, info: dict, *args, **kwargs): @classmethod def from_service_account_file(cls, filename: str, *args, **kwargs): """Creates an instance of this client using the provided credentials - file. + file. Args: filename (str): The path to the service account private key json @@ -110,7 +103,7 @@ def from_service_account_file(cls, filename: str, *args, **kwargs): @property def transport(self) -> BetaAnalyticsDataTransport: - """Return the transport used by the client instance. + """Returns the transport used by the client instance. Returns: BetaAnalyticsDataTransport: The transport used by the client instance. @@ -124,12 +117,12 @@ def transport(self) -> BetaAnalyticsDataTransport: def __init__( self, *, - credentials: credentials.Credentials = None, + credentials: ga_credentials.Credentials = None, transport: Union[str, BetaAnalyticsDataTransport] = "grpc_asyncio", client_options: ClientOptions = None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: - """Instantiate the beta analytics data client. + """Instantiates the beta analytics data client. Args: credentials (Optional[google.auth.credentials.Credentials]): The @@ -161,7 +154,6 @@ def __init__( google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport creation failed for any reason. """ - self._client = BetaAnalyticsDataClient( credentials=credentials, transport=transport, @@ -190,7 +182,6 @@ async def run_report( Args: request (:class:`google.analytics.data_v1beta.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. @@ -204,7 +195,6 @@ async def run_report( """ # Create or coerce a protobuf request object. - request = analytics_data_api.RunReportRequest(request) # Wrap the RPC method; this adds retry and timeout information, @@ -246,7 +236,6 @@ async def run_pivot_report( request (:class:`google.analytics.data_v1beta.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. @@ -260,7 +249,6 @@ async def run_pivot_report( """ # Create or coerce a protobuf request object. - request = analytics_data_api.RunPivotReportRequest(request) # Wrap the RPC method; this adds retry and timeout information, @@ -298,7 +286,6 @@ async def batch_run_reports( request (:class:`google.analytics.data_v1beta.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. @@ -312,7 +299,6 @@ async def batch_run_reports( """ # Create or coerce a protobuf request object. - request = analytics_data_api.BatchRunReportsRequest(request) # Wrap the RPC method; this adds retry and timeout information, @@ -350,7 +336,6 @@ async def batch_run_pivot_reports( request (:class:`google.analytics.data_v1beta.types.BatchRunPivotReportsRequest`): 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. @@ -364,7 +349,6 @@ async def batch_run_pivot_reports( """ # Create or coerce a protobuf request object. - request = analytics_data_api.BatchRunPivotReportsRequest(request) # Wrap the RPC method; this adds retry and timeout information, @@ -429,7 +413,6 @@ async def get_metadata( 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. @@ -456,7 +439,6 @@ async def get_metadata( # If we have keyword arguments corresponding to fields on the # request, apply these. - if name is not None: request.name = name @@ -497,7 +479,6 @@ async def run_realtime_report( request (:class:`google.analytics.data_v1beta.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. @@ -511,7 +492,6 @@ async def run_realtime_report( """ # Create or coerce a protobuf request object. - request = analytics_data_api.RunRealtimeReportRequest(request) # Wrap the RPC method; this adds retry and timeout information, diff --git a/google/analytics/data_v1beta/services/beta_analytics_data/client.py b/google/analytics/data_v1beta/services/beta_analytics_data/client.py index fe5592b..b34867f 100644 --- a/google/analytics/data_v1beta/services/beta_analytics_data/client.py +++ b/google/analytics/data_v1beta/services/beta_analytics_data/client.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,7 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # - from collections import OrderedDict from distutils import util import os @@ -23,10 +21,10 @@ import pkg_resources from google.api_core import client_options as client_options_lib # type: ignore -from google.api_core import exceptions # 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.auth import credentials # type: ignore +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 @@ -34,7 +32,6 @@ from google.analytics.data_v1beta.types import analytics_data_api from google.analytics.data_v1beta.types import data - from .transports.base import BetaAnalyticsDataTransport, DEFAULT_CLIENT_INFO from .transports.grpc import BetaAnalyticsDataGrpcTransport from .transports.grpc_asyncio import BetaAnalyticsDataGrpcAsyncIOTransport @@ -57,7 +54,7 @@ class BetaAnalyticsDataClientMeta(type): def get_transport_class( cls, label: str = None, ) -> Type[BetaAnalyticsDataTransport]: - """Return an appropriate transport class. + """Returns an appropriate transport class. Args: label: The name of the desired transport. If none is @@ -80,7 +77,8 @@ class BetaAnalyticsDataClient(metaclass=BetaAnalyticsDataClientMeta): @staticmethod def _get_default_mtls_endpoint(api_endpoint): - """Convert api endpoint to mTLS endpoint. + """Converts api endpoint to mTLS endpoint. + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. Args: @@ -114,7 +112,8 @@ def _get_default_mtls_endpoint(api_endpoint): @classmethod def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials info. + """Creates an instance of this client using the provided credentials + info. Args: info (dict): The service account private key info. @@ -131,7 +130,7 @@ def from_service_account_info(cls, info: dict, *args, **kwargs): @classmethod def from_service_account_file(cls, filename: str, *args, **kwargs): """Creates an instance of this client using the provided credentials - file. + file. Args: filename (str): The path to the service account private key json @@ -150,27 +149,28 @@ def from_service_account_file(cls, filename: str, *args, **kwargs): @property def transport(self) -> BetaAnalyticsDataTransport: - """Return the transport used by the client instance. + """Returns the transport used by the client instance. Returns: - BetaAnalyticsDataTransport: The transport used by the client instance. + BetaAnalyticsDataTransport: The transport used by the client + instance. """ return self._transport @staticmethod def metadata_path(property: str,) -> str: - """Return a fully-qualified metadata string.""" + """Returns a fully-qualified metadata string.""" return "properties/{property}/metadata".format(property=property,) @staticmethod def parse_metadata_path(path: str) -> Dict[str, str]: - """Parse a metadata path into its component segments.""" + """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,) -> str: - """Return a fully-qualified billing_account string.""" + """Returns a fully-qualified billing_account string.""" return "billingAccounts/{billing_account}".format( billing_account=billing_account, ) @@ -183,7 +183,7 @@ def parse_common_billing_account_path(path: str) -> Dict[str, str]: @staticmethod def common_folder_path(folder: str,) -> str: - """Return a fully-qualified folder string.""" + """Returns a fully-qualified folder string.""" return "folders/{folder}".format(folder=folder,) @staticmethod @@ -194,7 +194,7 @@ def parse_common_folder_path(path: str) -> Dict[str, str]: @staticmethod def common_organization_path(organization: str,) -> str: - """Return a fully-qualified organization string.""" + """Returns a fully-qualified organization string.""" return "organizations/{organization}".format(organization=organization,) @staticmethod @@ -205,7 +205,7 @@ def parse_common_organization_path(path: str) -> Dict[str, str]: @staticmethod def common_project_path(project: str,) -> str: - """Return a fully-qualified project string.""" + """Returns a fully-qualified project string.""" return "projects/{project}".format(project=project,) @staticmethod @@ -216,7 +216,7 @@ def parse_common_project_path(path: str) -> Dict[str, str]: @staticmethod def common_location_path(project: str, location: str,) -> str: - """Return a fully-qualified location string.""" + """Returns a fully-qualified location string.""" return "projects/{project}/locations/{location}".format( project=project, location=location, ) @@ -230,12 +230,12 @@ def parse_common_location_path(path: str) -> Dict[str, str]: def __init__( self, *, - credentials: Optional[credentials.Credentials] = None, + credentials: Optional[ga_credentials.Credentials] = None, transport: Union[str, BetaAnalyticsDataTransport, None] = None, client_options: Optional[client_options_lib.ClientOptions] = None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: - """Instantiate the beta analytics data client. + """Instantiates the beta analytics data client. Args: credentials (Optional[google.auth.credentials.Credentials]): The @@ -290,9 +290,10 @@ def __init__( client_cert_source_func = client_options.client_cert_source else: is_mtls = mtls.has_default_client_cert_source() - client_cert_source_func = ( - mtls.default_client_cert_source() if is_mtls else None - ) + 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: @@ -304,12 +305,14 @@ def __init__( elif use_mtls_env == "always": api_endpoint = self.DEFAULT_MTLS_ENDPOINT elif use_mtls_env == "auto": - api_endpoint = ( - self.DEFAULT_MTLS_ENDPOINT if is_mtls else self.DEFAULT_ENDPOINT - ) + 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" + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" ) # Save or instantiate the transport. @@ -324,8 +327,8 @@ def __init__( ) if client_options.scopes: raise ValueError( - "When providing a transport instance, " - "provide its scopes directly." + "When providing a transport instance, provide its scopes " + "directly." ) self._transport = transport else: @@ -361,7 +364,6 @@ def run_report( Args: request (google.analytics.data_v1beta.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. @@ -375,7 +377,6 @@ def run_report( """ # 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 @@ -418,7 +419,6 @@ def run_pivot_report( request (google.analytics.data_v1beta.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. @@ -432,7 +432,6 @@ def run_pivot_report( """ # 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 @@ -471,7 +470,6 @@ def batch_run_reports( request (google.analytics.data_v1beta.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. @@ -485,7 +483,6 @@ def batch_run_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 @@ -524,7 +521,6 @@ def batch_run_pivot_reports( request (google.analytics.data_v1beta.types.BatchRunPivotReportsRequest): 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. @@ -538,7 +534,6 @@ def batch_run_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 @@ -604,7 +599,6 @@ def get_metadata( 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. @@ -633,10 +627,8 @@ def get_metadata( # 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 @@ -673,7 +665,6 @@ def run_realtime_report( request (google.analytics.data_v1beta.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. @@ -687,7 +678,6 @@ def run_realtime_report( """ # 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 diff --git a/google/analytics/data_v1beta/services/beta_analytics_data/transports/__init__.py b/google/analytics/data_v1beta/services/beta_analytics_data/transports/__init__.py index 1c9d44a..c921785 100644 --- a/google/analytics/data_v1beta/services/beta_analytics_data/transports/__init__.py +++ b/google/analytics/data_v1beta/services/beta_analytics_data/transports/__init__.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,7 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # - from collections import OrderedDict from typing import Dict, Type diff --git a/google/analytics/data_v1beta/services/beta_analytics_data/transports/base.py b/google/analytics/data_v1beta/services/beta_analytics_data/transports/base.py index a2d0d7d..a8d1ff4 100644 --- a/google/analytics/data_v1beta/services/beta_analytics_data/transports/base.py +++ b/google/analytics/data_v1beta/services/beta_analytics_data/transports/base.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,20 +13,20 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import abc -import typing +from typing import Awaitable, Callable, Dict, Optional, Sequence, Union +import packaging.version import pkg_resources -from google import auth # type: ignore -from google.api_core import exceptions # type: ignore +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore from google.api_core import gapic_v1 # type: ignore from google.api_core import retry as retries # type: ignore -from google.auth import credentials # type: ignore +from google.auth import credentials as ga_credentials # type: ignore from google.analytics.data_v1beta.types import analytics_data_api - try: DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( gapic_version=pkg_resources.get_distribution("google-analytics-data",).version, @@ -35,6 +34,17 @@ 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 + +_API_CORE_VERSION = google.api_core.__version__ + class BetaAnalyticsDataTransport(abc.ABC): """Abstract transport class for BetaAnalyticsData.""" @@ -44,21 +54,24 @@ class BetaAnalyticsDataTransport(abc.ABC): "https://www.googleapis.com/auth/analytics.readonly", ) + DEFAULT_HOST: str = "analyticsdata.googleapis.com" + def __init__( self, *, - host: str = "analyticsdata.googleapis.com", - credentials: credentials.Credentials = None, - credentials_file: typing.Optional[str] = None, - scopes: typing.Optional[typing.Sequence[str]] = AUTH_SCOPES, - quota_project_id: typing.Optional[str] = None, + host: str = DEFAULT_HOST, + credentials: ga_credentials.Credentials = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, **kwargs, ) -> None: """Instantiate the transport. Args: - host (Optional[str]): The hostname to connect to. + host (Optional[str]): + The hostname to connect to. credentials (Optional[google.auth.credentials.Credentials]): The authorization credentials to attach to requests. These credentials identify the application to the service; if none @@ -67,7 +80,7 @@ def __init__( credentials_file (Optional[str]): A file with credentials that can be loaded with :func:`google.auth.load_credentials_from_file`. This argument is mutually exclusive with credentials. - scope (Optional[Sequence[str]]): A list of scopes. + scopes (Optional[Sequence[str]]): A list of scopes. quota_project_id (Optional[str]): An optional project to use for billing and quota. client_info (google.api_core.gapic_v1.client_info.ClientInfo): @@ -81,29 +94,76 @@ def __init__( host += ":443" self._host = host + scopes_kwargs = self._get_scopes_kwargs(self._host, scopes) + # Save the scopes. self._scopes = scopes or self.AUTH_SCOPES # If no credentials are provided, then determine the appropriate # defaults. if credentials and credentials_file: - raise exceptions.DuplicateCredentialArgs( + raise core_exceptions.DuplicateCredentialArgs( "'credentials_file' and 'credentials' are mutually exclusive" ) if credentials_file is not None: - credentials, _ = auth.load_credentials_from_file( - credentials_file, scopes=self._scopes, quota_project_id=quota_project_id + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, **scopes_kwargs, quota_project_id=quota_project_id ) elif credentials is None: - credentials, _ = auth.default( - scopes=self._scopes, quota_project_id=quota_project_id + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id ) # Save the credentials. self._credentials = credentials + # TODO(busunkim): These two class methods are in the base transport + # to avoid duplicating code across the transport classes. These functions + # should be deleted once the minimum required versions of google-api-core + # and google-auth are 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 + + # TODO: Remove this function once google-api-core >= 1.26.0 is required + @classmethod + def _get_self_signed_jwt_kwargs( + cls, host: str, scopes: Optional[Sequence[str]] + ) -> Dict[str, Union[Optional[Sequence[str]], str]]: + """Returns kwargs to pass to grpc_helpers.create_channel depending on the google-api-core version""" + + self_signed_jwt_kwargs: Dict[str, Union[Optional[Sequence[str]], str]] = {} + + if _API_CORE_VERSION and ( + packaging.version.parse(_API_CORE_VERSION) + >= packaging.version.parse("1.26.0") + ): + self_signed_jwt_kwargs["default_scopes"] = cls.AUTH_SCOPES + self_signed_jwt_kwargs["scopes"] = scopes + self_signed_jwt_kwargs["default_host"] = cls.DEFAULT_HOST + else: + self_signed_jwt_kwargs["scopes"] = scopes or cls.AUTH_SCOPES + + return self_signed_jwt_kwargs + def _prep_wrapped_messages(self, client_info): # Precompute the wrapped methods. self._wrapped_methods = { @@ -132,11 +192,11 @@ def _prep_wrapped_messages(self, client_info): @property def run_report( self, - ) -> typing.Callable[ + ) -> Callable[ [analytics_data_api.RunReportRequest], - typing.Union[ + Union[ analytics_data_api.RunReportResponse, - typing.Awaitable[analytics_data_api.RunReportResponse], + Awaitable[analytics_data_api.RunReportResponse], ], ]: raise NotImplementedError() @@ -144,11 +204,11 @@ def run_report( @property def run_pivot_report( self, - ) -> typing.Callable[ + ) -> Callable[ [analytics_data_api.RunPivotReportRequest], - typing.Union[ + Union[ analytics_data_api.RunPivotReportResponse, - typing.Awaitable[analytics_data_api.RunPivotReportResponse], + Awaitable[analytics_data_api.RunPivotReportResponse], ], ]: raise NotImplementedError() @@ -156,11 +216,11 @@ def run_pivot_report( @property def batch_run_reports( self, - ) -> typing.Callable[ + ) -> Callable[ [analytics_data_api.BatchRunReportsRequest], - typing.Union[ + Union[ analytics_data_api.BatchRunReportsResponse, - typing.Awaitable[analytics_data_api.BatchRunReportsResponse], + Awaitable[analytics_data_api.BatchRunReportsResponse], ], ]: raise NotImplementedError() @@ -168,11 +228,11 @@ def batch_run_reports( @property def batch_run_pivot_reports( self, - ) -> typing.Callable[ + ) -> Callable[ [analytics_data_api.BatchRunPivotReportsRequest], - typing.Union[ + Union[ analytics_data_api.BatchRunPivotReportsResponse, - typing.Awaitable[analytics_data_api.BatchRunPivotReportsResponse], + Awaitable[analytics_data_api.BatchRunPivotReportsResponse], ], ]: raise NotImplementedError() @@ -180,22 +240,20 @@ def batch_run_pivot_reports( @property def get_metadata( self, - ) -> typing.Callable[ + ) -> Callable[ [analytics_data_api.GetMetadataRequest], - typing.Union[ - analytics_data_api.Metadata, typing.Awaitable[analytics_data_api.Metadata] - ], + Union[analytics_data_api.Metadata, Awaitable[analytics_data_api.Metadata]], ]: raise NotImplementedError() @property def run_realtime_report( self, - ) -> typing.Callable[ + ) -> Callable[ [analytics_data_api.RunRealtimeReportRequest], - typing.Union[ + Union[ analytics_data_api.RunRealtimeReportResponse, - typing.Awaitable[analytics_data_api.RunRealtimeReportResponse], + Awaitable[analytics_data_api.RunRealtimeReportResponse], ], ]: raise NotImplementedError() diff --git a/google/analytics/data_v1beta/services/beta_analytics_data/transports/grpc.py b/google/analytics/data_v1beta/services/beta_analytics_data/transports/grpc.py index d744160..224a21a 100644 --- a/google/analytics/data_v1beta/services/beta_analytics_data/transports/grpc.py +++ b/google/analytics/data_v1beta/services/beta_analytics_data/transports/grpc.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,20 +13,18 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple +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 import auth # type: ignore -from google.auth import credentials # type: ignore +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore import grpc # type: ignore from google.analytics.data_v1beta.types import analytics_data_api - from .base import BetaAnalyticsDataTransport, DEFAULT_CLIENT_INFO @@ -50,7 +47,7 @@ def __init__( self, *, host: str = "analyticsdata.googleapis.com", - credentials: credentials.Credentials = None, + credentials: ga_credentials.Credentials = None, credentials_file: str = None, scopes: Sequence[str] = None, channel: grpc.Channel = None, @@ -64,7 +61,8 @@ def __init__( """Instantiate the transport. Args: - host (Optional[str]): The hostname to connect to. + host (Optional[str]): + The hostname to connect to. credentials (Optional[google.auth.credentials.Credentials]): The authorization credentials to attach to requests. These credentials identify the application to the service; if none @@ -174,7 +172,7 @@ def __init__( def create_channel( cls, host: str = "analyticsdata.googleapis.com", - credentials: credentials.Credentials = None, + credentials: ga_credentials.Credentials = None, credentials_file: str = None, scopes: Optional[Sequence[str]] = None, quota_project_id: Optional[str] = None, @@ -205,13 +203,15 @@ def create_channel( google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` and ``credentials_file`` are passed. """ - scopes = scopes or cls.AUTH_SCOPES + + self_signed_jwt_kwargs = cls._get_self_signed_jwt_kwargs(host, scopes) + return grpc_helpers.create_channel( host, credentials=credentials, credentials_file=credentials_file, - scopes=scopes, quota_project_id=quota_project_id, + **self_signed_jwt_kwargs, **kwargs, ) diff --git a/google/analytics/data_v1beta/services/beta_analytics_data/transports/grpc_asyncio.py b/google/analytics/data_v1beta/services/beta_analytics_data/transports/grpc_asyncio.py index 09c2015..4e697a9 100644 --- a/google/analytics/data_v1beta/services/beta_analytics_data/transports/grpc_asyncio.py +++ b/google/analytics/data_v1beta/services/beta_analytics_data/transports/grpc_asyncio.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,21 +13,19 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple +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 import auth # type: ignore -from google.auth import credentials # type: ignore +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 from google.analytics.data_v1beta.types import analytics_data_api - from .base import BetaAnalyticsDataTransport, DEFAULT_CLIENT_INFO from .grpc import BetaAnalyticsDataGrpcTransport @@ -53,7 +50,7 @@ class BetaAnalyticsDataGrpcAsyncIOTransport(BetaAnalyticsDataTransport): def create_channel( cls, host: str = "analyticsdata.googleapis.com", - credentials: credentials.Credentials = None, + credentials: ga_credentials.Credentials = None, credentials_file: Optional[str] = None, scopes: Optional[Sequence[str]] = None, quota_project_id: Optional[str] = None, @@ -80,13 +77,15 @@ def create_channel( Returns: aio.Channel: A gRPC AsyncIO channel object. """ - scopes = scopes or cls.AUTH_SCOPES + + self_signed_jwt_kwargs = cls._get_self_signed_jwt_kwargs(host, scopes) + return grpc_helpers_async.create_channel( host, credentials=credentials, credentials_file=credentials_file, - scopes=scopes, quota_project_id=quota_project_id, + **self_signed_jwt_kwargs, **kwargs, ) @@ -94,7 +93,7 @@ def __init__( self, *, host: str = "analyticsdata.googleapis.com", - credentials: credentials.Credentials = None, + credentials: ga_credentials.Credentials = None, credentials_file: Optional[str] = None, scopes: Optional[Sequence[str]] = None, channel: aio.Channel = None, @@ -108,7 +107,8 @@ def __init__( """Instantiate the transport. Args: - host (Optional[str]): The hostname to connect to. + host (Optional[str]): + The hostname to connect to. credentials (Optional[google.auth.credentials.Credentials]): The authorization credentials to attach to requests. These credentials identify the application to the service; if none @@ -166,7 +166,6 @@ def __init__( # If a channel was explicitly provided, set it. self._grpc_channel = channel self._ssl_channel_credentials = None - else: if api_mtls_endpoint: host = api_mtls_endpoint diff --git a/google/analytics/data_v1beta/types/__init__.py b/google/analytics/data_v1beta/types/__init__.py index faa4850..3ccd5c9 100644 --- a/google/analytics/data_v1beta/types/__init__.py +++ b/google/analytics/data_v1beta/types/__init__.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,7 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # - from .analytics_data_api import ( BatchRunPivotReportsRequest, BatchRunPivotReportsResponse, diff --git a/google/analytics/data_v1beta/types/analytics_data_api.py b/google/analytics/data_v1beta/types/analytics_data_api.py index ca14a44..70fd077 100644 --- a/google/analytics/data_v1beta/types/analytics_data_api.py +++ b/google/analytics/data_v1beta/types/analytics_data_api.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,10 +13,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import proto # type: ignore - from google.analytics.data_v1beta.types import data @@ -53,18 +50,15 @@ class Metadata(proto.Message): The metric descriptions. """ - name = proto.Field(proto.STRING, number=3) - + 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,) class RunReportRequest(proto.Message): r"""The request to generate a report. - Attributes: property (str): A Google Analytics GA4 property identifier whose events are @@ -149,42 +143,28 @@ class RunReportRequest(proto.Message): `PropertyQuota <#PropertyQuota>`__. """ - property = proto.Field(proto.STRING, number=1) - + 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,) - date_ranges = proto.RepeatedField(proto.MESSAGE, number=4, message=data.DateRange,) - dimension_filter = proto.Field( proto.MESSAGE, number=5, message=data.FilterExpression, ) - metric_filter = proto.Field(proto.MESSAGE, number=6, message=data.FilterExpression,) - - offset = proto.Field(proto.INT64, number=7) - - limit = proto.Field(proto.INT64, number=8) - + offset = proto.Field(proto.INT64, number=7,) + limit = proto.Field(proto.INT64, number=8,) metric_aggregations = proto.RepeatedField( proto.ENUM, number=9, enum=data.MetricAggregation, ) - order_bys = proto.RepeatedField(proto.MESSAGE, number=10, message=data.OrderBy,) - - currency_code = proto.Field(proto.STRING, number=11) - + 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) + 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_v1beta.types.DimensionHeader]): Describes dimension columns. The number of @@ -230,31 +210,21 @@ class RunReportResponse(proto.Message): 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) - + row_count = proto.Field(proto.INT32, number=7,) metadata = proto.Field(proto.MESSAGE, number=8, message=data.ResponseMetaData,) - property_quota = proto.Field(proto.MESSAGE, number=9, message=data.PropertyQuota,) - - kind = proto.Field(proto.STRING, number=10) + kind = proto.Field(proto.STRING, number=10,) class RunPivotReportRequest(proto.Message): r"""The request to generate a pivot report. - Attributes: property (str): A Google Analytics GA4 property identifier whose events are @@ -318,29 +288,19 @@ class RunPivotReportRequest(proto.Message): `PropertyQuota <#PropertyQuota>`__. """ - property = proto.Field(proto.STRING, number=1) - + 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,) - date_ranges = proto.RepeatedField(proto.MESSAGE, number=4, message=data.DateRange,) - pivots = proto.RepeatedField(proto.MESSAGE, number=5, message=data.Pivot,) - dimension_filter = proto.Field( proto.MESSAGE, number=6, message=data.FilterExpression, ) - metric_filter = proto.Field(proto.MESSAGE, number=7, message=data.FilterExpression,) - - currency_code = proto.Field(proto.STRING, number=8) - + currency_code = proto.Field(proto.STRING, number=8,) cohort_spec = proto.Field(proto.MESSAGE, number=9, message=data.CohortSpec,) - - keep_empty_rows = proto.Field(proto.BOOL, number=10) - - return_property_quota = proto.Field(proto.BOOL, number=11) + keep_empty_rows = proto.Field(proto.BOOL, number=10,) + return_property_quota = proto.Field(proto.BOOL, number=11,) class RunPivotReportResponse(proto.Message): @@ -422,29 +382,21 @@ class RunPivotReportResponse(proto.Message): pivot_headers = proto.RepeatedField( proto.MESSAGE, number=1, message=data.PivotHeader, ) - dimension_headers = proto.RepeatedField( proto.MESSAGE, number=2, message=data.DimensionHeader, ) - metric_headers = proto.RepeatedField( proto.MESSAGE, number=3, message=data.MetricHeader, ) - rows = proto.RepeatedField(proto.MESSAGE, number=4, message=data.Row,) - aggregates = proto.RepeatedField(proto.MESSAGE, number=5, message=data.Row,) - metadata = proto.Field(proto.MESSAGE, number=6, message=data.ResponseMetaData,) - property_quota = proto.Field(proto.MESSAGE, number=7, message=data.PropertyQuota,) - - kind = proto.Field(proto.STRING, number=8) + kind = proto.Field(proto.STRING, number=8,) class BatchRunReportsRequest(proto.Message): r"""The batch request containing multiple report requests. - Attributes: property (str): A Google Analytics GA4 property identifier whose events are @@ -462,14 +414,12 @@ class BatchRunReportsRequest(proto.Message): allowed up to 5 requests. """ - property = proto.Field(proto.STRING, number=1) - + property = proto.Field(proto.STRING, number=1,) 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_v1beta.types.RunReportResponse]): Individual responses. Each response has a @@ -482,13 +432,11 @@ class BatchRunReportsResponse(proto.Message): """ reports = proto.RepeatedField(proto.MESSAGE, number=1, message="RunReportResponse",) - - kind = proto.Field(proto.STRING, number=2) + kind = proto.Field(proto.STRING, number=2,) class BatchRunPivotReportsRequest(proto.Message): r"""The batch request containing multiple pivot report requests. - Attributes: property (str): A Google Analytics GA4 property identifier whose events are @@ -506,8 +454,7 @@ class BatchRunPivotReportsRequest(proto.Message): request is allowed up to 5 requests. """ - property = proto.Field(proto.STRING, number=1) - + property = proto.Field(proto.STRING, number=1,) requests = proto.RepeatedField( proto.MESSAGE, number=2, message="RunPivotReportRequest", ) @@ -515,7 +462,6 @@ class BatchRunPivotReportsRequest(proto.Message): class BatchRunPivotReportsResponse(proto.Message): r"""The batch response containing multiple pivot reports. - Attributes: pivot_reports (Sequence[google.analytics.data_v1beta.types.RunPivotReportResponse]): Individual responses. Each response has a @@ -530,13 +476,11 @@ class BatchRunPivotReportsResponse(proto.Message): pivot_reports = proto.RepeatedField( proto.MESSAGE, number=1, message="RunPivotReportResponse", ) - - kind = proto.Field(proto.STRING, number=2) + kind = proto.Field(proto.STRING, number=2,) 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. @@ -553,12 +497,11 @@ class GetMetadataRequest(proto.Message): not return custom dimensions and metrics. """ - name = proto.Field(proto.STRING, number=1) + name = 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 @@ -606,27 +549,19 @@ class RunRealtimeReportRequest(proto.Message): `PropertyQuota <#PropertyQuota>`__. """ - property = proto.Field(proto.STRING, number=1) - + 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,) - dimension_filter = proto.Field( proto.MESSAGE, number=4, message=data.FilterExpression, ) - metric_filter = proto.Field(proto.MESSAGE, number=5, message=data.FilterExpression,) - - limit = proto.Field(proto.INT64, number=6) - + limit = proto.Field(proto.INT64, number=6,) 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) + return_property_quota = proto.Field(proto.BOOL, number=9,) class RunRealtimeReportResponse(proto.Message): @@ -672,24 +607,16 @@ class RunRealtimeReportResponse(proto.Message): 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) - + row_count = proto.Field(proto.INT32, number=7,) property_quota = proto.Field(proto.MESSAGE, number=8, message=data.PropertyQuota,) - - kind = proto.Field(proto.STRING, number=9) + kind = proto.Field(proto.STRING, number=9,) __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/analytics/data_v1beta/types/data.py b/google/analytics/data_v1beta/types/data.py index c2c3313..573f56e 100644 --- a/google/analytics/data_v1beta/types/data.py +++ b/google/analytics/data_v1beta/types/data.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,7 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import proto # type: ignore @@ -104,11 +102,9 @@ class DateRange(proto.Message): in the request: ``date_range_0``, ``date_range_1``, etc. """ - start_date = proto.Field(proto.STRING, number=1) - - end_date = proto.Field(proto.STRING, number=2) - - name = proto.Field(proto.STRING, number=3) + start_date = proto.Field(proto.STRING, number=1,) + end_date = proto.Field(proto.STRING, number=2,) + name = proto.Field(proto.STRING, number=3,) class Dimension(proto.Message): @@ -141,8 +137,7 @@ class Dimension(proto.Message): ", ", city). """ - name = proto.Field(proto.STRING, number=1) - + name = proto.Field(proto.STRING, number=1,) dimension_expression = proto.Field( proto.MESSAGE, number=2, message="DimensionExpression", ) @@ -170,18 +165,16 @@ class DimensionExpression(proto.Message): 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 to a name in dimensions field of the request. """ - dimension_name = proto.Field(proto.STRING, number=1) + dimension_name = proto.Field(proto.STRING, number=1,) 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 @@ -198,18 +191,15 @@ class ConcatenateExpression(proto.Message): response will contain "US,FR,JP". """ - dimension_names = proto.RepeatedField(proto.STRING, number=1) - - delimiter = proto.Field(proto.STRING, number=2) + dimension_names = proto.RepeatedField(proto.STRING, number=1,) + delimiter = proto.Field(proto.STRING, number=2,) lower_case = proto.Field( proto.MESSAGE, number=4, oneof="one_expression", message=CaseExpression, ) - upper_case = proto.Field( proto.MESSAGE, number=5, oneof="one_expression", message=CaseExpression, ) - concatenate = proto.Field( proto.MESSAGE, number=6, oneof="one_expression", message=ConcatenateExpression, ) @@ -246,11 +236,9 @@ class Metric(proto.Message): ``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) + 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): @@ -274,21 +262,17 @@ class FilterExpression(proto.Message): and_group = proto.Field( proto.MESSAGE, number=1, oneof="expr", message="FilterExpressionList", ) - or_group = proto.Field( proto.MESSAGE, number=2, oneof="expr", message="FilterExpressionList", ) - not_expression = proto.Field( proto.MESSAGE, number=3, oneof="expr", message="FilterExpression", ) - filter = proto.Field(proto.MESSAGE, number=4, oneof="expr", message="Filter",) class FilterExpressionList(proto.Message): r"""A list of filter expressions. - Attributes: expressions (Sequence[google.analytics.data_v1beta.types.FilterExpression]): A list of filter expressions. @@ -301,7 +285,6 @@ class FilterExpressionList(proto.Message): class Filter(proto.Message): r"""An expression to filter dimension or metric values. - Attributes: field_name (str): The dimension name or metric name. Must be a @@ -318,7 +301,6 @@ class Filter(proto.Message): class StringFilter(proto.Message): r"""The filter for string - Attributes: match_type (google.analytics.data_v1beta.types.Filter.StringFilter.MatchType): The match type for this filter. @@ -341,14 +323,11 @@ class MatchType(proto.Enum): 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) + 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. @@ -357,13 +336,11 @@ class InListFilter(proto.Message): If true, the string value is case sensitive. """ - values = proto.RepeatedField(proto.STRING, number=1) - - case_sensitive = proto.Field(proto.BOOL, number=2) + 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_v1beta.types.Filter.NumericFilter.Operation): The operation type for this filter. @@ -383,7 +360,6 @@ class Operation(proto.Enum): operation = proto.Field( proto.ENUM, number=1, enum="Filter.NumericFilter.Operation", ) - value = proto.Field(proto.MESSAGE, number=2, message="NumericValue",) class BetweenFilter(proto.Message): @@ -398,23 +374,18 @@ class BetweenFilter(proto.Message): """ from_value = proto.Field(proto.MESSAGE, number=1, message="NumericValue",) - to_value = proto.Field(proto.MESSAGE, number=2, message="NumericValue",) - field_name = proto.Field(proto.STRING, number=1) - + field_name = proto.Field(proto.STRING, number=1,) string_filter = proto.Field( proto.MESSAGE, number=3, oneof="one_filter", message=StringFilter, ) - in_list_filter = proto.Field( proto.MESSAGE, number=4, oneof="one_filter", message=InListFilter, ) - numeric_filter = proto.Field( proto.MESSAGE, number=5, oneof="one_filter", message=NumericFilter, ) - between_filter = proto.Field( proto.MESSAGE, number=6, oneof="one_filter", message=BetweenFilter, ) @@ -422,7 +393,6 @@ class BetweenFilter(proto.Message): class OrderBy(proto.Message): r"""The sort options. - Attributes: metric (google.analytics.data_v1beta.types.OrderBy.MetricOrderBy): Sorts results by a metric's values. @@ -437,17 +407,15 @@ class OrderBy(proto.Message): 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) + 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. @@ -463,15 +431,13 @@ class OrderType(proto.Enum): CASE_INSENSITIVE_ALPHANUMERIC = 2 NUMERIC = 3 - dimension_name = proto.Field(proto.STRING, number=1) - + 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 @@ -513,12 +479,10 @@ class PivotSelection(proto.Message): 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) + 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", ) @@ -526,16 +490,13 @@ class PivotSelection(proto.Message): metric = proto.Field( proto.MESSAGE, number=1, oneof="one_order_by", message=MetricOrderBy, ) - dimension = proto.Field( proto.MESSAGE, number=2, oneof="one_order_by", message=DimensionOrderBy, ) - pivot = proto.Field( proto.MESSAGE, number=3, oneof="one_order_by", message=PivotOrderBy, ) - - desc = proto.Field(proto.BOOL, number=4) + desc = proto.Field(proto.BOOL, number=4,) class Pivot(proto.Message): @@ -574,14 +535,10 @@ class Pivot(proto.Message): specified metric_aggregations. """ - field_names = proto.RepeatedField(proto.STRING, number=1) - + field_names = proto.RepeatedField(proto.STRING, number=1,) order_bys = proto.RepeatedField(proto.MESSAGE, number=2, message="OrderBy",) - - offset = proto.Field(proto.INT64, number=3) - - limit = proto.Field(proto.INT64, number=4) - + offset = proto.Field(proto.INT64, number=3,) + limit = proto.Field(proto.INT64, number=4,) metric_aggregations = proto.RepeatedField( proto.ENUM, number=5, enum="MetricAggregation", ) @@ -624,9 +581,7 @@ class CohortSpec(proto.Message): """ cohorts = proto.RepeatedField(proto.MESSAGE, number=1, message="Cohort",) - cohorts_range = proto.Field(proto.MESSAGE, number=2, message="CohortsRange",) - cohort_report_settings = proto.Field( proto.MESSAGE, number=3, message="CohortReportSettings", ) @@ -671,10 +626,8 @@ class Cohort(proto.Message): month. """ - name = proto.Field(proto.STRING, number=1) - - dimension = proto.Field(proto.STRING, number=2) - + name = proto.Field(proto.STRING, number=1,) + dimension = proto.Field(proto.STRING, number=2,) date_range = proto.Field(proto.MESSAGE, number=3, message="DateRange",) @@ -735,22 +688,19 @@ class Granularity(proto.Enum): MONTHLY = 3 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) + start_offset = proto.Field(proto.INT32, number=2,) + end_offset = proto.Field(proto.INT32, number=3,) 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``. """ - accumulate = proto.Field(proto.BOOL, number=1) + accumulate = proto.Field(proto.BOOL, number=1,) class ResponseMetaData(proto.Message): @@ -764,7 +714,7 @@ class ResponseMetaData(proto.Message): can happen for high cardinality reports. """ - data_loss_from_other_row = proto.Field(proto.BOOL, number=3) + data_loss_from_other_row = proto.Field(proto.BOOL, number=3,) class DimensionHeader(proto.Message): @@ -779,7 +729,7 @@ class DimensionHeader(proto.Message): The dimension's name. """ - name = proto.Field(proto.STRING, number=1) + name = proto.Field(proto.STRING, number=1,) class MetricHeader(proto.Message): @@ -796,14 +746,12 @@ class MetricHeader(proto.Message): The metric's data type. """ - name = proto.Field(proto.STRING, number=1) - + name = proto.Field(proto.STRING, number=1,) type_ = proto.Field(proto.ENUM, number=2, enum="MetricType",) class PivotHeader(proto.Message): r"""Dimensions' values in a single pivot. - Attributes: pivot_dimension_headers (Sequence[google.analytics.data_v1beta.types.PivotDimensionHeader]): The size is the same as the cardinality of @@ -817,13 +765,11 @@ class PivotHeader(proto.Message): pivot_dimension_headers = proto.RepeatedField( proto.MESSAGE, number=1, message="PivotDimensionHeader", ) - - row_count = proto.Field(proto.INT32, number=2) + 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_v1beta.types.DimensionValue]): Values of multiple dimensions in a pivot. @@ -884,36 +830,32 @@ class Row(proto.Message): dimension_values = proto.RepeatedField( proto.MESSAGE, number=1, message="DimensionValue", ) - metric_values = proto.RepeatedField(proto.MESSAGE, number=2, message="MetricValue",) class DimensionValue(proto.Message): r"""The value of a dimension. - Attributes: value (str): Value as a string if the dimension type is a string. """ - value = proto.Field(proto.STRING, number=1, oneof="one_value") + value = proto.Field(proto.STRING, number=1, oneof="one_value",) class MetricValue(proto.Message): r"""The value of a metric. - Attributes: value (str): Measurement value. See MetricHeader for type. """ - value = proto.Field(proto.STRING, number=4, oneof="one_value") + value = proto.Field(proto.STRING, number=4, oneof="one_value",) class NumericValue(proto.Message): r"""To represent a number. - Attributes: int64_value (int): Integer value @@ -921,9 +863,8 @@ class NumericValue(proto.Message): Double value """ - int64_value = proto.Field(proto.INT64, number=1, oneof="one_value") - - double_value = proto.Field(proto.DOUBLE, number=2, oneof="one_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): @@ -964,15 +905,11 @@ class PropertyQuota(proto.Message): """ tokens_per_day = proto.Field(proto.MESSAGE, number=1, message="QuotaStatus",) - tokens_per_hour = proto.Field(proto.MESSAGE, number=2, message="QuotaStatus",) - concurrent_requests = proto.Field(proto.MESSAGE, number=3, message="QuotaStatus",) - server_errors_per_project_per_hour = proto.Field( proto.MESSAGE, number=4, message="QuotaStatus", ) - potentially_thresholded_requests_per_hour = proto.Field( proto.MESSAGE, number=5, message="QuotaStatus", ) @@ -980,7 +917,6 @@ class PropertyQuota(proto.Message): class QuotaStatus(proto.Message): r"""Current state for a particular quota group. - Attributes: consumed (int): Quota consumed by this request. @@ -988,14 +924,12 @@ class QuotaStatus(proto.Message): Quota remaining after this request. """ - consumed = proto.Field(proto.INT32, number=1) - - remaining = proto.Field(proto.INT32, number=2) + consumed = proto.Field(proto.INT32, number=1,) + remaining = proto.Field(proto.INT32, number=2,) class DimensionMetadata(proto.Message): r"""Explains a dimension. - Attributes: api_name (str): This dimension's name. Useable in @@ -1018,20 +952,15 @@ class DimensionMetadata(proto.Message): for this property. """ - api_name = proto.Field(proto.STRING, number=1) - - ui_name = proto.Field(proto.STRING, number=2) - - description = proto.Field(proto.STRING, number=3) - - deprecated_api_names = proto.RepeatedField(proto.STRING, number=4) - - custom_definition = proto.Field(proto.BOOL, number=5) + api_name = proto.Field(proto.STRING, number=1,) + ui_name = proto.Field(proto.STRING, number=2,) + description = proto.Field(proto.STRING, number=3,) + deprecated_api_names = proto.RepeatedField(proto.STRING, number=4,) + custom_definition = proto.Field(proto.BOOL, number=5,) class MetricMetadata(proto.Message): r"""Explains a metric. - Attributes: api_name (str): A metric name. Useable in `Metric <#Metric>`__'s ``name``. @@ -1060,19 +989,13 @@ class MetricMetadata(proto.Message): this property. """ - api_name = proto.Field(proto.STRING, number=1) - - ui_name = proto.Field(proto.STRING, number=2) - - description = proto.Field(proto.STRING, number=3) - - deprecated_api_names = proto.RepeatedField(proto.STRING, number=4) - + api_name = proto.Field(proto.STRING, number=1,) + ui_name = proto.Field(proto.STRING, number=2,) + description = proto.Field(proto.STRING, number=3,) + deprecated_api_names = proto.RepeatedField(proto.STRING, number=4,) type_ = proto.Field(proto.ENUM, number=5, enum="MetricType",) - - expression = proto.Field(proto.STRING, number=6) - - custom_definition = proto.Field(proto.BOOL, number=7) + expression = proto.Field(proto.STRING, number=6,) + custom_definition = proto.Field(proto.BOOL, number=7,) __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/samples/snippets/requirements.txt b/samples/snippets/requirements.txt index 2b2d2d6..4079fe1 100644 --- a/samples/snippets/requirements.txt +++ b/samples/snippets/requirements.txt @@ -1,2 +1,2 @@ -google-analytics-data==0.5.0 +google-analytics-data==0.5.1 google-auth-oauthlib==0.4.4 \ No newline at end of file diff --git a/setup.py b/setup.py index 3370d8d..bb82eed 100644 --- a/setup.py +++ b/setup.py @@ -19,7 +19,7 @@ import os import setuptools # type: ignore -version = "0.5.1" +version = "0.6.0" package_root = os.path.abspath(os.path.dirname(__file__)) @@ -44,6 +44,7 @@ "google-api-core[grpc] >= 1.22.2, < 2.0.0dev", "libcst >= 0.2.5", "proto-plus >= 1.4.0", + "packaging >= 14.3", ), python_requires=">=3.6", classifiers=[ diff --git a/testing/constraints-3.6.txt b/testing/constraints-3.6.txt index 16e003f..33059b8 100644 --- a/testing/constraints-3.6.txt +++ b/testing/constraints-3.6.txt @@ -8,3 +8,5 @@ google-api-core==1.22.2 libcst==0.2.5 proto-plus==1.4.0 +packaging==14.3 +google-auth==1.24.0 # TODO: remove when google-auth>=1.25.0 is required through google-api-core diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..4de6597 --- /dev/null +++ b/tests/__init__.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 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. +# diff --git a/tests/unit/__init__.py b/tests/unit/__init__.py new file mode 100644 index 0000000..4de6597 --- /dev/null +++ b/tests/unit/__init__.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 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. +# diff --git a/tests/unit/gapic/__init__.py b/tests/unit/gapic/__init__.py new file mode 100644 index 0000000..4de6597 --- /dev/null +++ b/tests/unit/gapic/__init__.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 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. +# diff --git a/tests/unit/gapic/data_v1alpha/__init__.py b/tests/unit/gapic/data_v1alpha/__init__.py index 42ffdf2..4de6597 100644 --- a/tests/unit/gapic/data_v1alpha/__init__.py +++ b/tests/unit/gapic/data_v1alpha/__init__.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (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 375f3eb..72848d7 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,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,9 +13,9 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import os import mock +import packaging.version import grpc from grpc.experimental import aio @@ -24,7 +23,7 @@ import pytest from proto.marshal.rules.dates import DurationRule, TimestampRule -from google import auth + from google.analytics.data_v1alpha.services.alpha_analytics_data import ( AlphaAnalyticsDataAsyncClient, ) @@ -32,16 +31,46 @@ AlphaAnalyticsDataClient, ) from google.analytics.data_v1alpha.services.alpha_analytics_data import transports +from google.analytics.data_v1alpha.services.alpha_analytics_data.transports.base import ( + _API_CORE_VERSION, +) +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 -from google.api_core import exceptions +from google.api_core import exceptions as core_exceptions from google.api_core import gapic_v1 from google.api_core import grpc_helpers from google.api_core import grpc_helpers_async -from google.auth import credentials +from google.auth import credentials as ga_credentials from google.auth.exceptions import MutualTLSChannelError from google.oauth2 import service_account +import google.auth + + +# TODO(busunkim): Once google-api-core >= 1.26.0 is required: +# - Delete all the api-core and 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", +) + +requires_api_core_lt_1_26_0 = pytest.mark.skipif( + packaging.version.parse(_API_CORE_VERSION) >= packaging.version.parse("1.26.0"), + reason="This test requires google-api-core < 1.26.0", +) + +requires_api_core_gte_1_26_0 = pytest.mark.skipif( + packaging.version.parse(_API_CORE_VERSION) < packaging.version.parse("1.26.0"), + reason="This test requires google-api-core >= 1.26.0", +) def client_cert_source_callback(): @@ -93,7 +122,7 @@ def test__get_default_mtls_endpoint(): "client_class", [AlphaAnalyticsDataClient, AlphaAnalyticsDataAsyncClient,] ) def test_alpha_analytics_data_client_from_service_account_info(client_class): - creds = credentials.AnonymousCredentials() + creds = ga_credentials.AnonymousCredentials() with mock.patch.object( service_account.Credentials, "from_service_account_info" ) as factory: @@ -110,7 +139,7 @@ def test_alpha_analytics_data_client_from_service_account_info(client_class): "client_class", [AlphaAnalyticsDataClient, AlphaAnalyticsDataAsyncClient,] ) def test_alpha_analytics_data_client_from_service_account_file(client_class): - creds = credentials.AnonymousCredentials() + creds = ga_credentials.AnonymousCredentials() with mock.patch.object( service_account.Credentials, "from_service_account_file" ) as factory: @@ -163,7 +192,7 @@ def test_alpha_analytics_data_client_client_options( ): # Check that if channel is provided we won't create a new one. with mock.patch.object(AlphaAnalyticsDataClient, "get_transport_class") as gtc: - transport = transport_class(credentials=credentials.AnonymousCredentials()) + transport = transport_class(credentials=ga_credentials.AnonymousCredentials()) client = client_class(transport=transport) gtc.assert_not_called() @@ -461,7 +490,7 @@ def test_run_report( transport: str = "grpc", request_type=analytics_data_api.RunReportRequest ): client = AlphaAnalyticsDataClient( - credentials=credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -472,19 +501,15 @@ def test_run_report( 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 @@ -496,7 +521,7 @@ 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=credentials.AnonymousCredentials(), transport="grpc", + credentials=ga_credentials.AnonymousCredentials(), transport="grpc", ) # Mock the actual call within the gRPC stub, and fake the request. @@ -504,7 +529,6 @@ def test_run_report_empty_call(): client.run_report() call.assert_called() _, args, _ = call.mock_calls[0] - assert args[0] == analytics_data_api.RunReportRequest() @@ -513,7 +537,7 @@ async def test_run_report_async( transport: str = "grpc_asyncio", request_type=analytics_data_api.RunReportRequest ): client = AlphaAnalyticsDataAsyncClient( - credentials=credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -526,18 +550,15 @@ async def test_run_report_async( 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 @@ -550,7 +571,7 @@ def test_run_pivot_report( transport: str = "grpc", request_type=analytics_data_api.RunPivotReportRequest ): client = AlphaAnalyticsDataClient( - credentials=credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -561,17 +582,14 @@ def test_run_pivot_report( 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) @@ -583,7 +601,7 @@ 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=credentials.AnonymousCredentials(), transport="grpc", + credentials=ga_credentials.AnonymousCredentials(), transport="grpc", ) # Mock the actual call within the gRPC stub, and fake the request. @@ -591,7 +609,6 @@ def test_run_pivot_report_empty_call(): client.run_pivot_report() call.assert_called() _, args, _ = call.mock_calls[0] - assert args[0] == analytics_data_api.RunPivotReportRequest() @@ -601,7 +618,7 @@ async def test_run_pivot_report_async( request_type=analytics_data_api.RunPivotReportRequest, ): client = AlphaAnalyticsDataAsyncClient( - credentials=credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -614,13 +631,11 @@ async def test_run_pivot_report_async( 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. @@ -636,7 +651,7 @@ def test_batch_run_reports( transport: str = "grpc", request_type=analytics_data_api.BatchRunReportsRequest ): client = AlphaAnalyticsDataClient( - credentials=credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -649,17 +664,14 @@ def test_batch_run_reports( ) 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) @@ -671,7 +683,7 @@ 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=credentials.AnonymousCredentials(), transport="grpc", + credentials=ga_credentials.AnonymousCredentials(), transport="grpc", ) # Mock the actual call within the gRPC stub, and fake the request. @@ -681,7 +693,6 @@ def test_batch_run_reports_empty_call(): client.batch_run_reports() call.assert_called() _, args, _ = call.mock_calls[0] - assert args[0] == analytics_data_api.BatchRunReportsRequest() @@ -691,7 +702,7 @@ async def test_batch_run_reports_async( request_type=analytics_data_api.BatchRunReportsRequest, ): client = AlphaAnalyticsDataAsyncClient( - credentials=credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -706,13 +717,11 @@ async def test_batch_run_reports_async( 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. @@ -728,7 +737,7 @@ def test_batch_run_pivot_reports( transport: str = "grpc", request_type=analytics_data_api.BatchRunPivotReportsRequest ): client = AlphaAnalyticsDataClient( - credentials=credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -741,17 +750,14 @@ def test_batch_run_pivot_reports( ) 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) @@ -763,7 +769,7 @@ 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=credentials.AnonymousCredentials(), transport="grpc", + credentials=ga_credentials.AnonymousCredentials(), transport="grpc", ) # Mock the actual call within the gRPC stub, and fake the request. @@ -773,7 +779,6 @@ def test_batch_run_pivot_reports_empty_call(): client.batch_run_pivot_reports() call.assert_called() _, args, _ = call.mock_calls[0] - assert args[0] == analytics_data_api.BatchRunPivotReportsRequest() @@ -783,7 +788,7 @@ async def test_batch_run_pivot_reports_async( request_type=analytics_data_api.BatchRunPivotReportsRequest, ): client = AlphaAnalyticsDataAsyncClient( - credentials=credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -798,13 +803,11 @@ async def test_batch_run_pivot_reports_async( 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. @@ -820,7 +823,7 @@ def test_get_metadata( transport: str = "grpc", request_type=analytics_data_api.GetMetadataRequest ): client = AlphaAnalyticsDataClient( - credentials=credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -831,19 +834,15 @@ def test_get_metadata( 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" @@ -855,7 +854,7 @@ 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=credentials.AnonymousCredentials(), transport="grpc", + credentials=ga_credentials.AnonymousCredentials(), transport="grpc", ) # Mock the actual call within the gRPC stub, and fake the request. @@ -863,7 +862,6 @@ def test_get_metadata_empty_call(): client.get_metadata() call.assert_called() _, args, _ = call.mock_calls[0] - assert args[0] == analytics_data_api.GetMetadataRequest() @@ -872,7 +870,7 @@ async def test_get_metadata_async( transport: str = "grpc_asyncio", request_type=analytics_data_api.GetMetadataRequest ): client = AlphaAnalyticsDataAsyncClient( - credentials=credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -885,18 +883,15 @@ async def test_get_metadata_async( 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" @@ -906,17 +901,19 @@ async def test_get_metadata_async_from_dict(): def test_get_metadata_field_headers(): - client = AlphaAnalyticsDataClient(credentials=credentials.AnonymousCredentials(),) + 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. @@ -932,12 +929,13 @@ def test_get_metadata_field_headers(): @pytest.mark.asyncio async def test_get_metadata_field_headers_async(): client = AlphaAnalyticsDataAsyncClient( - credentials=credentials.AnonymousCredentials(), + 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. @@ -945,7 +943,6 @@ async def test_get_metadata_field_headers_async(): 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. @@ -959,13 +956,14 @@ async def test_get_metadata_field_headers_async(): def test_get_metadata_flattened(): - client = AlphaAnalyticsDataClient(credentials=credentials.AnonymousCredentials(),) + 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",) @@ -974,12 +972,13 @@ def test_get_metadata_flattened(): # 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=credentials.AnonymousCredentials(),) + client = AlphaAnalyticsDataClient( + credentials=ga_credentials.AnonymousCredentials(), + ) # Attempting to call a method with both a request object and flattened # fields is an error. @@ -992,7 +991,7 @@ def test_get_metadata_flattened_error(): @pytest.mark.asyncio async def test_get_metadata_flattened_async(): client = AlphaAnalyticsDataAsyncClient( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1011,14 +1010,13 @@ async def test_get_metadata_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" @pytest.mark.asyncio async def test_get_metadata_flattened_error_async(): client = AlphaAnalyticsDataAsyncClient( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) # Attempting to call a method with both a request object and flattened @@ -1033,7 +1031,7 @@ def test_run_realtime_report( transport: str = "grpc", request_type=analytics_data_api.RunRealtimeReportRequest ): client = AlphaAnalyticsDataClient( - credentials=credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -1046,19 +1044,15 @@ def test_run_realtime_report( ) as call: # Designate an appropriate return value for the call. call.return_value = analytics_data_api.RunRealtimeReportResponse(row_count=992,) - response = client.run_realtime_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() # Establish that the response is the type that we expect. - assert isinstance(response, analytics_data_api.RunRealtimeReportResponse) - assert response.row_count == 992 @@ -1070,7 +1064,7 @@ def test_run_realtime_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=credentials.AnonymousCredentials(), transport="grpc", + credentials=ga_credentials.AnonymousCredentials(), transport="grpc", ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1080,7 +1074,6 @@ def test_run_realtime_report_empty_call(): client.run_realtime_report() call.assert_called() _, args, _ = call.mock_calls[0] - assert args[0] == analytics_data_api.RunRealtimeReportRequest() @@ -1090,7 +1083,7 @@ async def test_run_realtime_report_async( request_type=analytics_data_api.RunRealtimeReportRequest, ): client = AlphaAnalyticsDataAsyncClient( - credentials=credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -1105,18 +1098,15 @@ async def test_run_realtime_report_async( call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( analytics_data_api.RunRealtimeReportResponse(row_count=992,) ) - response = await client.run_realtime_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() # Establish that the response is the type that we expect. assert isinstance(response, analytics_data_api.RunRealtimeReportResponse) - assert response.row_count == 992 @@ -1126,11 +1116,14 @@ async def test_run_realtime_report_async_from_dict(): def test_run_realtime_report_field_headers(): - client = AlphaAnalyticsDataClient(credentials=credentials.AnonymousCredentials(),) + 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.property = "property/value" # Mock the actual call within the gRPC stub, and fake the request. @@ -1138,7 +1131,6 @@ def test_run_realtime_report_field_headers(): type(client.transport.run_realtime_report), "__call__" ) as call: call.return_value = analytics_data_api.RunRealtimeReportResponse() - client.run_realtime_report(request) # Establish that the underlying gRPC stub method was called. @@ -1154,12 +1146,13 @@ def test_run_realtime_report_field_headers(): @pytest.mark.asyncio async def test_run_realtime_report_field_headers_async(): client = AlphaAnalyticsDataAsyncClient( - credentials=credentials.AnonymousCredentials(), + 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.property = "property/value" # Mock the actual call within the gRPC stub, and fake the request. @@ -1169,7 +1162,6 @@ async def test_run_realtime_report_field_headers_async(): call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( analytics_data_api.RunRealtimeReportResponse() ) - await client.run_realtime_report(request) # Establish that the underlying gRPC stub method was called. @@ -1185,16 +1177,16 @@ async def test_run_realtime_report_field_headers_async(): def test_credentials_transport_error(): # It is an error to provide credentials and a transport instance. transport = transports.AlphaAnalyticsDataGrpcTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) with pytest.raises(ValueError): client = AlphaAnalyticsDataClient( - credentials=credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) # It is an error to provide a credentials file and a transport instance. transport = transports.AlphaAnalyticsDataGrpcTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) with pytest.raises(ValueError): client = AlphaAnalyticsDataClient( @@ -1204,7 +1196,7 @@ def test_credentials_transport_error(): # It is an error to provide scopes and a transport instance. transport = transports.AlphaAnalyticsDataGrpcTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) with pytest.raises(ValueError): client = AlphaAnalyticsDataClient( @@ -1215,7 +1207,7 @@ def test_credentials_transport_error(): def test_transport_instance(): # A client may be instantiated with a custom transport instance. transport = transports.AlphaAnalyticsDataGrpcTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) client = AlphaAnalyticsDataClient(transport=transport) assert client.transport is transport @@ -1224,13 +1216,13 @@ def test_transport_instance(): def test_transport_get_channel(): # A client may be instantiated with a custom transport instance. transport = transports.AlphaAnalyticsDataGrpcTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) channel = transport.grpc_channel assert channel transport = transports.AlphaAnalyticsDataGrpcAsyncIOTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) channel = transport.grpc_channel assert channel @@ -1245,23 +1237,25 @@ def test_transport_get_channel(): ) def test_transport_adc(transport_class): # Test default credentials are used if not provided. - with mock.patch.object(auth, "default") as adc: - adc.return_value = (credentials.AnonymousCredentials(), None) + with mock.patch.object(google.auth, "default") as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) transport_class() adc.assert_called_once() def test_transport_grpc_default(): # A client should use the gRPC transport by default. - client = AlphaAnalyticsDataClient(credentials=credentials.AnonymousCredentials(),) + client = AlphaAnalyticsDataClient( + credentials=ga_credentials.AnonymousCredentials(), + ) assert isinstance(client.transport, transports.AlphaAnalyticsDataGrpcTransport,) def test_alpha_analytics_data_base_transport_error(): # Passing both a credentials object and credentials_file should raise an error - with pytest.raises(exceptions.DuplicateCredentialArgs): + with pytest.raises(core_exceptions.DuplicateCredentialArgs): transport = transports.AlphaAnalyticsDataTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), credentials_file="credentials.json", ) @@ -1273,7 +1267,7 @@ def test_alpha_analytics_data_base_transport(): ) as Transport: Transport.return_value = None transport = transports.AlphaAnalyticsDataTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) # Every method on the transport should just blindly @@ -1291,15 +1285,40 @@ def test_alpha_analytics_data_base_transport(): getattr(transport, method)(request=object()) +@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( - auth, "load_credentials_from_file" + 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=None, + default_scopes=( + "https://www.googleapis.com/auth/analytics", + "https://www.googleapis.com/auth/analytics.readonly", + ), + quota_project_id="octopus", + ) + + +@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 = (credentials.AnonymousCredentials(), None) + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) transport = transports.AlphaAnalyticsDataTransport( credentials_file="credentials.json", quota_project_id="octopus", ) @@ -1315,19 +1334,36 @@ def test_alpha_analytics_data_base_transport_with_credentials_file(): 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(auth, "default") as adc, mock.patch( + with mock.patch.object(google.auth, "default", autospec=True) as adc, mock.patch( "google.analytics.data_v1alpha.services.alpha_analytics_data.transports.AlphaAnalyticsDataTransport._prep_wrapped_messages" ) as Transport: Transport.return_value = None - adc.return_value = (credentials.AnonymousCredentials(), None) + adc.return_value = (ga_credentials.AnonymousCredentials(), None) transport = transports.AlphaAnalyticsDataTransport() 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(auth, "default") as adc: - adc.return_value = (credentials.AnonymousCredentials(), None) + 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=None, + default_scopes=( + "https://www.googleapis.com/auth/analytics", + "https://www.googleapis.com/auth/analytics.readonly", + ), + quota_project_id=None, + ) + + +@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=( @@ -1338,14 +1374,44 @@ def test_alpha_analytics_data_auth_adc(): ) -def test_alpha_analytics_data_transport_auth_adc(): +@pytest.mark.parametrize( + "transport_class", + [ + transports.AlphaAnalyticsDataGrpcTransport, + 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. - with mock.patch.object(auth, "default") as adc: - adc.return_value = (credentials.AnonymousCredentials(), None) - transports.AlphaAnalyticsDataGrpcTransport( - host="squid.clam.whelk", quota_project_id="octopus" + with mock.patch.object(google.auth, "default", autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class(quota_project_id="octopus", scopes=["1", "2"]) + adc.assert_called_once_with( + scopes=["1", "2"], + default_scopes=( + "https://www.googleapis.com/auth/analytics", + "https://www.googleapis.com/auth/analytics.readonly", + ), + quota_project_id="octopus", ) + + +@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", @@ -1355,6 +1421,121 @@ def test_alpha_analytics_data_transport_auth_adc(): ) +@pytest.mark.parametrize( + "transport_class,grpc_helpers", + [ + (transports.AlphaAnalyticsDataGrpcTransport, grpc_helpers), + (transports.AlphaAnalyticsDataGrpcAsyncIOTransport, grpc_helpers_async), + ], +) +@requires_api_core_gte_1_26_0 +def test_alpha_analytics_data_transport_create_channel(transport_class, grpc_helpers): + # 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, mock.patch.object( + grpc_helpers, "create_channel", autospec=True + ) as create_channel: + creds = ga_credentials.AnonymousCredentials() + adc.return_value = (creds, None) + transport_class(quota_project_id="octopus", scopes=["1", "2"]) + + create_channel.assert_called_with( + "analyticsdata.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + default_scopes=( + "https://www.googleapis.com/auth/analytics", + "https://www.googleapis.com/auth/analytics.readonly", + ), + scopes=["1", "2"], + default_host="analyticsdata.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize( + "transport_class,grpc_helpers", + [ + (transports.AlphaAnalyticsDataGrpcTransport, grpc_helpers), + (transports.AlphaAnalyticsDataGrpcAsyncIOTransport, grpc_helpers_async), + ], +) +@requires_api_core_lt_1_26_0 +def test_alpha_analytics_data_transport_create_channel_old_api_core( + transport_class, grpc_helpers +): + # 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, mock.patch.object( + grpc_helpers, "create_channel", autospec=True + ) as create_channel: + creds = ga_credentials.AnonymousCredentials() + adc.return_value = (creds, None) + transport_class(quota_project_id="octopus") + + create_channel.assert_called_with( + "analyticsdata.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + scopes=( + "https://www.googleapis.com/auth/analytics", + "https://www.googleapis.com/auth/analytics.readonly", + ), + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize( + "transport_class,grpc_helpers", + [ + (transports.AlphaAnalyticsDataGrpcTransport, grpc_helpers), + (transports.AlphaAnalyticsDataGrpcAsyncIOTransport, grpc_helpers_async), + ], +) +@requires_api_core_lt_1_26_0 +def test_alpha_analytics_data_transport_create_channel_user_scopes( + transport_class, grpc_helpers +): + # 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, mock.patch.object( + grpc_helpers, "create_channel", autospec=True + ) as create_channel: + creds = ga_credentials.AnonymousCredentials() + adc.return_value = (creds, None) + + transport_class(quota_project_id="octopus", scopes=["1", "2"]) + + create_channel.assert_called_with( + "analyticsdata.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + scopes=["1", "2"], + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + @pytest.mark.parametrize( "transport_class", [ @@ -1365,7 +1546,7 @@ def test_alpha_analytics_data_transport_auth_adc(): def test_alpha_analytics_data_grpc_transport_client_cert_source_for_mtls( transport_class, ): - cred = credentials.AnonymousCredentials() + cred = ga_credentials.AnonymousCredentials() # Check ssl_channel_credentials is used if provided. with mock.patch.object(transport_class, "create_channel") as mock_create_channel: @@ -1407,7 +1588,7 @@ def test_alpha_analytics_data_grpc_transport_client_cert_source_for_mtls( def test_alpha_analytics_data_host_no_port(): client = AlphaAnalyticsDataClient( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), client_options=client_options.ClientOptions( api_endpoint="analyticsdata.googleapis.com" ), @@ -1417,7 +1598,7 @@ def test_alpha_analytics_data_host_no_port(): def test_alpha_analytics_data_host_with_port(): client = AlphaAnalyticsDataClient( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), client_options=client_options.ClientOptions( api_endpoint="analyticsdata.googleapis.com:8000" ), @@ -1473,9 +1654,9 @@ def test_alpha_analytics_data_transport_channel_mtls_with_client_cert_source( mock_grpc_channel = mock.Mock() grpc_create_channel.return_value = mock_grpc_channel - cred = credentials.AnonymousCredentials() + cred = ga_credentials.AnonymousCredentials() with pytest.warns(DeprecationWarning): - with mock.patch.object(auth, "default") as adc: + with mock.patch.object(google.auth, "default") as adc: adc.return_value = (cred, None) transport = transport_class( host="squid.clam.whelk", @@ -1557,7 +1738,6 @@ def test_alpha_analytics_data_transport_channel_mtls_with_adc(transport_class): def test_metadata_path(): property = "squid" - expected = "properties/{property}/metadata".format(property=property,) actual = AlphaAnalyticsDataClient.metadata_path(property) assert expected == actual @@ -1576,7 +1756,6 @@ def test_parse_metadata_path(): def test_common_billing_account_path(): billing_account = "whelk" - expected = "billingAccounts/{billing_account}".format( billing_account=billing_account, ) @@ -1597,7 +1776,6 @@ def test_parse_common_billing_account_path(): def test_common_folder_path(): folder = "oyster" - expected = "folders/{folder}".format(folder=folder,) actual = AlphaAnalyticsDataClient.common_folder_path(folder) assert expected == actual @@ -1616,7 +1794,6 @@ def test_parse_common_folder_path(): def test_common_organization_path(): organization = "cuttlefish" - expected = "organizations/{organization}".format(organization=organization,) actual = AlphaAnalyticsDataClient.common_organization_path(organization) assert expected == actual @@ -1635,7 +1812,6 @@ def test_parse_common_organization_path(): def test_common_project_path(): project = "winkle" - expected = "projects/{project}".format(project=project,) actual = AlphaAnalyticsDataClient.common_project_path(project) assert expected == actual @@ -1655,7 +1831,6 @@ def test_parse_common_project_path(): def test_common_location_path(): project = "scallop" location = "abalone" - expected = "projects/{project}/locations/{location}".format( project=project, location=location, ) @@ -1682,7 +1857,7 @@ def test_client_withDEFAULT_CLIENT_INFO(): transports.AlphaAnalyticsDataTransport, "_prep_wrapped_messages" ) as prep: client = AlphaAnalyticsDataClient( - credentials=credentials.AnonymousCredentials(), client_info=client_info, + credentials=ga_credentials.AnonymousCredentials(), client_info=client_info, ) prep.assert_called_once_with(client_info) @@ -1691,6 +1866,6 @@ def test_client_withDEFAULT_CLIENT_INFO(): ) as prep: transport_class = AlphaAnalyticsDataClient.get_transport_class() transport = transport_class( - credentials=credentials.AnonymousCredentials(), client_info=client_info, + credentials=ga_credentials.AnonymousCredentials(), client_info=client_info, ) prep.assert_called_once_with(client_info) diff --git a/tests/unit/gapic/data_v1beta/__init__.py b/tests/unit/gapic/data_v1beta/__init__.py index 42ffdf2..4de6597 100644 --- a/tests/unit/gapic/data_v1beta/__init__.py +++ b/tests/unit/gapic/data_v1beta/__init__.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/tests/unit/gapic/data_v1beta/test_beta_analytics_data.py b/tests/unit/gapic/data_v1beta/test_beta_analytics_data.py index 4a75e3e..c22e2f8 100644 --- a/tests/unit/gapic/data_v1beta/test_beta_analytics_data.py +++ b/tests/unit/gapic/data_v1beta/test_beta_analytics_data.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,9 +13,9 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import os import mock +import packaging.version import grpc from grpc.experimental import aio @@ -24,7 +23,7 @@ import pytest from proto.marshal.rules.dates import DurationRule, TimestampRule -from google import auth + from google.analytics.data_v1beta.services.beta_analytics_data import ( BetaAnalyticsDataAsyncClient, ) @@ -32,16 +31,46 @@ BetaAnalyticsDataClient, ) from google.analytics.data_v1beta.services.beta_analytics_data import transports +from google.analytics.data_v1beta.services.beta_analytics_data.transports.base import ( + _API_CORE_VERSION, +) +from google.analytics.data_v1beta.services.beta_analytics_data.transports.base import ( + _GOOGLE_AUTH_VERSION, +) from google.analytics.data_v1beta.types import analytics_data_api from google.analytics.data_v1beta.types import data from google.api_core import client_options -from google.api_core import exceptions +from google.api_core import exceptions as core_exceptions from google.api_core import gapic_v1 from google.api_core import grpc_helpers from google.api_core import grpc_helpers_async -from google.auth import credentials +from google.auth import credentials as ga_credentials from google.auth.exceptions import MutualTLSChannelError from google.oauth2 import service_account +import google.auth + + +# TODO(busunkim): Once google-api-core >= 1.26.0 is required: +# - Delete all the api-core and 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", +) + +requires_api_core_lt_1_26_0 = pytest.mark.skipif( + packaging.version.parse(_API_CORE_VERSION) >= packaging.version.parse("1.26.0"), + reason="This test requires google-api-core < 1.26.0", +) + +requires_api_core_gte_1_26_0 = pytest.mark.skipif( + packaging.version.parse(_API_CORE_VERSION) < packaging.version.parse("1.26.0"), + reason="This test requires google-api-core >= 1.26.0", +) def client_cert_source_callback(): @@ -93,7 +122,7 @@ def test__get_default_mtls_endpoint(): "client_class", [BetaAnalyticsDataClient, BetaAnalyticsDataAsyncClient,] ) def test_beta_analytics_data_client_from_service_account_info(client_class): - creds = credentials.AnonymousCredentials() + creds = ga_credentials.AnonymousCredentials() with mock.patch.object( service_account.Credentials, "from_service_account_info" ) as factory: @@ -110,7 +139,7 @@ def test_beta_analytics_data_client_from_service_account_info(client_class): "client_class", [BetaAnalyticsDataClient, BetaAnalyticsDataAsyncClient,] ) def test_beta_analytics_data_client_from_service_account_file(client_class): - creds = credentials.AnonymousCredentials() + creds = ga_credentials.AnonymousCredentials() with mock.patch.object( service_account.Credentials, "from_service_account_file" ) as factory: @@ -163,7 +192,7 @@ def test_beta_analytics_data_client_client_options( ): # Check that if channel is provided we won't create a new one. with mock.patch.object(BetaAnalyticsDataClient, "get_transport_class") as gtc: - transport = transport_class(credentials=credentials.AnonymousCredentials()) + transport = transport_class(credentials=ga_credentials.AnonymousCredentials()) client = client_class(transport=transport) gtc.assert_not_called() @@ -461,7 +490,7 @@ def test_run_report( transport: str = "grpc", request_type=analytics_data_api.RunReportRequest ): client = BetaAnalyticsDataClient( - credentials=credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -474,21 +503,16 @@ def test_run_report( call.return_value = analytics_data_api.RunReportResponse( row_count=992, kind="kind_value", ) - 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 - assert response.kind == "kind_value" @@ -500,7 +524,7 @@ 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 = BetaAnalyticsDataClient( - credentials=credentials.AnonymousCredentials(), transport="grpc", + credentials=ga_credentials.AnonymousCredentials(), transport="grpc", ) # Mock the actual call within the gRPC stub, and fake the request. @@ -508,7 +532,6 @@ def test_run_report_empty_call(): client.run_report() call.assert_called() _, args, _ = call.mock_calls[0] - assert args[0] == analytics_data_api.RunReportRequest() @@ -517,7 +540,7 @@ async def test_run_report_async( transport: str = "grpc_asyncio", request_type=analytics_data_api.RunReportRequest ): client = BetaAnalyticsDataAsyncClient( - credentials=credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -530,20 +553,16 @@ async def test_run_report_async( call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( analytics_data_api.RunReportResponse(row_count=992, kind="kind_value",) ) - 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 - assert response.kind == "kind_value" @@ -553,17 +572,17 @@ async def test_run_report_async_from_dict(): def test_run_report_field_headers(): - client = BetaAnalyticsDataClient(credentials=credentials.AnonymousCredentials(),) + client = BetaAnalyticsDataClient(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.RunReportRequest() + request.property = "property/value" # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object(type(client.transport.run_report), "__call__") as call: call.return_value = analytics_data_api.RunReportResponse() - client.run_report(request) # Establish that the underlying gRPC stub method was called. @@ -579,12 +598,13 @@ def test_run_report_field_headers(): @pytest.mark.asyncio async def test_run_report_field_headers_async(): client = BetaAnalyticsDataAsyncClient( - credentials=credentials.AnonymousCredentials(), + 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.RunReportRequest() + request.property = "property/value" # Mock the actual call within the gRPC stub, and fake the request. @@ -592,7 +612,6 @@ async def test_run_report_field_headers_async(): call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( analytics_data_api.RunReportResponse() ) - await client.run_report(request) # Establish that the underlying gRPC stub method was called. @@ -609,7 +628,7 @@ def test_run_pivot_report( transport: str = "grpc", request_type=analytics_data_api.RunPivotReportRequest ): client = BetaAnalyticsDataClient( - credentials=credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -622,19 +641,15 @@ def test_run_pivot_report( call.return_value = analytics_data_api.RunPivotReportResponse( kind="kind_value", ) - 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) - assert response.kind == "kind_value" @@ -646,7 +661,7 @@ 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 = BetaAnalyticsDataClient( - credentials=credentials.AnonymousCredentials(), transport="grpc", + credentials=ga_credentials.AnonymousCredentials(), transport="grpc", ) # Mock the actual call within the gRPC stub, and fake the request. @@ -654,7 +669,6 @@ def test_run_pivot_report_empty_call(): client.run_pivot_report() call.assert_called() _, args, _ = call.mock_calls[0] - assert args[0] == analytics_data_api.RunPivotReportRequest() @@ -664,7 +678,7 @@ async def test_run_pivot_report_async( request_type=analytics_data_api.RunPivotReportRequest, ): client = BetaAnalyticsDataAsyncClient( - credentials=credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -677,18 +691,15 @@ async def test_run_pivot_report_async( call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( analytics_data_api.RunPivotReportResponse(kind="kind_value",) ) - 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) - assert response.kind == "kind_value" @@ -698,17 +709,17 @@ async def test_run_pivot_report_async_from_dict(): def test_run_pivot_report_field_headers(): - client = BetaAnalyticsDataClient(credentials=credentials.AnonymousCredentials(),) + client = BetaAnalyticsDataClient(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.RunPivotReportRequest() + request.property = "property/value" # 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: call.return_value = analytics_data_api.RunPivotReportResponse() - client.run_pivot_report(request) # Establish that the underlying gRPC stub method was called. @@ -724,12 +735,13 @@ def test_run_pivot_report_field_headers(): @pytest.mark.asyncio async def test_run_pivot_report_field_headers_async(): client = BetaAnalyticsDataAsyncClient( - credentials=credentials.AnonymousCredentials(), + 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.RunPivotReportRequest() + request.property = "property/value" # Mock the actual call within the gRPC stub, and fake the request. @@ -737,7 +749,6 @@ async def test_run_pivot_report_field_headers_async(): call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( analytics_data_api.RunPivotReportResponse() ) - await client.run_pivot_report(request) # Establish that the underlying gRPC stub method was called. @@ -754,7 +765,7 @@ def test_batch_run_reports( transport: str = "grpc", request_type=analytics_data_api.BatchRunReportsRequest ): client = BetaAnalyticsDataClient( - credentials=credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -769,19 +780,15 @@ def test_batch_run_reports( call.return_value = analytics_data_api.BatchRunReportsResponse( kind="kind_value", ) - 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) - assert response.kind == "kind_value" @@ -793,7 +800,7 @@ 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 = BetaAnalyticsDataClient( - credentials=credentials.AnonymousCredentials(), transport="grpc", + credentials=ga_credentials.AnonymousCredentials(), transport="grpc", ) # Mock the actual call within the gRPC stub, and fake the request. @@ -803,7 +810,6 @@ def test_batch_run_reports_empty_call(): client.batch_run_reports() call.assert_called() _, args, _ = call.mock_calls[0] - assert args[0] == analytics_data_api.BatchRunReportsRequest() @@ -813,7 +819,7 @@ async def test_batch_run_reports_async( request_type=analytics_data_api.BatchRunReportsRequest, ): client = BetaAnalyticsDataAsyncClient( - credentials=credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -828,18 +834,15 @@ async def test_batch_run_reports_async( call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( analytics_data_api.BatchRunReportsResponse(kind="kind_value",) ) - 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) - assert response.kind == "kind_value" @@ -849,11 +852,12 @@ async def test_batch_run_reports_async_from_dict(): def test_batch_run_reports_field_headers(): - client = BetaAnalyticsDataClient(credentials=credentials.AnonymousCredentials(),) + client = BetaAnalyticsDataClient(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.BatchRunReportsRequest() + request.property = "property/value" # Mock the actual call within the gRPC stub, and fake the request. @@ -861,7 +865,6 @@ def test_batch_run_reports_field_headers(): type(client.transport.batch_run_reports), "__call__" ) as call: call.return_value = analytics_data_api.BatchRunReportsResponse() - client.batch_run_reports(request) # Establish that the underlying gRPC stub method was called. @@ -877,12 +880,13 @@ def test_batch_run_reports_field_headers(): @pytest.mark.asyncio async def test_batch_run_reports_field_headers_async(): client = BetaAnalyticsDataAsyncClient( - credentials=credentials.AnonymousCredentials(), + 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.BatchRunReportsRequest() + request.property = "property/value" # Mock the actual call within the gRPC stub, and fake the request. @@ -892,7 +896,6 @@ async def test_batch_run_reports_field_headers_async(): call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( analytics_data_api.BatchRunReportsResponse() ) - await client.batch_run_reports(request) # Establish that the underlying gRPC stub method was called. @@ -909,7 +912,7 @@ def test_batch_run_pivot_reports( transport: str = "grpc", request_type=analytics_data_api.BatchRunPivotReportsRequest ): client = BetaAnalyticsDataClient( - credentials=credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -924,19 +927,15 @@ def test_batch_run_pivot_reports( call.return_value = analytics_data_api.BatchRunPivotReportsResponse( kind="kind_value", ) - 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) - assert response.kind == "kind_value" @@ -948,7 +947,7 @@ 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 = BetaAnalyticsDataClient( - credentials=credentials.AnonymousCredentials(), transport="grpc", + credentials=ga_credentials.AnonymousCredentials(), transport="grpc", ) # Mock the actual call within the gRPC stub, and fake the request. @@ -958,7 +957,6 @@ def test_batch_run_pivot_reports_empty_call(): client.batch_run_pivot_reports() call.assert_called() _, args, _ = call.mock_calls[0] - assert args[0] == analytics_data_api.BatchRunPivotReportsRequest() @@ -968,7 +966,7 @@ async def test_batch_run_pivot_reports_async( request_type=analytics_data_api.BatchRunPivotReportsRequest, ): client = BetaAnalyticsDataAsyncClient( - credentials=credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -983,18 +981,15 @@ async def test_batch_run_pivot_reports_async( call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( analytics_data_api.BatchRunPivotReportsResponse(kind="kind_value",) ) - 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) - assert response.kind == "kind_value" @@ -1004,11 +999,12 @@ async def test_batch_run_pivot_reports_async_from_dict(): def test_batch_run_pivot_reports_field_headers(): - client = BetaAnalyticsDataClient(credentials=credentials.AnonymousCredentials(),) + client = BetaAnalyticsDataClient(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.BatchRunPivotReportsRequest() + request.property = "property/value" # Mock the actual call within the gRPC stub, and fake the request. @@ -1016,7 +1012,6 @@ def test_batch_run_pivot_reports_field_headers(): type(client.transport.batch_run_pivot_reports), "__call__" ) as call: call.return_value = analytics_data_api.BatchRunPivotReportsResponse() - client.batch_run_pivot_reports(request) # Establish that the underlying gRPC stub method was called. @@ -1032,12 +1027,13 @@ def test_batch_run_pivot_reports_field_headers(): @pytest.mark.asyncio async def test_batch_run_pivot_reports_field_headers_async(): client = BetaAnalyticsDataAsyncClient( - credentials=credentials.AnonymousCredentials(), + 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.BatchRunPivotReportsRequest() + request.property = "property/value" # Mock the actual call within the gRPC stub, and fake the request. @@ -1047,7 +1043,6 @@ async def test_batch_run_pivot_reports_field_headers_async(): call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( analytics_data_api.BatchRunPivotReportsResponse() ) - await client.batch_run_pivot_reports(request) # Establish that the underlying gRPC stub method was called. @@ -1064,7 +1059,7 @@ def test_get_metadata( transport: str = "grpc", request_type=analytics_data_api.GetMetadataRequest ): client = BetaAnalyticsDataClient( - credentials=credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -1075,19 +1070,15 @@ def test_get_metadata( 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" @@ -1099,7 +1090,7 @@ 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 = BetaAnalyticsDataClient( - credentials=credentials.AnonymousCredentials(), transport="grpc", + credentials=ga_credentials.AnonymousCredentials(), transport="grpc", ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1107,7 +1098,6 @@ def test_get_metadata_empty_call(): client.get_metadata() call.assert_called() _, args, _ = call.mock_calls[0] - assert args[0] == analytics_data_api.GetMetadataRequest() @@ -1116,7 +1106,7 @@ async def test_get_metadata_async( transport: str = "grpc_asyncio", request_type=analytics_data_api.GetMetadataRequest ): client = BetaAnalyticsDataAsyncClient( - credentials=credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -1129,18 +1119,15 @@ async def test_get_metadata_async( 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" @@ -1150,17 +1137,17 @@ async def test_get_metadata_async_from_dict(): def test_get_metadata_field_headers(): - client = BetaAnalyticsDataClient(credentials=credentials.AnonymousCredentials(),) + client = BetaAnalyticsDataClient(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. @@ -1176,12 +1163,13 @@ def test_get_metadata_field_headers(): @pytest.mark.asyncio async def test_get_metadata_field_headers_async(): client = BetaAnalyticsDataAsyncClient( - credentials=credentials.AnonymousCredentials(), + 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. @@ -1189,7 +1177,6 @@ async def test_get_metadata_field_headers_async(): 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. @@ -1203,13 +1190,12 @@ async def test_get_metadata_field_headers_async(): def test_get_metadata_flattened(): - client = BetaAnalyticsDataClient(credentials=credentials.AnonymousCredentials(),) + client = BetaAnalyticsDataClient(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",) @@ -1218,12 +1204,11 @@ def test_get_metadata_flattened(): # 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 = BetaAnalyticsDataClient(credentials=credentials.AnonymousCredentials(),) + client = BetaAnalyticsDataClient(credentials=ga_credentials.AnonymousCredentials(),) # Attempting to call a method with both a request object and flattened # fields is an error. @@ -1236,7 +1221,7 @@ def test_get_metadata_flattened_error(): @pytest.mark.asyncio async def test_get_metadata_flattened_async(): client = BetaAnalyticsDataAsyncClient( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1255,14 +1240,13 @@ async def test_get_metadata_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" @pytest.mark.asyncio async def test_get_metadata_flattened_error_async(): client = BetaAnalyticsDataAsyncClient( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) # Attempting to call a method with both a request object and flattened @@ -1277,7 +1261,7 @@ def test_run_realtime_report( transport: str = "grpc", request_type=analytics_data_api.RunRealtimeReportRequest ): client = BetaAnalyticsDataClient( - credentials=credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -1292,21 +1276,16 @@ def test_run_realtime_report( call.return_value = analytics_data_api.RunRealtimeReportResponse( row_count=992, kind="kind_value", ) - response = client.run_realtime_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() # Establish that the response is the type that we expect. - assert isinstance(response, analytics_data_api.RunRealtimeReportResponse) - assert response.row_count == 992 - assert response.kind == "kind_value" @@ -1318,7 +1297,7 @@ def test_run_realtime_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 = BetaAnalyticsDataClient( - credentials=credentials.AnonymousCredentials(), transport="grpc", + credentials=ga_credentials.AnonymousCredentials(), transport="grpc", ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1328,7 +1307,6 @@ def test_run_realtime_report_empty_call(): client.run_realtime_report() call.assert_called() _, args, _ = call.mock_calls[0] - assert args[0] == analytics_data_api.RunRealtimeReportRequest() @@ -1338,7 +1316,7 @@ async def test_run_realtime_report_async( request_type=analytics_data_api.RunRealtimeReportRequest, ): client = BetaAnalyticsDataAsyncClient( - credentials=credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -1355,20 +1333,16 @@ async def test_run_realtime_report_async( row_count=992, kind="kind_value", ) ) - response = await client.run_realtime_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() # Establish that the response is the type that we expect. assert isinstance(response, analytics_data_api.RunRealtimeReportResponse) - assert response.row_count == 992 - assert response.kind == "kind_value" @@ -1378,11 +1352,12 @@ async def test_run_realtime_report_async_from_dict(): def test_run_realtime_report_field_headers(): - client = BetaAnalyticsDataClient(credentials=credentials.AnonymousCredentials(),) + client = BetaAnalyticsDataClient(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.property = "property/value" # Mock the actual call within the gRPC stub, and fake the request. @@ -1390,7 +1365,6 @@ def test_run_realtime_report_field_headers(): type(client.transport.run_realtime_report), "__call__" ) as call: call.return_value = analytics_data_api.RunRealtimeReportResponse() - client.run_realtime_report(request) # Establish that the underlying gRPC stub method was called. @@ -1406,12 +1380,13 @@ def test_run_realtime_report_field_headers(): @pytest.mark.asyncio async def test_run_realtime_report_field_headers_async(): client = BetaAnalyticsDataAsyncClient( - credentials=credentials.AnonymousCredentials(), + 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.property = "property/value" # Mock the actual call within the gRPC stub, and fake the request. @@ -1421,7 +1396,6 @@ async def test_run_realtime_report_field_headers_async(): call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( analytics_data_api.RunRealtimeReportResponse() ) - await client.run_realtime_report(request) # Establish that the underlying gRPC stub method was called. @@ -1437,16 +1411,16 @@ async def test_run_realtime_report_field_headers_async(): def test_credentials_transport_error(): # It is an error to provide credentials and a transport instance. transport = transports.BetaAnalyticsDataGrpcTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) with pytest.raises(ValueError): client = BetaAnalyticsDataClient( - credentials=credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) # It is an error to provide a credentials file and a transport instance. transport = transports.BetaAnalyticsDataGrpcTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) with pytest.raises(ValueError): client = BetaAnalyticsDataClient( @@ -1456,7 +1430,7 @@ def test_credentials_transport_error(): # It is an error to provide scopes and a transport instance. transport = transports.BetaAnalyticsDataGrpcTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) with pytest.raises(ValueError): client = BetaAnalyticsDataClient( @@ -1467,7 +1441,7 @@ def test_credentials_transport_error(): def test_transport_instance(): # A client may be instantiated with a custom transport instance. transport = transports.BetaAnalyticsDataGrpcTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) client = BetaAnalyticsDataClient(transport=transport) assert client.transport is transport @@ -1476,13 +1450,13 @@ def test_transport_instance(): def test_transport_get_channel(): # A client may be instantiated with a custom transport instance. transport = transports.BetaAnalyticsDataGrpcTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) channel = transport.grpc_channel assert channel transport = transports.BetaAnalyticsDataGrpcAsyncIOTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) channel = transport.grpc_channel assert channel @@ -1497,23 +1471,23 @@ def test_transport_get_channel(): ) def test_transport_adc(transport_class): # Test default credentials are used if not provided. - with mock.patch.object(auth, "default") as adc: - adc.return_value = (credentials.AnonymousCredentials(), None) + with mock.patch.object(google.auth, "default") as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) transport_class() adc.assert_called_once() def test_transport_grpc_default(): # A client should use the gRPC transport by default. - client = BetaAnalyticsDataClient(credentials=credentials.AnonymousCredentials(),) + client = BetaAnalyticsDataClient(credentials=ga_credentials.AnonymousCredentials(),) assert isinstance(client.transport, transports.BetaAnalyticsDataGrpcTransport,) def test_beta_analytics_data_base_transport_error(): # Passing both a credentials object and credentials_file should raise an error - with pytest.raises(exceptions.DuplicateCredentialArgs): + with pytest.raises(core_exceptions.DuplicateCredentialArgs): transport = transports.BetaAnalyticsDataTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), credentials_file="credentials.json", ) @@ -1525,7 +1499,7 @@ def test_beta_analytics_data_base_transport(): ) as Transport: Transport.return_value = None transport = transports.BetaAnalyticsDataTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) # Every method on the transport should just blindly @@ -1543,15 +1517,40 @@ def test_beta_analytics_data_base_transport(): getattr(transport, method)(request=object()) +@requires_google_auth_gte_1_25_0 def test_beta_analytics_data_base_transport_with_credentials_file(): # Instantiate the base transport with a credentials file with mock.patch.object( - auth, "load_credentials_from_file" + google.auth, "load_credentials_from_file", autospec=True ) as load_creds, mock.patch( "google.analytics.data_v1beta.services.beta_analytics_data.transports.BetaAnalyticsDataTransport._prep_wrapped_messages" ) as Transport: Transport.return_value = None - load_creds.return_value = (credentials.AnonymousCredentials(), None) + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.BetaAnalyticsDataTransport( + credentials_file="credentials.json", quota_project_id="octopus", + ) + load_creds.assert_called_once_with( + "credentials.json", + scopes=None, + default_scopes=( + "https://www.googleapis.com/auth/analytics", + "https://www.googleapis.com/auth/analytics.readonly", + ), + quota_project_id="octopus", + ) + + +@requires_google_auth_lt_1_25_0 +def test_beta_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_v1beta.services.beta_analytics_data.transports.BetaAnalyticsDataTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) transport = transports.BetaAnalyticsDataTransport( credentials_file="credentials.json", quota_project_id="octopus", ) @@ -1567,19 +1566,36 @@ def test_beta_analytics_data_base_transport_with_credentials_file(): def test_beta_analytics_data_base_transport_with_adc(): # Test the default credentials are used if credentials and credentials_file are None. - with mock.patch.object(auth, "default") as adc, mock.patch( + with mock.patch.object(google.auth, "default", autospec=True) as adc, mock.patch( "google.analytics.data_v1beta.services.beta_analytics_data.transports.BetaAnalyticsDataTransport._prep_wrapped_messages" ) as Transport: Transport.return_value = None - adc.return_value = (credentials.AnonymousCredentials(), None) + adc.return_value = (ga_credentials.AnonymousCredentials(), None) transport = transports.BetaAnalyticsDataTransport() adc.assert_called_once() +@requires_google_auth_gte_1_25_0 def test_beta_analytics_data_auth_adc(): # If no credentials are provided, we should use ADC credentials. - with mock.patch.object(auth, "default") as adc: - adc.return_value = (credentials.AnonymousCredentials(), None) + with mock.patch.object(google.auth, "default", autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + BetaAnalyticsDataClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=( + "https://www.googleapis.com/auth/analytics", + "https://www.googleapis.com/auth/analytics.readonly", + ), + quota_project_id=None, + ) + + +@requires_google_auth_lt_1_25_0 +def test_beta_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) BetaAnalyticsDataClient() adc.assert_called_once_with( scopes=( @@ -1590,14 +1606,44 @@ def test_beta_analytics_data_auth_adc(): ) -def test_beta_analytics_data_transport_auth_adc(): +@pytest.mark.parametrize( + "transport_class", + [ + transports.BetaAnalyticsDataGrpcTransport, + transports.BetaAnalyticsDataGrpcAsyncIOTransport, + ], +) +@requires_google_auth_gte_1_25_0 +def test_beta_analytics_data_transport_auth_adc(transport_class): # If credentials and host are not provided, the transport class should use # ADC credentials. - with mock.patch.object(auth, "default") as adc: - adc.return_value = (credentials.AnonymousCredentials(), None) - transports.BetaAnalyticsDataGrpcTransport( - host="squid.clam.whelk", quota_project_id="octopus" + with mock.patch.object(google.auth, "default", autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class(quota_project_id="octopus", scopes=["1", "2"]) + adc.assert_called_once_with( + scopes=["1", "2"], + default_scopes=( + "https://www.googleapis.com/auth/analytics", + "https://www.googleapis.com/auth/analytics.readonly", + ), + quota_project_id="octopus", ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.BetaAnalyticsDataGrpcTransport, + transports.BetaAnalyticsDataGrpcAsyncIOTransport, + ], +) +@requires_google_auth_lt_1_25_0 +def test_beta_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", @@ -1607,6 +1653,121 @@ def test_beta_analytics_data_transport_auth_adc(): ) +@pytest.mark.parametrize( + "transport_class,grpc_helpers", + [ + (transports.BetaAnalyticsDataGrpcTransport, grpc_helpers), + (transports.BetaAnalyticsDataGrpcAsyncIOTransport, grpc_helpers_async), + ], +) +@requires_api_core_gte_1_26_0 +def test_beta_analytics_data_transport_create_channel(transport_class, grpc_helpers): + # 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, mock.patch.object( + grpc_helpers, "create_channel", autospec=True + ) as create_channel: + creds = ga_credentials.AnonymousCredentials() + adc.return_value = (creds, None) + transport_class(quota_project_id="octopus", scopes=["1", "2"]) + + create_channel.assert_called_with( + "analyticsdata.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + default_scopes=( + "https://www.googleapis.com/auth/analytics", + "https://www.googleapis.com/auth/analytics.readonly", + ), + scopes=["1", "2"], + default_host="analyticsdata.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize( + "transport_class,grpc_helpers", + [ + (transports.BetaAnalyticsDataGrpcTransport, grpc_helpers), + (transports.BetaAnalyticsDataGrpcAsyncIOTransport, grpc_helpers_async), + ], +) +@requires_api_core_lt_1_26_0 +def test_beta_analytics_data_transport_create_channel_old_api_core( + transport_class, grpc_helpers +): + # 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, mock.patch.object( + grpc_helpers, "create_channel", autospec=True + ) as create_channel: + creds = ga_credentials.AnonymousCredentials() + adc.return_value = (creds, None) + transport_class(quota_project_id="octopus") + + create_channel.assert_called_with( + "analyticsdata.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + scopes=( + "https://www.googleapis.com/auth/analytics", + "https://www.googleapis.com/auth/analytics.readonly", + ), + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize( + "transport_class,grpc_helpers", + [ + (transports.BetaAnalyticsDataGrpcTransport, grpc_helpers), + (transports.BetaAnalyticsDataGrpcAsyncIOTransport, grpc_helpers_async), + ], +) +@requires_api_core_lt_1_26_0 +def test_beta_analytics_data_transport_create_channel_user_scopes( + transport_class, grpc_helpers +): + # 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, mock.patch.object( + grpc_helpers, "create_channel", autospec=True + ) as create_channel: + creds = ga_credentials.AnonymousCredentials() + adc.return_value = (creds, None) + + transport_class(quota_project_id="octopus", scopes=["1", "2"]) + + create_channel.assert_called_with( + "analyticsdata.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + scopes=["1", "2"], + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + @pytest.mark.parametrize( "transport_class", [ @@ -1617,7 +1778,7 @@ def test_beta_analytics_data_transport_auth_adc(): def test_beta_analytics_data_grpc_transport_client_cert_source_for_mtls( transport_class, ): - cred = credentials.AnonymousCredentials() + cred = ga_credentials.AnonymousCredentials() # Check ssl_channel_credentials is used if provided. with mock.patch.object(transport_class, "create_channel") as mock_create_channel: @@ -1659,7 +1820,7 @@ def test_beta_analytics_data_grpc_transport_client_cert_source_for_mtls( def test_beta_analytics_data_host_no_port(): client = BetaAnalyticsDataClient( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), client_options=client_options.ClientOptions( api_endpoint="analyticsdata.googleapis.com" ), @@ -1669,7 +1830,7 @@ def test_beta_analytics_data_host_no_port(): def test_beta_analytics_data_host_with_port(): client = BetaAnalyticsDataClient( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), client_options=client_options.ClientOptions( api_endpoint="analyticsdata.googleapis.com:8000" ), @@ -1725,9 +1886,9 @@ def test_beta_analytics_data_transport_channel_mtls_with_client_cert_source( mock_grpc_channel = mock.Mock() grpc_create_channel.return_value = mock_grpc_channel - cred = credentials.AnonymousCredentials() + cred = ga_credentials.AnonymousCredentials() with pytest.warns(DeprecationWarning): - with mock.patch.object(auth, "default") as adc: + with mock.patch.object(google.auth, "default") as adc: adc.return_value = (cred, None) transport = transport_class( host="squid.clam.whelk", @@ -1809,7 +1970,6 @@ def test_beta_analytics_data_transport_channel_mtls_with_adc(transport_class): def test_metadata_path(): property = "squid" - expected = "properties/{property}/metadata".format(property=property,) actual = BetaAnalyticsDataClient.metadata_path(property) assert expected == actual @@ -1828,7 +1988,6 @@ def test_parse_metadata_path(): def test_common_billing_account_path(): billing_account = "whelk" - expected = "billingAccounts/{billing_account}".format( billing_account=billing_account, ) @@ -1849,7 +2008,6 @@ def test_parse_common_billing_account_path(): def test_common_folder_path(): folder = "oyster" - expected = "folders/{folder}".format(folder=folder,) actual = BetaAnalyticsDataClient.common_folder_path(folder) assert expected == actual @@ -1868,7 +2026,6 @@ def test_parse_common_folder_path(): def test_common_organization_path(): organization = "cuttlefish" - expected = "organizations/{organization}".format(organization=organization,) actual = BetaAnalyticsDataClient.common_organization_path(organization) assert expected == actual @@ -1887,7 +2044,6 @@ def test_parse_common_organization_path(): def test_common_project_path(): project = "winkle" - expected = "projects/{project}".format(project=project,) actual = BetaAnalyticsDataClient.common_project_path(project) assert expected == actual @@ -1907,7 +2063,6 @@ def test_parse_common_project_path(): def test_common_location_path(): project = "scallop" location = "abalone" - expected = "projects/{project}/locations/{location}".format( project=project, location=location, ) @@ -1934,7 +2089,7 @@ def test_client_withDEFAULT_CLIENT_INFO(): transports.BetaAnalyticsDataTransport, "_prep_wrapped_messages" ) as prep: client = BetaAnalyticsDataClient( - credentials=credentials.AnonymousCredentials(), client_info=client_info, + credentials=ga_credentials.AnonymousCredentials(), client_info=client_info, ) prep.assert_called_once_with(client_info) @@ -1943,6 +2098,6 @@ def test_client_withDEFAULT_CLIENT_INFO(): ) as prep: transport_class = BetaAnalyticsDataClient.get_transport_class() transport = transport_class( - credentials=credentials.AnonymousCredentials(), client_info=client_info, + credentials=ga_credentials.AnonymousCredentials(), client_info=client_info, ) prep.assert_called_once_with(client_info)