diff --git a/packages/google-analytics-admin/google/analytics/admin_v1beta/__init__.py b/packages/google-analytics-admin/google/analytics/admin_v1beta/__init__.py index 769bbb6a0df1..aec458fb544d 100644 --- a/packages/google-analytics-admin/google/analytics/admin_v1beta/__init__.py +++ b/packages/google-analytics-admin/google/analytics/admin_v1beta/__init__.py @@ -22,6 +22,27 @@ AnalyticsAdminServiceAsyncClient, AnalyticsAdminServiceClient, ) +from .types.access_report import ( + AccessBetweenFilter, + AccessDateRange, + AccessDimension, + AccessDimensionHeader, + AccessDimensionValue, + AccessFilter, + AccessFilterExpression, + AccessFilterExpressionList, + AccessInListFilter, + AccessMetric, + AccessMetricHeader, + AccessMetricValue, + AccessNumericFilter, + AccessOrderBy, + AccessQuota, + AccessQuotaStatus, + AccessRow, + AccessStringFilter, + NumericValue, +) from .types.analytics_admin import ( AcknowledgeUserDataCollectionRequest, AcknowledgeUserDataCollectionResponse, @@ -73,6 +94,8 @@ ListPropertiesResponse, ProvisionAccountTicketRequest, ProvisionAccountTicketResponse, + RunAccessReportRequest, + RunAccessReportResponse, SearchChangeHistoryEventsRequest, SearchChangeHistoryEventsResponse, UpdateAccountRequest, @@ -110,6 +133,24 @@ __all__ = ( "AnalyticsAdminServiceAsyncClient", + "AccessBetweenFilter", + "AccessDateRange", + "AccessDimension", + "AccessDimensionHeader", + "AccessDimensionValue", + "AccessFilter", + "AccessFilterExpression", + "AccessFilterExpressionList", + "AccessInListFilter", + "AccessMetric", + "AccessMetricHeader", + "AccessMetricValue", + "AccessNumericFilter", + "AccessOrderBy", + "AccessQuota", + "AccessQuotaStatus", + "AccessRow", + "AccessStringFilter", "Account", "AccountSummary", "AcknowledgeUserDataCollectionRequest", @@ -176,11 +217,14 @@ "ListPropertiesRequest", "ListPropertiesResponse", "MeasurementProtocolSecret", + "NumericValue", "Property", "PropertySummary", "PropertyType", "ProvisionAccountTicketRequest", "ProvisionAccountTicketResponse", + "RunAccessReportRequest", + "RunAccessReportResponse", "SearchChangeHistoryEventsRequest", "SearchChangeHistoryEventsResponse", "ServiceLevel", diff --git a/packages/google-analytics-admin/google/analytics/admin_v1beta/gapic_metadata.json b/packages/google-analytics-admin/google/analytics/admin_v1beta/gapic_metadata.json index 9cc2698502d3..444b369365a7 100644 --- a/packages/google-analytics-admin/google/analytics/admin_v1beta/gapic_metadata.json +++ b/packages/google-analytics-admin/google/analytics/admin_v1beta/gapic_metadata.json @@ -200,6 +200,11 @@ "provision_account_ticket" ] }, + "RunAccessReport": { + "methods": [ + "run_access_report" + ] + }, "SearchChangeHistoryEvents": { "methods": [ "search_change_history_events" @@ -440,6 +445,11 @@ "provision_account_ticket" ] }, + "RunAccessReport": { + "methods": [ + "run_access_report" + ] + }, "SearchChangeHistoryEvents": { "methods": [ "search_change_history_events" @@ -680,6 +690,11 @@ "provision_account_ticket" ] }, + "RunAccessReport": { + "methods": [ + "run_access_report" + ] + }, "SearchChangeHistoryEvents": { "methods": [ "search_change_history_events" diff --git a/packages/google-analytics-admin/google/analytics/admin_v1beta/services/analytics_admin_service/async_client.py b/packages/google-analytics-admin/google/analytics/admin_v1beta/services/analytics_admin_service/async_client.py index ab8aa22d4d39..eb56c83c9bcc 100644 --- a/packages/google-analytics-admin/google/analytics/admin_v1beta/services/analytics_admin_service/async_client.py +++ b/packages/google-analytics-admin/google/analytics/admin_v1beta/services/analytics_admin_service/async_client.py @@ -47,7 +47,11 @@ from google.protobuf import wrappers_pb2 # type: ignore from google.analytics.admin_v1beta.services.analytics_admin_service import pagers -from google.analytics.admin_v1beta.types import analytics_admin, resources +from google.analytics.admin_v1beta.types import ( + access_report, + analytics_admin, + resources, +) from .client import AnalyticsAdminServiceClient from .transports.base import DEFAULT_CLIENT_INFO, AnalyticsAdminServiceTransport @@ -358,7 +362,7 @@ async def sample_get_account(): # and friendly error handling. rpc = gapic_v1.method_async.wrap_method( self._client._transport.get_account, - default_timeout=60.0, + default_timeout=None, client_info=DEFAULT_CLIENT_INFO, ) @@ -443,7 +447,7 @@ async def sample_list_accounts(): # and friendly error handling. rpc = gapic_v1.method_async.wrap_method( self._client._transport.list_accounts, - default_timeout=60.0, + default_timeout=None, client_info=DEFAULT_CLIENT_INFO, ) @@ -550,7 +554,7 @@ async def sample_delete_account(): # and friendly error handling. rpc = gapic_v1.method_async.wrap_method( self._client._transport.delete_account, - default_timeout=60.0, + default_timeout=None, client_info=DEFAULT_CLIENT_INFO, ) @@ -622,10 +626,10 @@ async def sample_update_account(): should not be set. update_mask (:class:`google.protobuf.field_mask_pb2.FieldMask`): Required. The list of fields to be updated. Field names - must be in snake case (e.g., "field_to_update"). Omitted - fields will not be updated. To replace the entire - entity, use one path with the string "*" to match all - fields. + must be in snake case (for example, "field_to_update"). + Omitted fields will not be updated. To replace the + entire entity, use one path with the string "*" to match + all fields. This corresponds to the ``update_mask`` field on the ``request`` instance; if ``request`` is provided, this @@ -665,7 +669,7 @@ async def sample_update_account(): # and friendly error handling. rpc = gapic_v1.method_async.wrap_method( self._client._transport.update_account, - default_timeout=60.0, + default_timeout=None, client_info=DEFAULT_CLIENT_INFO, ) @@ -748,7 +752,7 @@ async def sample_provision_account_ticket(): # and friendly error handling. rpc = gapic_v1.method_async.wrap_method( self._client._transport.provision_account_ticket, - default_timeout=60.0, + default_timeout=None, client_info=DEFAULT_CLIENT_INFO, ) @@ -932,7 +936,7 @@ async def sample_get_property(): # and friendly error handling. rpc = gapic_v1.method_async.wrap_method( self._client._transport.get_property, - default_timeout=60.0, + default_timeout=None, client_info=DEFAULT_CLIENT_INFO, ) @@ -1022,7 +1026,7 @@ async def sample_list_properties(): # and friendly error handling. rpc = gapic_v1.method_async.wrap_method( self._client._transport.list_properties, - default_timeout=60.0, + default_timeout=None, client_info=DEFAULT_CLIENT_INFO, ) @@ -1133,7 +1137,7 @@ async def sample_create_property(): # and friendly error handling. rpc = gapic_v1.method_async.wrap_method( self._client._transport.create_property, - default_timeout=60.0, + default_timeout=None, client_info=DEFAULT_CLIENT_INFO, ) @@ -1167,8 +1171,8 @@ async def delete_property( GoogleAdsLinks, Streams, UserLinks) will be permanently purged. https://support.google.com/analytics/answer/6154772 - Returns an error if the target is not found, or is not - an GA4 Property. + Returns an error if the target is not found, or is not a + GA4 Property. .. code-block:: python @@ -1241,7 +1245,7 @@ async def sample_delete_property(): # and friendly error handling. rpc = gapic_v1.method_async.wrap_method( self._client._transport.delete_property, - default_timeout=60.0, + default_timeout=None, client_info=DEFAULT_CLIENT_INFO, ) @@ -1361,7 +1365,7 @@ async def sample_update_property(): # and friendly error handling. rpc = gapic_v1.method_async.wrap_method( self._client._transport.update_property, - default_timeout=60.0, + default_timeout=None, client_info=DEFAULT_CLIENT_INFO, ) @@ -1478,7 +1482,7 @@ async def sample_create_firebase_link(): # and friendly error handling. rpc = gapic_v1.method_async.wrap_method( self._client._transport.create_firebase_link, - default_timeout=60.0, + default_timeout=None, client_info=DEFAULT_CLIENT_INFO, ) @@ -1574,7 +1578,7 @@ async def sample_delete_firebase_link(): # and friendly error handling. rpc = gapic_v1.method_async.wrap_method( self._client._transport.delete_firebase_link, - default_timeout=60.0, + default_timeout=None, client_info=DEFAULT_CLIENT_INFO, ) @@ -1678,7 +1682,7 @@ async def sample_list_firebase_links(): # and friendly error handling. rpc = gapic_v1.method_async.wrap_method( self._client._transport.list_firebase_links, - default_timeout=60.0, + default_timeout=None, client_info=DEFAULT_CLIENT_INFO, ) @@ -1801,7 +1805,7 @@ async def sample_create_google_ads_link(): # and friendly error handling. rpc = gapic_v1.method_async.wrap_method( self._client._transport.create_google_ads_link, - default_timeout=60.0, + default_timeout=None, client_info=DEFAULT_CLIENT_INFO, ) @@ -1915,7 +1919,7 @@ async def sample_update_google_ads_link(): # and friendly error handling. rpc = gapic_v1.method_async.wrap_method( self._client._transport.update_google_ads_link, - default_timeout=60.0, + default_timeout=None, client_info=DEFAULT_CLIENT_INFO, ) @@ -2012,7 +2016,7 @@ async def sample_delete_google_ads_link(): # and friendly error handling. rpc = gapic_v1.method_async.wrap_method( self._client._transport.delete_google_ads_link, - default_timeout=60.0, + default_timeout=None, client_info=DEFAULT_CLIENT_INFO, ) @@ -2117,7 +2121,7 @@ async def sample_list_google_ads_links(): # and friendly error handling. rpc = gapic_v1.method_async.wrap_method( self._client._transport.list_google_ads_links, - default_timeout=60.0, + default_timeout=None, client_info=DEFAULT_CLIENT_INFO, ) @@ -2834,7 +2838,7 @@ async def acknowledge_user_data_collection( r"""Acknowledges the terms of user data collection for the specified property. This acknowledgement must be completed (either in the - Google Analytics UI or via this API) before + Google Analytics UI or through this API) before MeasurementProtocolSecret resources may be created. .. code-block:: python @@ -5293,6 +5297,99 @@ async def sample_get_data_stream(): # Done; return the response. return response + async def run_access_report( + self, + request: Optional[Union[analytics_admin.RunAccessReportRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> analytics_admin.RunAccessReportResponse: + r"""Returns a customized report of data access records. The report + provides records of each time a user reads Google Analytics + reporting data. Access records are retained for up to 2 years. + + Data Access Reports can be requested for a property. The + property must be in Google Analytics 360. This method is only + available to Administrators. + + These data access records include GA4 UI Reporting, GA4 UI + Explorations, GA4 Data API, and other products like Firebase & + Admob that can retrieve data from Google Analytics through a + linkage. These records don't include property configuration + changes like adding a stream or changing a property's time zone. + For configuration change history, see + `searchChangeHistoryEvents `__. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.analytics import admin_v1beta + + async def sample_run_access_report(): + # Create a client + client = admin_v1beta.AnalyticsAdminServiceAsyncClient() + + # Initialize request argument(s) + request = admin_v1beta.RunAccessReportRequest( + ) + + # Make the request + response = await client.run_access_report(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.analytics.admin_v1beta.types.RunAccessReportRequest, dict]]): + The request object. The request for a Data Access Record + Report. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.analytics.admin_v1beta.types.RunAccessReportResponse: + The customized Data Access Record + Report response. + + """ + # Create or coerce a protobuf request object. + request = analytics_admin.RunAccessReportRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.run_access_report, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("entity", request.entity),)), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + async def __aenter__(self): return self diff --git a/packages/google-analytics-admin/google/analytics/admin_v1beta/services/analytics_admin_service/client.py b/packages/google-analytics-admin/google/analytics/admin_v1beta/services/analytics_admin_service/client.py index 6b5e2404d187..2a158d707e32 100644 --- a/packages/google-analytics-admin/google/analytics/admin_v1beta/services/analytics_admin_service/client.py +++ b/packages/google-analytics-admin/google/analytics/admin_v1beta/services/analytics_admin_service/client.py @@ -51,7 +51,11 @@ from google.protobuf import wrappers_pb2 # type: ignore from google.analytics.admin_v1beta.services.analytics_admin_service import pagers -from google.analytics.admin_v1beta.types import analytics_admin, resources +from google.analytics.admin_v1beta.types import ( + access_report, + analytics_admin, + resources, +) from .transports.base import DEFAULT_CLIENT_INFO, AnalyticsAdminServiceTransport from .transports.grpc import AnalyticsAdminServiceGrpcTransport @@ -985,10 +989,10 @@ def sample_update_account(): should not be set. update_mask (google.protobuf.field_mask_pb2.FieldMask): Required. The list of fields to be updated. Field names - must be in snake case (e.g., "field_to_update"). Omitted - fields will not be updated. To replace the entire - entity, use one path with the string "*" to match all - fields. + must be in snake case (for example, "field_to_update"). + Omitted fields will not be updated. To replace the + entire entity, use one path with the string "*" to match + all fields. This corresponds to the ``update_mask`` field on the ``request`` instance; if ``request`` is provided, this @@ -1533,8 +1537,8 @@ def delete_property( GoogleAdsLinks, Streams, UserLinks) will be permanently purged. https://support.google.com/analytics/answer/6154772 - Returns an error if the target is not found, or is not - an GA4 Property. + Returns an error if the target is not found, or is not a + GA4 Property. .. code-block:: python @@ -3220,7 +3224,7 @@ def acknowledge_user_data_collection( r"""Acknowledges the terms of user data collection for the specified property. This acknowledgement must be completed (either in the - Google Analytics UI or via this API) before + Google Analytics UI or through this API) before MeasurementProtocolSecret resources may be created. .. code-block:: python @@ -5691,6 +5695,100 @@ def sample_get_data_stream(): # Done; return the response. return response + def run_access_report( + self, + request: Optional[Union[analytics_admin.RunAccessReportRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> analytics_admin.RunAccessReportResponse: + r"""Returns a customized report of data access records. The report + provides records of each time a user reads Google Analytics + reporting data. Access records are retained for up to 2 years. + + Data Access Reports can be requested for a property. The + property must be in Google Analytics 360. This method is only + available to Administrators. + + These data access records include GA4 UI Reporting, GA4 UI + Explorations, GA4 Data API, and other products like Firebase & + Admob that can retrieve data from Google Analytics through a + linkage. These records don't include property configuration + changes like adding a stream or changing a property's time zone. + For configuration change history, see + `searchChangeHistoryEvents `__. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.analytics import admin_v1beta + + def sample_run_access_report(): + # Create a client + client = admin_v1beta.AnalyticsAdminServiceClient() + + # Initialize request argument(s) + request = admin_v1beta.RunAccessReportRequest( + ) + + # Make the request + response = client.run_access_report(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.analytics.admin_v1beta.types.RunAccessReportRequest, dict]): + The request object. The request for a Data Access Record + Report. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.analytics.admin_v1beta.types.RunAccessReportResponse: + The customized Data Access Record + Report response. + + """ + # Create or coerce a protobuf request object. + # Minor optimization to avoid making a copy if the user passes + # in a analytics_admin.RunAccessReportRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, analytics_admin.RunAccessReportRequest): + request = analytics_admin.RunAccessReportRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.run_access_report] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("entity", request.entity),)), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + def __enter__(self) -> "AnalyticsAdminServiceClient": return self diff --git a/packages/google-analytics-admin/google/analytics/admin_v1beta/services/analytics_admin_service/transports/base.py b/packages/google-analytics-admin/google/analytics/admin_v1beta/services/analytics_admin_service/transports/base.py index 9b682f4cb8e4..a5d82b0fa54c 100644 --- a/packages/google-analytics-admin/google/analytics/admin_v1beta/services/analytics_admin_service/transports/base.py +++ b/packages/google-analytics-admin/google/analytics/admin_v1beta/services/analytics_admin_service/transports/base.py @@ -128,27 +128,27 @@ def _prep_wrapped_messages(self, client_info): self._wrapped_methods = { self.get_account: gapic_v1.method.wrap_method( self.get_account, - default_timeout=60.0, + default_timeout=None, client_info=client_info, ), self.list_accounts: gapic_v1.method.wrap_method( self.list_accounts, - default_timeout=60.0, + default_timeout=None, client_info=client_info, ), self.delete_account: gapic_v1.method.wrap_method( self.delete_account, - default_timeout=60.0, + default_timeout=None, client_info=client_info, ), self.update_account: gapic_v1.method.wrap_method( self.update_account, - default_timeout=60.0, + default_timeout=None, client_info=client_info, ), self.provision_account_ticket: gapic_v1.method.wrap_method( self.provision_account_ticket, - default_timeout=60.0, + default_timeout=None, client_info=client_info, ), self.list_account_summaries: gapic_v1.method.wrap_method( @@ -158,62 +158,62 @@ def _prep_wrapped_messages(self, client_info): ), self.get_property: gapic_v1.method.wrap_method( self.get_property, - default_timeout=60.0, + default_timeout=None, client_info=client_info, ), self.list_properties: gapic_v1.method.wrap_method( self.list_properties, - default_timeout=60.0, + default_timeout=None, client_info=client_info, ), self.create_property: gapic_v1.method.wrap_method( self.create_property, - default_timeout=60.0, + default_timeout=None, client_info=client_info, ), self.delete_property: gapic_v1.method.wrap_method( self.delete_property, - default_timeout=60.0, + default_timeout=None, client_info=client_info, ), self.update_property: gapic_v1.method.wrap_method( self.update_property, - default_timeout=60.0, + default_timeout=None, client_info=client_info, ), self.create_firebase_link: gapic_v1.method.wrap_method( self.create_firebase_link, - default_timeout=60.0, + default_timeout=None, client_info=client_info, ), self.delete_firebase_link: gapic_v1.method.wrap_method( self.delete_firebase_link, - default_timeout=60.0, + default_timeout=None, client_info=client_info, ), self.list_firebase_links: gapic_v1.method.wrap_method( self.list_firebase_links, - default_timeout=60.0, + default_timeout=None, client_info=client_info, ), self.create_google_ads_link: gapic_v1.method.wrap_method( self.create_google_ads_link, - default_timeout=60.0, + default_timeout=None, client_info=client_info, ), self.update_google_ads_link: gapic_v1.method.wrap_method( self.update_google_ads_link, - default_timeout=60.0, + default_timeout=None, client_info=client_info, ), self.delete_google_ads_link: gapic_v1.method.wrap_method( self.delete_google_ads_link, - default_timeout=60.0, + default_timeout=None, client_info=client_info, ), self.list_google_ads_links: gapic_v1.method.wrap_method( self.list_google_ads_links, - default_timeout=60.0, + default_timeout=None, client_info=client_info, ), self.get_data_sharing_settings: gapic_v1.method.wrap_method( @@ -361,6 +361,11 @@ def _prep_wrapped_messages(self, client_info): default_timeout=None, client_info=client_info, ), + self.run_access_report: gapic_v1.method.wrap_method( + self.run_access_report, + default_timeout=None, + client_info=client_info, + ), } def close(self): @@ -847,6 +852,18 @@ def get_data_stream( ]: raise NotImplementedError() + @property + def run_access_report( + self, + ) -> Callable[ + [analytics_admin.RunAccessReportRequest], + Union[ + analytics_admin.RunAccessReportResponse, + Awaitable[analytics_admin.RunAccessReportResponse], + ], + ]: + raise NotImplementedError() + @property def kind(self) -> str: raise NotImplementedError() diff --git a/packages/google-analytics-admin/google/analytics/admin_v1beta/services/analytics_admin_service/transports/grpc.py b/packages/google-analytics-admin/google/analytics/admin_v1beta/services/analytics_admin_service/transports/grpc.py index 600257d5899c..56f91a4434c9 100644 --- a/packages/google-analytics-admin/google/analytics/admin_v1beta/services/analytics_admin_service/transports/grpc.py +++ b/packages/google-analytics-admin/google/analytics/admin_v1beta/services/analytics_admin_service/transports/grpc.py @@ -511,8 +511,8 @@ def delete_property( GoogleAdsLinks, Streams, UserLinks) will be permanently purged. https://support.google.com/analytics/answer/6154772 - Returns an error if the target is not found, or is not - an GA4 Property. + Returns an error if the target is not found, or is not a + GA4 Property. Returns: Callable[[~.DeletePropertyRequest], @@ -954,7 +954,7 @@ def acknowledge_user_data_collection( Acknowledges the terms of user data collection for the specified property. This acknowledgement must be completed (either in the - Google Analytics UI or via this API) before + Google Analytics UI or through this API) before MeasurementProtocolSecret resources may be created. Returns: @@ -1588,6 +1588,49 @@ def get_data_stream( ) return self._stubs["get_data_stream"] + @property + def run_access_report( + self, + ) -> Callable[ + [analytics_admin.RunAccessReportRequest], + analytics_admin.RunAccessReportResponse, + ]: + r"""Return a callable for the run access report method over gRPC. + + Returns a customized report of data access records. The report + provides records of each time a user reads Google Analytics + reporting data. Access records are retained for up to 2 years. + + Data Access Reports can be requested for a property. The + property must be in Google Analytics 360. This method is only + available to Administrators. + + These data access records include GA4 UI Reporting, GA4 UI + Explorations, GA4 Data API, and other products like Firebase & + Admob that can retrieve data from Google Analytics through a + linkage. These records don't include property configuration + changes like adding a stream or changing a property's time zone. + For configuration change history, see + `searchChangeHistoryEvents `__. + + Returns: + Callable[[~.RunAccessReportRequest], + ~.RunAccessReportResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "run_access_report" not in self._stubs: + self._stubs["run_access_report"] = self.grpc_channel.unary_unary( + "/google.analytics.admin.v1beta.AnalyticsAdminService/RunAccessReport", + request_serializer=analytics_admin.RunAccessReportRequest.serialize, + response_deserializer=analytics_admin.RunAccessReportResponse.deserialize, + ) + return self._stubs["run_access_report"] + def close(self): self.grpc_channel.close() diff --git a/packages/google-analytics-admin/google/analytics/admin_v1beta/services/analytics_admin_service/transports/grpc_asyncio.py b/packages/google-analytics-admin/google/analytics/admin_v1beta/services/analytics_admin_service/transports/grpc_asyncio.py index 6be73269f2cd..07a3fce18ad7 100644 --- a/packages/google-analytics-admin/google/analytics/admin_v1beta/services/analytics_admin_service/transports/grpc_asyncio.py +++ b/packages/google-analytics-admin/google/analytics/admin_v1beta/services/analytics_admin_service/transports/grpc_asyncio.py @@ -520,8 +520,8 @@ def delete_property( GoogleAdsLinks, Streams, UserLinks) will be permanently purged. https://support.google.com/analytics/answer/6154772 - Returns an error if the target is not found, or is not - an GA4 Property. + Returns an error if the target is not found, or is not a + GA4 Property. Returns: Callable[[~.DeletePropertyRequest], @@ -973,7 +973,7 @@ def acknowledge_user_data_collection( Acknowledges the terms of user data collection for the specified property. This acknowledgement must be completed (either in the - Google Analytics UI or via this API) before + Google Analytics UI or through this API) before MeasurementProtocolSecret resources may be created. Returns: @@ -1632,6 +1632,49 @@ def get_data_stream( ) return self._stubs["get_data_stream"] + @property + def run_access_report( + self, + ) -> Callable[ + [analytics_admin.RunAccessReportRequest], + Awaitable[analytics_admin.RunAccessReportResponse], + ]: + r"""Return a callable for the run access report method over gRPC. + + Returns a customized report of data access records. The report + provides records of each time a user reads Google Analytics + reporting data. Access records are retained for up to 2 years. + + Data Access Reports can be requested for a property. The + property must be in Google Analytics 360. This method is only + available to Administrators. + + These data access records include GA4 UI Reporting, GA4 UI + Explorations, GA4 Data API, and other products like Firebase & + Admob that can retrieve data from Google Analytics through a + linkage. These records don't include property configuration + changes like adding a stream or changing a property's time zone. + For configuration change history, see + `searchChangeHistoryEvents `__. + + Returns: + Callable[[~.RunAccessReportRequest], + Awaitable[~.RunAccessReportResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "run_access_report" not in self._stubs: + self._stubs["run_access_report"] = self.grpc_channel.unary_unary( + "/google.analytics.admin.v1beta.AnalyticsAdminService/RunAccessReport", + request_serializer=analytics_admin.RunAccessReportRequest.serialize, + response_deserializer=analytics_admin.RunAccessReportResponse.deserialize, + ) + return self._stubs["run_access_report"] + def close(self): return self.grpc_channel.close() diff --git a/packages/google-analytics-admin/google/analytics/admin_v1beta/services/analytics_admin_service/transports/rest.py b/packages/google-analytics-admin/google/analytics/admin_v1beta/services/analytics_admin_service/transports/rest.py index 2009ba834171..cab3887d3f02 100644 --- a/packages/google-analytics-admin/google/analytics/admin_v1beta/services/analytics_admin_service/transports/rest.py +++ b/packages/google-analytics-admin/google/analytics/admin_v1beta/services/analytics_admin_service/transports/rest.py @@ -337,6 +337,14 @@ def post_provision_account_ticket(self, response): logging.log(f"Received response: {response}") return response + def pre_run_access_report(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_run_access_report(self, response): + logging.log(f"Received response: {response}") + return response + def pre_search_change_history_events(self, request, metadata): logging.log(f"Received request: {request}") return request, metadata @@ -1213,6 +1221,29 @@ def post_provision_account_ticket( """ return response + def pre_run_access_report( + self, + request: analytics_admin.RunAccessReportRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[analytics_admin.RunAccessReportRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for run_access_report + + Override in a subclass to manipulate the request or metadata + before they are sent to the AnalyticsAdminService server. + """ + return request, metadata + + def post_run_access_report( + self, response: analytics_admin.RunAccessReportResponse + ) -> analytics_admin.RunAccessReportResponse: + """Post-rpc interceptor for run_access_report + + Override in a subclass to manipulate the response + after it is returned by the AnalyticsAdminService server but before + it is returned to user code. + """ + return response + def pre_search_change_history_events( self, request: analytics_admin.SearchChangeHistoryEventsRequest, @@ -4935,6 +4966,100 @@ def __call__( resp = self._interceptor.post_provision_account_ticket(resp) return resp + class _RunAccessReport(AnalyticsAdminServiceRestStub): + def __hash__(self): + return hash("RunAccessReport") + + def __call__( + self, + request: analytics_admin.RunAccessReportRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> analytics_admin.RunAccessReportResponse: + r"""Call the run access report method over HTTP. + + Args: + request (~.analytics_admin.RunAccessReportRequest): + The request object. The request for a Data Access Record + Report. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.analytics_admin.RunAccessReportResponse: + The customized Data Access Record + Report response. + + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v1beta/{entity=properties/*}:runAccessReport", + "body": "*", + }, + { + "method": "post", + "uri": "/v1beta/{entity=accounts/*}:runAccessReport", + "body": "*", + }, + ] + request, metadata = self._interceptor.pre_run_access_report( + request, metadata + ) + pb_request = analytics_admin.RunAccessReportRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], + including_default_value_fields=False, + use_integers_for_enums=True, + ) + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + including_default_value_fields=False, + use_integers_for_enums=True, + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = analytics_admin.RunAccessReportResponse() + pb_resp = analytics_admin.RunAccessReportResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_run_access_report(resp) + return resp + class _SearchChangeHistoryEvents(AnalyticsAdminServiceRestStub): def __hash__(self): return hash("SearchChangeHistoryEvents") @@ -6210,6 +6335,17 @@ def provision_account_ticket( # In C++ this would require a dynamic_cast return self._ProvisionAccountTicket(self._session, self._host, self._interceptor) # type: ignore + @property + def run_access_report( + self, + ) -> Callable[ + [analytics_admin.RunAccessReportRequest], + analytics_admin.RunAccessReportResponse, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._RunAccessReport(self._session, self._host, self._interceptor) # type: ignore + @property def search_change_history_events( self, diff --git a/packages/google-analytics-admin/google/analytics/admin_v1beta/types/__init__.py b/packages/google-analytics-admin/google/analytics/admin_v1beta/types/__init__.py index 8acc1cecf2e4..87c434afaaf9 100644 --- a/packages/google-analytics-admin/google/analytics/admin_v1beta/types/__init__.py +++ b/packages/google-analytics-admin/google/analytics/admin_v1beta/types/__init__.py @@ -13,6 +13,27 @@ # See the License for the specific language governing permissions and # limitations under the License. # +from .access_report import ( + AccessBetweenFilter, + AccessDateRange, + AccessDimension, + AccessDimensionHeader, + AccessDimensionValue, + AccessFilter, + AccessFilterExpression, + AccessFilterExpressionList, + AccessInListFilter, + AccessMetric, + AccessMetricHeader, + AccessMetricValue, + AccessNumericFilter, + AccessOrderBy, + AccessQuota, + AccessQuotaStatus, + AccessRow, + AccessStringFilter, + NumericValue, +) from .analytics_admin import ( AcknowledgeUserDataCollectionRequest, AcknowledgeUserDataCollectionResponse, @@ -64,6 +85,8 @@ ListPropertiesResponse, ProvisionAccountTicketRequest, ProvisionAccountTicketResponse, + RunAccessReportRequest, + RunAccessReportResponse, SearchChangeHistoryEventsRequest, SearchChangeHistoryEventsResponse, UpdateAccountRequest, @@ -100,6 +123,25 @@ ) __all__ = ( + "AccessBetweenFilter", + "AccessDateRange", + "AccessDimension", + "AccessDimensionHeader", + "AccessDimensionValue", + "AccessFilter", + "AccessFilterExpression", + "AccessFilterExpressionList", + "AccessInListFilter", + "AccessMetric", + "AccessMetricHeader", + "AccessMetricValue", + "AccessNumericFilter", + "AccessOrderBy", + "AccessQuota", + "AccessQuotaStatus", + "AccessRow", + "AccessStringFilter", + "NumericValue", "AcknowledgeUserDataCollectionRequest", "AcknowledgeUserDataCollectionResponse", "ArchiveCustomDimensionRequest", @@ -150,6 +192,8 @@ "ListPropertiesResponse", "ProvisionAccountTicketRequest", "ProvisionAccountTicketResponse", + "RunAccessReportRequest", + "RunAccessReportResponse", "SearchChangeHistoryEventsRequest", "SearchChangeHistoryEventsResponse", "UpdateAccountRequest", diff --git a/packages/google-analytics-admin/google/analytics/admin_v1beta/types/access_report.py b/packages/google-analytics-admin/google/analytics/admin_v1beta/types/access_report.py new file mode 100644 index 000000000000..172aa9976197 --- /dev/null +++ b/packages/google-analytics-admin/google/analytics/admin_v1beta/types/access_report.py @@ -0,0 +1,705 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.analytics.admin.v1beta", + manifest={ + "AccessDimension", + "AccessMetric", + "AccessDateRange", + "AccessFilterExpression", + "AccessFilterExpressionList", + "AccessFilter", + "AccessStringFilter", + "AccessInListFilter", + "AccessNumericFilter", + "AccessBetweenFilter", + "NumericValue", + "AccessOrderBy", + "AccessDimensionHeader", + "AccessMetricHeader", + "AccessRow", + "AccessDimensionValue", + "AccessMetricValue", + "AccessQuota", + "AccessQuotaStatus", + }, +) + + +class AccessDimension(proto.Message): + r"""Dimensions are attributes of your data. For example, the dimension + ``userEmail`` indicates the email of the user that accessed + reporting data. Dimension values in report responses are strings. + + Attributes: + dimension_name (str): + The API name of the dimension. See `Data Access + Schema `__ + for the list of dimensions supported in this API. + + Dimensions are referenced by name in ``dimensionFilter`` and + ``orderBys``. + """ + + dimension_name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class AccessMetric(proto.Message): + r"""The quantitative measurements of a report. For example, the metric + ``accessCount`` is the total number of data access records. + + Attributes: + metric_name (str): + The API name of the metric. See `Data Access + Schema `__ + for the list of metrics supported in this API. + + Metrics are referenced by name in ``metricFilter`` & + ``orderBys``. + """ + + metric_name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class AccessDateRange(proto.Message): + r"""A contiguous range of days: startDate, startDate + 1, ..., + endDate. + + Attributes: + start_date (str): + The inclusive start date for the query in the format + ``YYYY-MM-DD``. Cannot be after ``endDate``. The format + ``NdaysAgo``, ``yesterday``, or ``today`` is also accepted, + and in that case, the date is inferred based on the current + time in the request's time zone. + end_date (str): + The inclusive end date for the query in the format + ``YYYY-MM-DD``. Cannot be before ``startDate``. The format + ``NdaysAgo``, ``yesterday``, or ``today`` is also accepted, + and in that case, the date is inferred based on the current + time in the request's time zone. + """ + + start_date: str = proto.Field( + proto.STRING, + number=1, + ) + end_date: str = proto.Field( + proto.STRING, + number=2, + ) + + +class AccessFilterExpression(proto.Message): + r"""Expresses dimension or metric filters. The fields in the same + expression need to be either all dimensions or all metrics. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + and_group (google.analytics.admin_v1beta.types.AccessFilterExpressionList): + Each of the FilterExpressions in the and_group has an AND + relationship. + + This field is a member of `oneof`_ ``one_expression``. + or_group (google.analytics.admin_v1beta.types.AccessFilterExpressionList): + Each of the FilterExpressions in the or_group has an OR + relationship. + + This field is a member of `oneof`_ ``one_expression``. + not_expression (google.analytics.admin_v1beta.types.AccessFilterExpression): + The FilterExpression is NOT of not_expression. + + This field is a member of `oneof`_ ``one_expression``. + access_filter (google.analytics.admin_v1beta.types.AccessFilter): + A primitive filter. In the same + FilterExpression, all of the filter's field + names need to be either all dimensions or all + metrics. + + This field is a member of `oneof`_ ``one_expression``. + """ + + and_group: "AccessFilterExpressionList" = proto.Field( + proto.MESSAGE, + number=1, + oneof="one_expression", + message="AccessFilterExpressionList", + ) + or_group: "AccessFilterExpressionList" = proto.Field( + proto.MESSAGE, + number=2, + oneof="one_expression", + message="AccessFilterExpressionList", + ) + not_expression: "AccessFilterExpression" = proto.Field( + proto.MESSAGE, + number=3, + oneof="one_expression", + message="AccessFilterExpression", + ) + access_filter: "AccessFilter" = proto.Field( + proto.MESSAGE, + number=4, + oneof="one_expression", + message="AccessFilter", + ) + + +class AccessFilterExpressionList(proto.Message): + r"""A list of filter expressions. + + Attributes: + expressions (MutableSequence[google.analytics.admin_v1beta.types.AccessFilterExpression]): + A list of filter expressions. + """ + + expressions: MutableSequence["AccessFilterExpression"] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message="AccessFilterExpression", + ) + + +class AccessFilter(proto.Message): + r"""An expression to filter dimension or metric values. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + string_filter (google.analytics.admin_v1beta.types.AccessStringFilter): + Strings related filter. + + This field is a member of `oneof`_ ``one_filter``. + in_list_filter (google.analytics.admin_v1beta.types.AccessInListFilter): + A filter for in list values. + + This field is a member of `oneof`_ ``one_filter``. + numeric_filter (google.analytics.admin_v1beta.types.AccessNumericFilter): + A filter for numeric or date values. + + This field is a member of `oneof`_ ``one_filter``. + between_filter (google.analytics.admin_v1beta.types.AccessBetweenFilter): + A filter for two values. + + This field is a member of `oneof`_ ``one_filter``. + field_name (str): + The dimension name or metric name. + """ + + string_filter: "AccessStringFilter" = proto.Field( + proto.MESSAGE, + number=2, + oneof="one_filter", + message="AccessStringFilter", + ) + in_list_filter: "AccessInListFilter" = proto.Field( + proto.MESSAGE, + number=3, + oneof="one_filter", + message="AccessInListFilter", + ) + numeric_filter: "AccessNumericFilter" = proto.Field( + proto.MESSAGE, + number=4, + oneof="one_filter", + message="AccessNumericFilter", + ) + between_filter: "AccessBetweenFilter" = proto.Field( + proto.MESSAGE, + number=5, + oneof="one_filter", + message="AccessBetweenFilter", + ) + field_name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class AccessStringFilter(proto.Message): + r"""The filter for strings. + + Attributes: + match_type (google.analytics.admin_v1beta.types.AccessStringFilter.MatchType): + The match type for this filter. + value (str): + The string value used for the matching. + case_sensitive (bool): + If true, the string value is case sensitive. + """ + + class MatchType(proto.Enum): + r"""The match type of a string filter. + + Values: + MATCH_TYPE_UNSPECIFIED (0): + Unspecified + EXACT (1): + Exact match of the string value. + BEGINS_WITH (2): + Begins with the string value. + ENDS_WITH (3): + Ends with the string value. + CONTAINS (4): + Contains the string value. + FULL_REGEXP (5): + Full match for the regular expression with + the string value. + PARTIAL_REGEXP (6): + Partial match for the regular expression with + the string value. + """ + MATCH_TYPE_UNSPECIFIED = 0 + EXACT = 1 + BEGINS_WITH = 2 + ENDS_WITH = 3 + CONTAINS = 4 + FULL_REGEXP = 5 + PARTIAL_REGEXP = 6 + + match_type: MatchType = proto.Field( + proto.ENUM, + number=1, + enum=MatchType, + ) + value: str = proto.Field( + proto.STRING, + number=2, + ) + case_sensitive: bool = proto.Field( + proto.BOOL, + number=3, + ) + + +class AccessInListFilter(proto.Message): + r"""The result needs to be in a list of string values. + + Attributes: + values (MutableSequence[str]): + The list of string values. Must be non-empty. + case_sensitive (bool): + If true, the string value is case sensitive. + """ + + values: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=1, + ) + case_sensitive: bool = proto.Field( + proto.BOOL, + number=2, + ) + + +class AccessNumericFilter(proto.Message): + r"""Filters for numeric or date values. + + Attributes: + operation (google.analytics.admin_v1beta.types.AccessNumericFilter.Operation): + The operation type for this filter. + value (google.analytics.admin_v1beta.types.NumericValue): + A numeric value or a date value. + """ + + class Operation(proto.Enum): + r"""The operation applied to a numeric filter. + + Values: + OPERATION_UNSPECIFIED (0): + Unspecified. + EQUAL (1): + Equal + LESS_THAN (2): + Less than + LESS_THAN_OR_EQUAL (3): + Less than or equal + GREATER_THAN (4): + Greater than + GREATER_THAN_OR_EQUAL (5): + Greater than or equal + """ + OPERATION_UNSPECIFIED = 0 + EQUAL = 1 + LESS_THAN = 2 + LESS_THAN_OR_EQUAL = 3 + GREATER_THAN = 4 + GREATER_THAN_OR_EQUAL = 5 + + operation: Operation = proto.Field( + proto.ENUM, + number=1, + enum=Operation, + ) + value: "NumericValue" = proto.Field( + proto.MESSAGE, + number=2, + message="NumericValue", + ) + + +class AccessBetweenFilter(proto.Message): + r"""To express that the result needs to be between two numbers + (inclusive). + + Attributes: + from_value (google.analytics.admin_v1beta.types.NumericValue): + Begins with this number. + to_value (google.analytics.admin_v1beta.types.NumericValue): + Ends with this number. + """ + + from_value: "NumericValue" = proto.Field( + proto.MESSAGE, + number=1, + message="NumericValue", + ) + to_value: "NumericValue" = proto.Field( + proto.MESSAGE, + number=2, + message="NumericValue", + ) + + +class NumericValue(proto.Message): + r"""To represent a number. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + int64_value (int): + Integer value + + This field is a member of `oneof`_ ``one_value``. + double_value (float): + Double value + + This field is a member of `oneof`_ ``one_value``. + """ + + int64_value: int = proto.Field( + proto.INT64, + number=1, + oneof="one_value", + ) + double_value: float = proto.Field( + proto.DOUBLE, + number=2, + oneof="one_value", + ) + + +class AccessOrderBy(proto.Message): + r"""Order bys define how rows will be sorted in the response. For + example, ordering rows by descending access count is one + ordering, and ordering rows by the country string is a different + ordering. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + metric (google.analytics.admin_v1beta.types.AccessOrderBy.MetricOrderBy): + Sorts results by a metric's values. + + This field is a member of `oneof`_ ``one_order_by``. + dimension (google.analytics.admin_v1beta.types.AccessOrderBy.DimensionOrderBy): + Sorts results by a dimension's values. + + This field is a member of `oneof`_ ``one_order_by``. + desc (bool): + If true, sorts by descending order. If false + or unspecified, sorts in ascending order. + """ + + class MetricOrderBy(proto.Message): + r"""Sorts by metric values. + + Attributes: + metric_name (str): + A metric name in the request to order by. + """ + + metric_name: str = proto.Field( + proto.STRING, + number=1, + ) + + class DimensionOrderBy(proto.Message): + r"""Sorts by dimension values. + + Attributes: + dimension_name (str): + A dimension name in the request to order by. + order_type (google.analytics.admin_v1beta.types.AccessOrderBy.DimensionOrderBy.OrderType): + Controls the rule for dimension value + ordering. + """ + + class OrderType(proto.Enum): + r"""Rule to order the string dimension values by. + + Values: + ORDER_TYPE_UNSPECIFIED (0): + Unspecified. + ALPHANUMERIC (1): + Alphanumeric sort by Unicode code point. For + example, "2" < "A" < "X" < "b" < "z". + CASE_INSENSITIVE_ALPHANUMERIC (2): + Case insensitive alphanumeric sort by lower + case Unicode code point. For example, "2" < "A" + < "b" < "X" < "z". + NUMERIC (3): + Dimension values are converted to numbers before sorting. + For example in NUMERIC sort, "25" < "100", and in + ``ALPHANUMERIC`` sort, "100" < "25". Non-numeric dimension + values all have equal ordering value below all numeric + values. + """ + ORDER_TYPE_UNSPECIFIED = 0 + ALPHANUMERIC = 1 + CASE_INSENSITIVE_ALPHANUMERIC = 2 + NUMERIC = 3 + + dimension_name: str = proto.Field( + proto.STRING, + number=1, + ) + order_type: "AccessOrderBy.DimensionOrderBy.OrderType" = proto.Field( + proto.ENUM, + number=2, + enum="AccessOrderBy.DimensionOrderBy.OrderType", + ) + + metric: MetricOrderBy = proto.Field( + proto.MESSAGE, + number=1, + oneof="one_order_by", + message=MetricOrderBy, + ) + dimension: DimensionOrderBy = proto.Field( + proto.MESSAGE, + number=2, + oneof="one_order_by", + message=DimensionOrderBy, + ) + desc: bool = proto.Field( + proto.BOOL, + number=3, + ) + + +class AccessDimensionHeader(proto.Message): + r"""Describes a dimension column in the report. Dimensions + requested in a report produce column entries within rows and + DimensionHeaders. However, dimensions used exclusively within + filters or expressions do not produce columns in a report; + correspondingly, those dimensions do not produce headers. + + Attributes: + dimension_name (str): + The dimension's name; for example + 'userEmail'. + """ + + dimension_name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class AccessMetricHeader(proto.Message): + r"""Describes a metric column in the report. Visible metrics + requested in a report produce column entries within rows and + MetricHeaders. However, metrics used exclusively within filters + or expressions do not produce columns in a report; + correspondingly, those metrics do not produce headers. + + Attributes: + metric_name (str): + The metric's name; for example 'accessCount'. + """ + + metric_name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class AccessRow(proto.Message): + r"""Access report data for each row. + + Attributes: + dimension_values (MutableSequence[google.analytics.admin_v1beta.types.AccessDimensionValue]): + List of dimension values. These values are in + the same order as specified in the request. + metric_values (MutableSequence[google.analytics.admin_v1beta.types.AccessMetricValue]): + List of metric values. These values are in + the same order as specified in the request. + """ + + dimension_values: MutableSequence["AccessDimensionValue"] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message="AccessDimensionValue", + ) + metric_values: MutableSequence["AccessMetricValue"] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message="AccessMetricValue", + ) + + +class AccessDimensionValue(proto.Message): + r"""The value of a dimension. + + Attributes: + value (str): + The dimension value. For example, this value + may be 'France' for the 'country' dimension. + """ + + value: str = proto.Field( + proto.STRING, + number=1, + ) + + +class AccessMetricValue(proto.Message): + r"""The value of a metric. + + Attributes: + value (str): + The measurement value. For example, this + value may be '13'. + """ + + value: str = proto.Field( + proto.STRING, + number=1, + ) + + +class AccessQuota(proto.Message): + r"""Current state of all quotas for this Analytics property. If + any quota for a property is exhausted, all requests to that + property will return Resource Exhausted errors. + + Attributes: + tokens_per_day (google.analytics.admin_v1beta.types.AccessQuotaStatus): + Properties can use 250,000 tokens per day. + Most requests consume fewer than 10 tokens. + tokens_per_hour (google.analytics.admin_v1beta.types.AccessQuotaStatus): + Properties can use 50,000 tokens per hour. An + API request consumes a single number of tokens, + and that number is deducted from all of the + hourly, daily, and per project hourly quotas. + concurrent_requests (google.analytics.admin_v1beta.types.AccessQuotaStatus): + Properties can use up to 50 concurrent + requests. + server_errors_per_project_per_hour (google.analytics.admin_v1beta.types.AccessQuotaStatus): + Properties and cloud project pairs can have + up to 50 server errors per hour. + tokens_per_project_per_hour (google.analytics.admin_v1beta.types.AccessQuotaStatus): + Properties can use up to 25% of their tokens + per project per hour. This amounts to Analytics + 360 Properties can use 12,500 tokens per project + per hour. An API request consumes a single + number of tokens, and that number is deducted + from all of the hourly, daily, and per project + hourly quotas. + """ + + tokens_per_day: "AccessQuotaStatus" = proto.Field( + proto.MESSAGE, + number=1, + message="AccessQuotaStatus", + ) + tokens_per_hour: "AccessQuotaStatus" = proto.Field( + proto.MESSAGE, + number=2, + message="AccessQuotaStatus", + ) + concurrent_requests: "AccessQuotaStatus" = proto.Field( + proto.MESSAGE, + number=3, + message="AccessQuotaStatus", + ) + server_errors_per_project_per_hour: "AccessQuotaStatus" = proto.Field( + proto.MESSAGE, + number=4, + message="AccessQuotaStatus", + ) + tokens_per_project_per_hour: "AccessQuotaStatus" = proto.Field( + proto.MESSAGE, + number=5, + message="AccessQuotaStatus", + ) + + +class AccessQuotaStatus(proto.Message): + r"""Current state for a particular quota group. + + Attributes: + consumed (int): + Quota consumed by this request. + remaining (int): + Quota remaining after this request. + """ + + consumed: int = proto.Field( + proto.INT32, + number=1, + ) + remaining: int = proto.Field( + proto.INT32, + number=2, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-analytics-admin/google/analytics/admin_v1beta/types/analytics_admin.py b/packages/google-analytics-admin/google/analytics/admin_v1beta/types/analytics_admin.py index ed53f0580511..ef723e805b01 100644 --- a/packages/google-analytics-admin/google/analytics/admin_v1beta/types/analytics_admin.py +++ b/packages/google-analytics-admin/google/analytics/admin_v1beta/types/analytics_admin.py @@ -21,11 +21,13 @@ from google.protobuf import timestamp_pb2 # type: ignore import proto # type: ignore -from google.analytics.admin_v1beta.types import resources +from google.analytics.admin_v1beta.types import access_report, resources __protobuf__ = proto.module( package="google.analytics.admin.v1beta", manifest={ + "RunAccessReportRequest", + "RunAccessReportResponse", "GetAccountRequest", "ListAccountsRequest", "ListAccountsResponse", @@ -90,6 +92,210 @@ ) +class RunAccessReportRequest(proto.Message): + r"""The request for a Data Access Record Report. + + Attributes: + entity (str): + The Data Access Report supports requesting at + the property level or account level. If + requested at the account level, Data Access + Reports include all access for all properties + under that account. + To request at the property level, entity should + be for example 'properties/123' if "123" is your + GA4 property ID. To request at the account + level, entity should be for example + 'accounts/1234' if "1234" is your GA4 Account + ID. + dimensions (MutableSequence[google.analytics.admin_v1beta.types.AccessDimension]): + The dimensions requested and displayed in the + response. Requests are allowed up to 9 + dimensions. + metrics (MutableSequence[google.analytics.admin_v1beta.types.AccessMetric]): + The metrics requested and displayed in the + response. Requests are allowed up to 10 metrics. + date_ranges (MutableSequence[google.analytics.admin_v1beta.types.AccessDateRange]): + Date ranges of access records to read. If + multiple date ranges are requested, each + response row will contain a zero based date + range index. If two date ranges overlap, the + access records for the overlapping days is + included in the response rows for both date + ranges. Requests are allowed up to 2 date + ranges. + dimension_filter (google.analytics.admin_v1beta.types.AccessFilterExpression): + Dimension filters let you restrict report response to + specific dimension values which match the filter. For + example, filtering on access records of a single user. To + learn more, see `Fundamentals of Dimension + Filters `__ + for examples. Metrics cannot be used in this filter. + metric_filter (google.analytics.admin_v1beta.types.AccessFilterExpression): + Metric filters allow you to restrict report + response to specific metric values which match + the filter. Metric filters are applied after + aggregating the report's rows, similar to SQL + having-clause. Dimensions cannot be used in this + filter. + offset (int): + The row count of the start row. The first row is counted as + row 0. If offset is unspecified, it is treated as 0. If + offset is zero, then this method will return the first page + of results with ``limit`` entries. + + To learn more about this pagination parameter, see + `Pagination `__. + limit (int): + The number of rows to return. If unspecified, 10,000 rows + are returned. The API returns a maximum of 100,000 rows per + request, no matter how many you ask for. ``limit`` must be + positive. + + The API may return fewer rows than the requested ``limit``, + if there aren't as many remaining rows as the ``limit``. For + instance, there are fewer than 300 possible values for the + dimension ``country``, so when reporting on only + ``country``, you can't get more than 300 rows, even if you + set ``limit`` to a higher value. + + To learn more about this pagination parameter, see + `Pagination `__. + time_zone (str): + This request's time zone if specified. If unspecified, the + property's time zone is used. The request's time zone is + used to interpret the start & end dates of the report. + + Formatted as strings from the IANA Time Zone database + (https://www.iana.org/time-zones); for example + "America/New_York" or "Asia/Tokyo". + order_bys (MutableSequence[google.analytics.admin_v1beta.types.AccessOrderBy]): + Specifies how rows are ordered in the + response. + return_entity_quota (bool): + Toggles whether to return the current state of this + Analytics Property's quota. Quota is returned in + `AccessQuota <#AccessQuota>`__. For account-level requests, + this field must be false. + """ + + entity: str = proto.Field( + proto.STRING, + number=1, + ) + dimensions: MutableSequence[access_report.AccessDimension] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message=access_report.AccessDimension, + ) + metrics: MutableSequence[access_report.AccessMetric] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message=access_report.AccessMetric, + ) + date_ranges: MutableSequence[access_report.AccessDateRange] = proto.RepeatedField( + proto.MESSAGE, + number=4, + message=access_report.AccessDateRange, + ) + dimension_filter: access_report.AccessFilterExpression = proto.Field( + proto.MESSAGE, + number=5, + message=access_report.AccessFilterExpression, + ) + metric_filter: access_report.AccessFilterExpression = proto.Field( + proto.MESSAGE, + number=6, + message=access_report.AccessFilterExpression, + ) + offset: int = proto.Field( + proto.INT64, + number=7, + ) + limit: int = proto.Field( + proto.INT64, + number=8, + ) + time_zone: str = proto.Field( + proto.STRING, + number=9, + ) + order_bys: MutableSequence[access_report.AccessOrderBy] = proto.RepeatedField( + proto.MESSAGE, + number=10, + message=access_report.AccessOrderBy, + ) + return_entity_quota: bool = proto.Field( + proto.BOOL, + number=11, + ) + + +class RunAccessReportResponse(proto.Message): + r"""The customized Data Access Record Report response. + + Attributes: + dimension_headers (MutableSequence[google.analytics.admin_v1beta.types.AccessDimensionHeader]): + The header for a column in the report that + corresponds to a specific dimension. The number + of DimensionHeaders and ordering of + DimensionHeaders matches the dimensions present + in rows. + metric_headers (MutableSequence[google.analytics.admin_v1beta.types.AccessMetricHeader]): + The header for a column in the report that + corresponds to a specific metric. The number of + MetricHeaders and ordering of MetricHeaders + matches the metrics present in rows. + rows (MutableSequence[google.analytics.admin_v1beta.types.AccessRow]): + Rows of dimension value combinations and + metric values in the report. + row_count (int): + The total number of rows in the query result. ``rowCount`` + is independent of the number of rows returned in the + response, the ``limit`` request parameter, and the + ``offset`` request parameter. For example if a query returns + 175 rows and includes ``limit`` of 50 in the API request, + the response will contain ``rowCount`` of 175 but only 50 + rows. + + To learn more about this pagination parameter, see + `Pagination `__. + quota (google.analytics.admin_v1beta.types.AccessQuota): + The quota state for this Analytics property + including this request. This field doesn't work + with account-level requests. + """ + + dimension_headers: MutableSequence[ + access_report.AccessDimensionHeader + ] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=access_report.AccessDimensionHeader, + ) + metric_headers: MutableSequence[ + access_report.AccessMetricHeader + ] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message=access_report.AccessMetricHeader, + ) + rows: MutableSequence[access_report.AccessRow] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message=access_report.AccessRow, + ) + row_count: int = proto.Field( + proto.INT32, + number=4, + ) + quota: access_report.AccessQuota = proto.Field( + proto.MESSAGE, + number=5, + message=access_report.AccessQuota, + ) + + class GetAccountRequest(proto.Message): r"""Request message for GetAccount RPC. @@ -196,9 +402,9 @@ class UpdateAccountRequest(proto.Message): field is used to identify the account. update_mask (google.protobuf.field_mask_pb2.FieldMask): Required. The list of fields to be updated. Field names must - be in snake case (e.g., "field_to_update"). Omitted fields - will not be updated. To replace the entire entity, use one - path with the string "*" to match all fields. + be in snake case (for example, "field_to_update"). Omitted + fields will not be updated. To replace the entire entity, + use one path with the string "*" to match all fields. """ account: resources.Account = proto.Field( @@ -222,8 +428,7 @@ class ProvisionAccountTicketRequest(proto.Message): redirect_uri (str): Redirect URI where the user will be sent after accepting Terms of Service. Must be - configured in Developers Console as a Redirect - URI + configured in Cloud Console as a Redirect URI. """ account: resources.Account = proto.Field( @@ -468,7 +673,7 @@ class ListFirebaseLinksRequest(proto.Message): A page token, received from a previous ``ListFirebaseLinks`` call. Provide this to retrieve the subsequent page. When paginating, all other parameters provided to - ``ListProperties`` must match the call that provided the + ``ListFirebaseLinks`` must match the call that provided the page token. """ diff --git a/packages/google-analytics-admin/google/analytics/admin_v1beta/types/resources.py b/packages/google-analytics-admin/google/analytics/admin_v1beta/types/resources.py index 422aa1e6077e..e550be304bbb 100644 --- a/packages/google-analytics-admin/google/analytics/admin_v1beta/types/resources.py +++ b/packages/google-analytics-admin/google/analytics/admin_v1beta/types/resources.py @@ -330,7 +330,7 @@ class Property(proto.Message): When creating a property, if the type is "PROPERTY_TYPE_UNSPECIFIED", then "ORDINARY_PROPERTY" will be implied. "SUBPROPERTY" and "ROLLUP_PROPERTY" types cannot - yet be created via Google Analytics Admin API. + yet be created with the Google Analytics Admin API. create_time (google.protobuf.timestamp_pb2.Timestamp): Output only. Time when the entity was originally created. @@ -1124,7 +1124,7 @@ class ConversionEvent(proto.Message): was created in the property. deletable (bool): Output only. If set, this event can currently - be deleted via DeleteConversionEvent. + be deleted with DeleteConversionEvent. custom (bool): Output only. If set to true, this conversion event refers to a custom event. If set to diff --git a/packages/google-analytics-admin/samples/generated_samples/analyticsadmin_v1beta_generated_analytics_admin_service_run_access_report_async.py b/packages/google-analytics-admin/samples/generated_samples/analyticsadmin_v1beta_generated_analytics_admin_service_run_access_report_async.py new file mode 100644 index 000000000000..fc6cb4703d33 --- /dev/null +++ b/packages/google-analytics-admin/samples/generated_samples/analyticsadmin_v1beta_generated_analytics_admin_service_run_access_report_async.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for RunAccessReport +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-analytics-admin + + +# [START analyticsadmin_v1beta_generated_AnalyticsAdminService_RunAccessReport_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.analytics import admin_v1beta + + +async def sample_run_access_report(): + # Create a client + client = admin_v1beta.AnalyticsAdminServiceAsyncClient() + + # Initialize request argument(s) + request = admin_v1beta.RunAccessReportRequest( + ) + + # Make the request + response = await client.run_access_report(request=request) + + # Handle the response + print(response) + +# [END analyticsadmin_v1beta_generated_AnalyticsAdminService_RunAccessReport_async] diff --git a/packages/google-analytics-admin/samples/generated_samples/analyticsadmin_v1beta_generated_analytics_admin_service_run_access_report_sync.py b/packages/google-analytics-admin/samples/generated_samples/analyticsadmin_v1beta_generated_analytics_admin_service_run_access_report_sync.py new file mode 100644 index 000000000000..afb7f56b39c0 --- /dev/null +++ b/packages/google-analytics-admin/samples/generated_samples/analyticsadmin_v1beta_generated_analytics_admin_service_run_access_report_sync.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for RunAccessReport +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-analytics-admin + + +# [START analyticsadmin_v1beta_generated_AnalyticsAdminService_RunAccessReport_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.analytics import admin_v1beta + + +def sample_run_access_report(): + # Create a client + client = admin_v1beta.AnalyticsAdminServiceClient() + + # Initialize request argument(s) + request = admin_v1beta.RunAccessReportRequest( + ) + + # Make the request + response = client.run_access_report(request=request) + + # Handle the response + print(response) + +# [END analyticsadmin_v1beta_generated_AnalyticsAdminService_RunAccessReport_sync] diff --git a/packages/google-analytics-admin/samples/generated_samples/snippet_metadata_google.analytics.admin.v1beta.json b/packages/google-analytics-admin/samples/generated_samples/snippet_metadata_google.analytics.admin.v1beta.json index c07437ac7ac9..89e737a352b9 100644 --- a/packages/google-analytics-admin/samples/generated_samples/snippet_metadata_google.analytics.admin.v1beta.json +++ b/packages/google-analytics-admin/samples/generated_samples/snippet_metadata_google.analytics.admin.v1beta.json @@ -6097,6 +6097,159 @@ ], "title": "analyticsadmin_v1beta_generated_analytics_admin_service_provision_account_ticket_sync.py" }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.analytics.admin_v1beta.AnalyticsAdminServiceAsyncClient", + "shortName": "AnalyticsAdminServiceAsyncClient" + }, + "fullName": "google.analytics.admin_v1beta.AnalyticsAdminServiceAsyncClient.run_access_report", + "method": { + "fullName": "google.analytics.admin.v1beta.AnalyticsAdminService.RunAccessReport", + "service": { + "fullName": "google.analytics.admin.v1beta.AnalyticsAdminService", + "shortName": "AnalyticsAdminService" + }, + "shortName": "RunAccessReport" + }, + "parameters": [ + { + "name": "request", + "type": "google.analytics.admin_v1beta.types.RunAccessReportRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.analytics.admin_v1beta.types.RunAccessReportResponse", + "shortName": "run_access_report" + }, + "description": "Sample for RunAccessReport", + "file": "analyticsadmin_v1beta_generated_analytics_admin_service_run_access_report_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "analyticsadmin_v1beta_generated_AnalyticsAdminService_RunAccessReport_async", + "segments": [ + { + "end": 50, + "start": 27, + "type": "FULL" + }, + { + "end": 50, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 44, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 47, + "start": 45, + "type": "REQUEST_EXECUTION" + }, + { + "end": 51, + "start": 48, + "type": "RESPONSE_HANDLING" + } + ], + "title": "analyticsadmin_v1beta_generated_analytics_admin_service_run_access_report_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.analytics.admin_v1beta.AnalyticsAdminServiceClient", + "shortName": "AnalyticsAdminServiceClient" + }, + "fullName": "google.analytics.admin_v1beta.AnalyticsAdminServiceClient.run_access_report", + "method": { + "fullName": "google.analytics.admin.v1beta.AnalyticsAdminService.RunAccessReport", + "service": { + "fullName": "google.analytics.admin.v1beta.AnalyticsAdminService", + "shortName": "AnalyticsAdminService" + }, + "shortName": "RunAccessReport" + }, + "parameters": [ + { + "name": "request", + "type": "google.analytics.admin_v1beta.types.RunAccessReportRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.analytics.admin_v1beta.types.RunAccessReportResponse", + "shortName": "run_access_report" + }, + "description": "Sample for RunAccessReport", + "file": "analyticsadmin_v1beta_generated_analytics_admin_service_run_access_report_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "analyticsadmin_v1beta_generated_AnalyticsAdminService_RunAccessReport_sync", + "segments": [ + { + "end": 50, + "start": 27, + "type": "FULL" + }, + { + "end": 50, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 44, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 47, + "start": 45, + "type": "REQUEST_EXECUTION" + }, + { + "end": 51, + "start": 48, + "type": "RESPONSE_HANDLING" + } + ], + "title": "analyticsadmin_v1beta_generated_analytics_admin_service_run_access_report_sync.py" + }, { "canonical": true, "clientMethod": { diff --git a/packages/google-analytics-admin/scripts/fixup_admin_v1beta_keywords.py b/packages/google-analytics-admin/scripts/fixup_admin_v1beta_keywords.py index a04abf6a7265..eca0cf04bd80 100644 --- a/packages/google-analytics-admin/scripts/fixup_admin_v1beta_keywords.py +++ b/packages/google-analytics-admin/scripts/fixup_admin_v1beta_keywords.py @@ -77,6 +77,7 @@ class adminCallTransformer(cst.CSTTransformer): 'list_measurement_protocol_secrets': ('parent', 'page_size', 'page_token', ), 'list_properties': ('filter', 'page_size', 'page_token', 'show_deleted', ), 'provision_account_ticket': ('account', 'redirect_uri', ), + 'run_access_report': ('entity', 'dimensions', 'metrics', 'date_ranges', 'dimension_filter', 'metric_filter', 'offset', 'limit', 'time_zone', 'order_bys', 'return_entity_quota', ), 'search_change_history_events': ('account', 'property', 'resource_type', 'action', 'actor_email', 'earliest_change_time', 'latest_change_time', 'page_size', 'page_token', ), 'update_account': ('account', 'update_mask', ), 'update_custom_dimension': ('update_mask', 'custom_dimension', ), diff --git a/packages/google-analytics-admin/tests/unit/gapic/admin_v1beta/test_analytics_admin_service.py b/packages/google-analytics-admin/tests/unit/gapic/admin_v1beta/test_analytics_admin_service.py index d39611ea71c9..026d37433522 100644 --- a/packages/google-analytics-admin/tests/unit/gapic/admin_v1beta/test_analytics_admin_service.py +++ b/packages/google-analytics-admin/tests/unit/gapic/admin_v1beta/test_analytics_admin_service.py @@ -51,7 +51,11 @@ pagers, transports, ) -from google.analytics.admin_v1beta.types import analytics_admin, resources +from google.analytics.admin_v1beta.types import ( + access_report, + analytics_admin, + resources, +) def client_cert_source_callback(): @@ -14078,6 +14082,166 @@ async def test_get_data_stream_flattened_error_async(): ) +@pytest.mark.parametrize( + "request_type", + [ + analytics_admin.RunAccessReportRequest, + dict, + ], +) +def test_run_access_report(request_type, transport: str = "grpc"): + client = AnalyticsAdminServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.run_access_report), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = analytics_admin.RunAccessReportResponse( + row_count=992, + ) + response = client.run_access_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_admin.RunAccessReportRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, analytics_admin.RunAccessReportResponse) + assert response.row_count == 992 + + +def test_run_access_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 = AnalyticsAdminServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.run_access_report), "__call__" + ) as call: + client.run_access_report() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == analytics_admin.RunAccessReportRequest() + + +@pytest.mark.asyncio +async def test_run_access_report_async( + transport: str = "grpc_asyncio", request_type=analytics_admin.RunAccessReportRequest +): + client = AnalyticsAdminServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.run_access_report), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + analytics_admin.RunAccessReportResponse( + row_count=992, + ) + ) + response = await client.run_access_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_admin.RunAccessReportRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, analytics_admin.RunAccessReportResponse) + assert response.row_count == 992 + + +@pytest.mark.asyncio +async def test_run_access_report_async_from_dict(): + await test_run_access_report_async(request_type=dict) + + +def test_run_access_report_field_headers(): + client = AnalyticsAdminServiceClient( + 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_admin.RunAccessReportRequest() + + request.entity = "entity_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.run_access_report), "__call__" + ) as call: + call.return_value = analytics_admin.RunAccessReportResponse() + client.run_access_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] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "entity=entity_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_run_access_report_field_headers_async(): + client = AnalyticsAdminServiceAsyncClient( + 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_admin.RunAccessReportRequest() + + request.entity = "entity_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.run_access_report), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + analytics_admin.RunAccessReportResponse() + ) + await client.run_access_report(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "entity=entity_value", + ) in kw["metadata"] + + @pytest.mark.parametrize( "request_type", [ @@ -27495,6 +27659,132 @@ def test_get_data_stream_rest_error(): ) +@pytest.mark.parametrize( + "request_type", + [ + analytics_admin.RunAccessReportRequest, + dict, + ], +) +def test_run_access_report_rest(request_type): + client = AnalyticsAdminServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {"entity": "properties/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = analytics_admin.RunAccessReportResponse( + row_count=992, + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = analytics_admin.RunAccessReportResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.run_access_report(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, analytics_admin.RunAccessReportResponse) + assert response.row_count == 992 + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_run_access_report_rest_interceptors(null_interceptor): + transport = transports.AnalyticsAdminServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.AnalyticsAdminServiceRestInterceptor(), + ) + client = AnalyticsAdminServiceClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.AnalyticsAdminServiceRestInterceptor, "post_run_access_report" + ) as post, mock.patch.object( + transports.AnalyticsAdminServiceRestInterceptor, "pre_run_access_report" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = analytics_admin.RunAccessReportRequest.pb( + analytics_admin.RunAccessReportRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = analytics_admin.RunAccessReportResponse.to_json( + analytics_admin.RunAccessReportResponse() + ) + + request = analytics_admin.RunAccessReportRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = analytics_admin.RunAccessReportResponse() + + client.run_access_report( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_run_access_report_rest_bad_request( + transport: str = "rest", request_type=analytics_admin.RunAccessReportRequest +): + client = AnalyticsAdminServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {"entity": "properties/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.run_access_report(request) + + +def test_run_access_report_rest_error(): + client = AnalyticsAdminServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + def test_credentials_transport_error(): # It is an error to provide credentials and a transport instance. transport = transports.AnalyticsAdminServiceGrpcTransport( @@ -27681,6 +27971,7 @@ def test_analytics_admin_service_base_transport(): "update_data_stream", "list_data_streams", "get_data_stream", + "run_access_report", ) for method in methods: with pytest.raises(NotImplementedError): @@ -28096,6 +28387,9 @@ def test_analytics_admin_service_client_transport_session_collision(transport_na session1 = client1.transport.get_data_stream._session session2 = client2.transport.get_data_stream._session assert session1 != session2 + session1 = client1.transport.run_access_report._session + session2 = client2.transport.run_access_report._session + assert session1 != session2 def test_analytics_admin_service_grpc_transport_channel():