- On January 1, 2020 this library will no longer support Python 2 on the latest released version. - Previously released library versions will continue to be available. For more information please + As of January 1, 2020 this library no longer supports Python 2 on the latest released version. + Library versions released prior to that date will continue to be available. For more information please visit Python 2 support on Google Cloud.
{% block body %} {% endblock %} diff --git a/docs/conf.py b/docs/conf.py index be56ae55..755f4854 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -20,6 +20,10 @@ # documentation root, use os.path.abspath to make it absolute, like shown here. sys.path.insert(0, os.path.abspath("..")) +# For plugins that can not read conf.py. +# See also: https://github.com/docascode/sphinx-docfx-yaml/issues/85 +sys.path.insert(0, os.path.abspath(".")) + __version__ = "" # -- General configuration ------------------------------------------------ @@ -38,21 +42,18 @@ "sphinx.ext.napoleon", "sphinx.ext.todo", "sphinx.ext.viewcode", + "recommonmark", ] # autodoc/autosummary flags autoclass_content = "both" -autodoc_default_flags = ["members"] +autodoc_default_options = {"members": True} autosummary_generate = True # Add any paths that contain templates here, relative to this directory. templates_path = ["_templates"] -# Allow markdown includes (so releases.md can include CHANGLEOG.md) -# http://www.sphinx-doc.org/en/master/markdown.html -source_parsers = {".md": "recommonmark.parser.CommonMarkParser"} - # The suffix(es) of source filenames. # You can specify multiple suffix as a list of string: # source_suffix = ['.rst', '.md'] @@ -93,7 +94,12 @@ # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. -exclude_patterns = ["_build"] +exclude_patterns = [ + "_build", + "samples/AUTHORING_GUIDE.md", + "samples/CONTRIBUTING.md", + "samples/snippets/README.rst", +] # The reST default role (used for this markup: `text`) to use for all # documents. @@ -340,7 +346,7 @@ intersphinx_mapping = { "python": ("http://python.readthedocs.org/en/latest/", None), "google-auth": ("https://google-auth.readthedocs.io/en/stable", None), - "google.api_core": ("https://googleapis.dev/python/google-api-core/latest/", None), + "google.api_core": ("https://googleapis.dev/python/google-api-core/latest/", None,), "grpc": ("https://grpc.io/grpc/python/", None), } diff --git a/docs/errorreporting_v1beta1/services.rst b/docs/errorreporting_v1beta1/services.rst new file mode 100644 index 00000000..a5ec3b92 --- /dev/null +++ b/docs/errorreporting_v1beta1/services.rst @@ -0,0 +1,12 @@ +Services for Google Cloud Errorreporting v1beta1 API +==================================================== + +.. automodule:: google.cloud.errorreporting_v1beta1.services.error_group_service + :members: + :inherited-members: +.. automodule:: google.cloud.errorreporting_v1beta1.services.error_stats_service + :members: + :inherited-members: +.. automodule:: google.cloud.errorreporting_v1beta1.services.report_errors_service + :members: + :inherited-members: diff --git a/docs/errorreporting_v1beta1/types.rst b/docs/errorreporting_v1beta1/types.rst new file mode 100644 index 00000000..9a74e347 --- /dev/null +++ b/docs/errorreporting_v1beta1/types.rst @@ -0,0 +1,5 @@ +Types for Google Cloud Errorreporting v1beta1 API +================================================= + +.. automodule:: google.cloud.errorreporting_v1beta1.types + :members: diff --git a/docs/gapic/v1beta1/api.rst b/docs/gapic/v1beta1/api.rst deleted file mode 100644 index 37ead7d3..00000000 --- a/docs/gapic/v1beta1/api.rst +++ /dev/null @@ -1,6 +0,0 @@ -Client for Stackdriver Error Reporting API -========================================== - -.. automodule:: google.cloud.errorreporting_v1beta1 - :members: - :inherited-members: \ No newline at end of file diff --git a/docs/gapic/v1beta1/types.rst b/docs/gapic/v1beta1/types.rst deleted file mode 100644 index 989f48a7..00000000 --- a/docs/gapic/v1beta1/types.rst +++ /dev/null @@ -1,5 +0,0 @@ -Types for Stackdriver Error Reporting API Client -================================================ - -.. automodule:: google.cloud.errorreporting_v1beta1.types - :members: \ No newline at end of file diff --git a/docs/index.rst b/docs/index.rst index 3fd35c32..949b1c9d 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,5 +1,7 @@ .. include:: README.rst +.. include:: multiprocessing.rst + Usage Documentation ------------------- @@ -17,8 +19,8 @@ API Reference client util - gapic/v1beta1/api - gapic/v1beta1/types + errorreporting_v1beta1/services + errorreporting_v1beta1/types Changelog diff --git a/docs/multiprocessing.rst b/docs/multiprocessing.rst new file mode 100644 index 00000000..1cb29d4c --- /dev/null +++ b/docs/multiprocessing.rst @@ -0,0 +1,7 @@ +.. note:: + + Because this client uses :mod:`grpcio` library, it is safe to + share instances across threads. In multiprocessing scenarios, the best + practice is to create client instances *after* the invocation of + :func:`os.fork` by :class:`multiprocessing.Pool` or + :class:`multiprocessing.Process`. diff --git a/google/cloud/error_reporting/_gapic.py b/google/cloud/error_reporting/_gapic.py index 0c6ec9e6..9c7f95c8 100644 --- a/google/cloud/error_reporting/_gapic.py +++ b/google/cloud/error_reporting/_gapic.py @@ -13,10 +13,9 @@ # limitations under the License. """GAX wrapper for Error Reporting API requests.""" +import json -from google.cloud.errorreporting_v1beta1.gapic import report_errors_service_client -from google.cloud.errorreporting_v1beta1.proto import report_errors_service_pb2 -from google.protobuf.json_format import ParseDict +import google.cloud.errorreporting_v1beta1 def make_report_error_api(client): @@ -28,7 +27,7 @@ def make_report_error_api(client): :rtype: :class:_ErrorReportingGapicApi :returns: An Error Reporting API instance. """ - gapic_api = report_errors_service_client.ReportErrorsServiceClient( + gapic_api = google.cloud.errorreporting_v1beta1.ReportErrorsServiceClient( credentials=client._credentials, client_info=client._client_info, client_options=client._client_options, @@ -40,7 +39,7 @@ class _ErrorReportingGapicApi(object): """Helper mapping Error Reporting-related APIs :type gapic: - :class:`report_errors_service_client.ReportErrorsServiceClient` + :class:`google.cloud.errorreporting_v1beta1.ReportErrorsServiceClient` :param gapic: API object used to make RPCs. :type project: str @@ -62,7 +61,15 @@ def report_error_event(self, error_report): Use :meth:~`google.cloud.error_reporting.client._build_error_report` """ - project_name = self._gapic_api.project_path(self._project) - error_report_payload = report_errors_service_pb2.ReportedErrorEvent() - ParseDict(error_report, error_report_payload) - self._gapic_api.report_error_event(project_name, error_report_payload) + project_name = f"projects/{self._project}" + + # Since error_report uses camel case for key names (like serviceContext), + # but ReportedErrorEvent uses snake case for key names (like service_context), + # we need to route throught json. + error_report_payload = google.cloud.errorreporting_v1beta1.ReportedErrorEvent.from_json( + json.dumps(error_report) + ) + + self._gapic_api.report_error_event( + project_name=project_name, event=error_report_payload + ) diff --git a/google/cloud/errorreporting_v1beta1/__init__.py b/google/cloud/errorreporting_v1beta1/__init__.py index 9553e4a4..43fc283f 100644 --- a/google/cloud/errorreporting_v1beta1/__init__.py +++ b/google/cloud/errorreporting_v1beta1/__init__.py @@ -1,45 +1,75 @@ -# Copyright 2018 Google LLC +# -*- 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 # -# https://www.apache.org/licenses/LICENSE-2.0 +# 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 absolute_import - -from google.cloud.errorreporting_v1beta1 import types -from google.cloud.errorreporting_v1beta1.gapic import enums -from google.cloud.errorreporting_v1beta1.gapic import error_group_service_client -from google.cloud.errorreporting_v1beta1.gapic import error_stats_service_client -from google.cloud.errorreporting_v1beta1.gapic import report_errors_service_client - - -class ErrorGroupServiceClient(error_group_service_client.ErrorGroupServiceClient): - __doc__ = error_group_service_client.ErrorGroupServiceClient.__doc__ - enums = enums - - -class ErrorStatsServiceClient(error_stats_service_client.ErrorStatsServiceClient): - __doc__ = error_stats_service_client.ErrorStatsServiceClient.__doc__ - enums = enums - - -class ReportErrorsServiceClient(report_errors_service_client.ReportErrorsServiceClient): - __doc__ = report_errors_service_client.ReportErrorsServiceClient.__doc__ - enums = enums +from .services.error_group_service import ErrorGroupServiceClient +from .services.error_stats_service import ErrorStatsServiceClient +from .services.report_errors_service import ReportErrorsServiceClient +from .types.common import ErrorContext +from .types.common import ErrorEvent +from .types.common import ErrorGroup +from .types.common import HttpRequestContext +from .types.common import ServiceContext +from .types.common import SourceLocation +from .types.common import TrackingIssue +from .types.error_group_service import GetGroupRequest +from .types.error_group_service import UpdateGroupRequest +from .types.error_stats_service import DeleteEventsRequest +from .types.error_stats_service import DeleteEventsResponse +from .types.error_stats_service import ErrorGroupOrder +from .types.error_stats_service import ErrorGroupStats +from .types.error_stats_service import ListEventsRequest +from .types.error_stats_service import ListEventsResponse +from .types.error_stats_service import ListGroupStatsRequest +from .types.error_stats_service import ListGroupStatsResponse +from .types.error_stats_service import QueryTimeRange +from .types.error_stats_service import ServiceContextFilter +from .types.error_stats_service import TimedCount +from .types.error_stats_service import TimedCountAlignment +from .types.report_errors_service import ReportErrorEventRequest +from .types.report_errors_service import ReportErrorEventResponse +from .types.report_errors_service import ReportedErrorEvent __all__ = ( - "enums", - "types", + "DeleteEventsRequest", + "DeleteEventsResponse", + "ErrorContext", + "ErrorEvent", + "ErrorGroup", + "ErrorGroupOrder", "ErrorGroupServiceClient", + "ErrorGroupStats", "ErrorStatsServiceClient", + "GetGroupRequest", + "HttpRequestContext", + "ListEventsRequest", + "ListEventsResponse", + "ListGroupStatsRequest", + "ListGroupStatsResponse", + "QueryTimeRange", + "ReportErrorEventRequest", + "ReportErrorEventResponse", + "ReportedErrorEvent", + "ServiceContext", + "ServiceContextFilter", + "SourceLocation", + "TimedCount", + "TimedCountAlignment", + "TrackingIssue", + "UpdateGroupRequest", "ReportErrorsServiceClient", ) diff --git a/google/cloud/errorreporting_v1beta1/gapic/__init__.py b/google/cloud/errorreporting_v1beta1/gapic/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/google/cloud/errorreporting_v1beta1/gapic/enums.py b/google/cloud/errorreporting_v1beta1/gapic/enums.py deleted file mode 100644 index 890ea7e7..00000000 --- a/google/cloud/errorreporting_v1beta1/gapic/enums.py +++ /dev/null @@ -1,89 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright 2019 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 -# -# https://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. - -"""Wrappers for protocol buffer enum types.""" - -import enum - - -class ErrorGroupOrder(enum.IntEnum): - """ - A sorting order of error groups. - - Attributes: - GROUP_ORDER_UNSPECIFIED (int): No group order specified. - COUNT_DESC (int): Total count of errors in the given time window in descending order. - LAST_SEEN_DESC (int): Timestamp when the group was last seen in the given time window - in descending order. - CREATED_DESC (int): Timestamp when the group was created in descending order. - AFFECTED_USERS_DESC (int): Number of affected users in the given time window in descending order. - """ - - GROUP_ORDER_UNSPECIFIED = 0 - COUNT_DESC = 1 - LAST_SEEN_DESC = 2 - CREATED_DESC = 3 - AFFECTED_USERS_DESC = 4 - - -class TimedCountAlignment(enum.IntEnum): - """ - Specifies how the time periods of error group counts are aligned. - - Attributes: - ERROR_COUNT_ALIGNMENT_UNSPECIFIED (int): No alignment specified. - ALIGNMENT_EQUAL_ROUNDED (int): The time periods shall be consecutive, have width equal to the requested - duration, and be aligned at the ``alignment_time`` provided in the - request. The ``alignment_time`` does not have to be inside the query - period but even if it is outside, only time periods are returned which - overlap with the query period. A rounded alignment will typically result - in a different size of the first or the last time period. - ALIGNMENT_EQUAL_AT_END (int): The time periods shall be consecutive, have width equal to the - requested duration, and be aligned at the end of the requested time - period. This can result in a different size of the - first time period. - """ - - ERROR_COUNT_ALIGNMENT_UNSPECIFIED = 0 - ALIGNMENT_EQUAL_ROUNDED = 1 - ALIGNMENT_EQUAL_AT_END = 2 - - -class QueryTimeRange(object): - class Period(enum.IntEnum): - """ - The supported time ranges. - - Attributes: - PERIOD_UNSPECIFIED (int): Do not use. - PERIOD_1_HOUR (int): Retrieve data for the last hour. - Recommended minimum timed count duration: 1 min. - PERIOD_6_HOURS (int): Retrieve data for the last 6 hours. - Recommended minimum timed count duration: 10 min. - PERIOD_1_DAY (int): Retrieve data for the last day. - Recommended minimum timed count duration: 1 hour. - PERIOD_1_WEEK (int): Retrieve data for the last week. - Recommended minimum timed count duration: 6 hours. - PERIOD_30_DAYS (int): Retrieve data for the last 30 days. - Recommended minimum timed count duration: 1 day. - """ - - PERIOD_UNSPECIFIED = 0 - PERIOD_1_HOUR = 1 - PERIOD_6_HOURS = 2 - PERIOD_1_DAY = 3 - PERIOD_1_WEEK = 4 - PERIOD_30_DAYS = 5 diff --git a/google/cloud/errorreporting_v1beta1/gapic/error_group_service_client.py b/google/cloud/errorreporting_v1beta1/gapic/error_group_service_client.py deleted file mode 100644 index af60931f..00000000 --- a/google/cloud/errorreporting_v1beta1/gapic/error_group_service_client.py +++ /dev/null @@ -1,342 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright 2019 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 -# -# https://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. - -"""Accesses the google.devtools.clouderrorreporting.v1beta1 ErrorGroupService API.""" - -import pkg_resources -import warnings - -from google.oauth2 import service_account -import google.api_core.client_options -import google.api_core.gapic_v1.client_info -import google.api_core.gapic_v1.config -import google.api_core.gapic_v1.method -import google.api_core.gapic_v1.routing_header -import google.api_core.grpc_helpers -import google.api_core.path_template -import grpc - -from google.cloud.errorreporting_v1beta1.gapic import enums -from google.cloud.errorreporting_v1beta1.gapic import error_group_service_client_config -from google.cloud.errorreporting_v1beta1.gapic.transports import ( - error_group_service_grpc_transport, -) -from google.cloud.errorreporting_v1beta1.proto import common_pb2 -from google.cloud.errorreporting_v1beta1.proto import error_group_service_pb2 -from google.cloud.errorreporting_v1beta1.proto import error_group_service_pb2_grpc - - -_GAPIC_LIBRARY_VERSION = pkg_resources.get_distribution( - "google-cloud-error-reporting" -).version - - -class ErrorGroupServiceClient(object): - """Service for retrieving and updating individual error groups.""" - - SERVICE_ADDRESS = "clouderrorreporting.googleapis.com:443" - """The default address of the service.""" - - # The name of the interface for this client. This is the key used to - # find the method configuration in the client_config dictionary. - _INTERFACE_NAME = "google.devtools.clouderrorreporting.v1beta1.ErrorGroupService" - - @classmethod - def from_service_account_file(cls, filename, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - ErrorGroupServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file(filename) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @classmethod - def group_path(cls, project, group): - """Return a fully-qualified group string.""" - return google.api_core.path_template.expand( - "projects/{project}/groups/{group}", project=project, group=group - ) - - def __init__( - self, - transport=None, - channel=None, - credentials=None, - client_config=None, - client_info=None, - client_options=None, - ): - """Constructor. - - Args: - transport (Union[~.ErrorGroupServiceGrpcTransport, - Callable[[~.Credentials, type], ~.ErrorGroupServiceGrpcTransport]): A transport - instance, responsible for actually making the API calls. - The default transport uses the gRPC protocol. - This argument may also be a callable which returns a - transport instance. Callables will be sent the credentials - as the first argument and the default transport class as - the second argument. - channel (grpc.Channel): DEPRECATED. A ``Channel`` instance - through which to make calls. This argument is mutually exclusive - with ``credentials``; providing both will raise an exception. - credentials (google.auth.credentials.Credentials): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is mutually exclusive with providing a - transport instance to ``transport``; doing so will raise - an exception. - client_config (dict): DEPRECATED. A dictionary of call options for - each method. If not specified, the default configuration is used. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - client_options (Union[dict, google.api_core.client_options.ClientOptions]): - Client options used to set user options on the client. API Endpoint - should be set through client_options. - """ - # Raise deprecation warnings for things we want to go away. - if client_config is not None: - warnings.warn( - "The `client_config` argument is deprecated.", - PendingDeprecationWarning, - stacklevel=2, - ) - else: - client_config = error_group_service_client_config.config - - if channel: - warnings.warn( - "The `channel` argument is deprecated; use " "`transport` instead.", - PendingDeprecationWarning, - stacklevel=2, - ) - - api_endpoint = self.SERVICE_ADDRESS - if client_options: - if type(client_options) == dict: - client_options = google.api_core.client_options.from_dict( - client_options - ) - if client_options.api_endpoint: - api_endpoint = client_options.api_endpoint - - # Instantiate the transport. - # The transport is responsible for handling serialization and - # deserialization and actually sending data to the service. - if transport: - if callable(transport): - self.transport = transport( - credentials=credentials, - default_class=error_group_service_grpc_transport.ErrorGroupServiceGrpcTransport, - address=api_endpoint, - ) - else: - if credentials: - raise ValueError( - "Received both a transport instance and " - "credentials; these are mutually exclusive." - ) - self.transport = transport - else: - self.transport = error_group_service_grpc_transport.ErrorGroupServiceGrpcTransport( - address=api_endpoint, channel=channel, credentials=credentials - ) - - if client_info is None: - client_info = google.api_core.gapic_v1.client_info.ClientInfo( - gapic_version=_GAPIC_LIBRARY_VERSION - ) - else: - client_info.gapic_version = _GAPIC_LIBRARY_VERSION - self._client_info = client_info - - # Parse out the default settings for retry and timeout for each RPC - # from the client configuration. - # (Ordinarily, these are the defaults specified in the `*_config.py` - # file next to this one.) - self._method_configs = google.api_core.gapic_v1.config.parse_method_configs( - client_config["interfaces"][self._INTERFACE_NAME] - ) - - # Save a dictionary of cached API call functions. - # These are the actual callables which invoke the proper - # transport methods, wrapped with `wrap_method` to add retry, - # timeout, and the like. - self._inner_api_calls = {} - - # Service calls - def get_group( - self, - group_name, - retry=google.api_core.gapic_v1.method.DEFAULT, - timeout=google.api_core.gapic_v1.method.DEFAULT, - metadata=None, - ): - """ - Get the specified group. - - Example: - >>> from google.cloud import errorreporting_v1beta1 - >>> - >>> client = errorreporting_v1beta1.ErrorGroupServiceClient() - >>> - >>> group_name = client.group_path('[PROJECT]', '[GROUP]') - >>> - >>> response = client.get_group(group_name) - - Args: - group_name (str): [Required] The group resource name. Written as - projects/projectID/groups/group\_name. Call groupStats.list to return a - list of groups belonging to this project. - - Example: projects/my-project-123/groups/my-group - retry (Optional[google.api_core.retry.Retry]): A retry object used - to retry requests. If ``None`` is specified, requests will - be retried using a default configuration. - timeout (Optional[float]): The amount of time, in seconds, to wait - for the request to complete. Note that if ``retry`` is - specified, the timeout applies to each individual attempt. - metadata (Optional[Sequence[Tuple[str, str]]]): Additional metadata - that is provided to the method. - - Returns: - A :class:`~google.cloud.errorreporting_v1beta1.types.ErrorGroup` instance. - - Raises: - google.api_core.exceptions.GoogleAPICallError: If the request - failed for any reason. - google.api_core.exceptions.RetryError: If the request failed due - to a retryable error and retry attempts failed. - ValueError: If the parameters are invalid. - """ - # Wrap the transport method to add retry and timeout logic. - if "get_group" not in self._inner_api_calls: - self._inner_api_calls[ - "get_group" - ] = google.api_core.gapic_v1.method.wrap_method( - self.transport.get_group, - default_retry=self._method_configs["GetGroup"].retry, - default_timeout=self._method_configs["GetGroup"].timeout, - client_info=self._client_info, - ) - - request = error_group_service_pb2.GetGroupRequest(group_name=group_name) - if metadata is None: - metadata = [] - metadata = list(metadata) - try: - routing_header = [("group_name", group_name)] - except AttributeError: - pass - else: - routing_metadata = google.api_core.gapic_v1.routing_header.to_grpc_metadata( - routing_header - ) - metadata.append(routing_metadata) - - return self._inner_api_calls["get_group"]( - request, retry=retry, timeout=timeout, metadata=metadata - ) - - def update_group( - self, - group, - retry=google.api_core.gapic_v1.method.DEFAULT, - timeout=google.api_core.gapic_v1.method.DEFAULT, - metadata=None, - ): - """ - Replace the data for the specified group. - Fails if the group does not exist. - - Example: - >>> from google.cloud import errorreporting_v1beta1 - >>> - >>> client = errorreporting_v1beta1.ErrorGroupServiceClient() - >>> - >>> # TODO: Initialize `group`: - >>> group = {} - >>> - >>> response = client.update_group(group) - - Args: - group (Union[dict, ~google.cloud.errorreporting_v1beta1.types.ErrorGroup]): [Required] The group which replaces the resource on the server. - - If a dict is provided, it must be of the same form as the protobuf - message :class:`~google.cloud.errorreporting_v1beta1.types.ErrorGroup` - retry (Optional[google.api_core.retry.Retry]): A retry object used - to retry requests. If ``None`` is specified, requests will - be retried using a default configuration. - timeout (Optional[float]): The amount of time, in seconds, to wait - for the request to complete. Note that if ``retry`` is - specified, the timeout applies to each individual attempt. - metadata (Optional[Sequence[Tuple[str, str]]]): Additional metadata - that is provided to the method. - - Returns: - A :class:`~google.cloud.errorreporting_v1beta1.types.ErrorGroup` instance. - - Raises: - google.api_core.exceptions.GoogleAPICallError: If the request - failed for any reason. - google.api_core.exceptions.RetryError: If the request failed due - to a retryable error and retry attempts failed. - ValueError: If the parameters are invalid. - """ - # Wrap the transport method to add retry and timeout logic. - if "update_group" not in self._inner_api_calls: - self._inner_api_calls[ - "update_group" - ] = google.api_core.gapic_v1.method.wrap_method( - self.transport.update_group, - default_retry=self._method_configs["UpdateGroup"].retry, - default_timeout=self._method_configs["UpdateGroup"].timeout, - client_info=self._client_info, - ) - - request = error_group_service_pb2.UpdateGroupRequest(group=group) - if metadata is None: - metadata = [] - metadata = list(metadata) - try: - routing_header = [("group.name", group.name)] - except AttributeError: - pass - else: - routing_metadata = google.api_core.gapic_v1.routing_header.to_grpc_metadata( - routing_header - ) - metadata.append(routing_metadata) - - return self._inner_api_calls["update_group"]( - request, retry=retry, timeout=timeout, metadata=metadata - ) diff --git a/google/cloud/errorreporting_v1beta1/gapic/error_group_service_client_config.py b/google/cloud/errorreporting_v1beta1/gapic/error_group_service_client_config.py deleted file mode 100644 index e70ec324..00000000 --- a/google/cloud/errorreporting_v1beta1/gapic/error_group_service_client_config.py +++ /dev/null @@ -1,33 +0,0 @@ -config = { - "interfaces": { - "google.devtools.clouderrorreporting.v1beta1.ErrorGroupService": { - "retry_codes": { - "idempotent": ["DEADLINE_EXCEEDED", "UNAVAILABLE"], - "non_idempotent": [], - }, - "retry_params": { - "default": { - "initial_retry_delay_millis": 100, - "retry_delay_multiplier": 1.3, - "max_retry_delay_millis": 60000, - "initial_rpc_timeout_millis": 20000, - "rpc_timeout_multiplier": 1.0, - "max_rpc_timeout_millis": 20000, - "total_timeout_millis": 600000, - } - }, - "methods": { - "GetGroup": { - "timeout_millis": 60000, - "retry_codes_name": "idempotent", - "retry_params_name": "default", - }, - "UpdateGroup": { - "timeout_millis": 60000, - "retry_codes_name": "idempotent", - "retry_params_name": "default", - }, - }, - } - } -} diff --git a/google/cloud/errorreporting_v1beta1/gapic/error_stats_service_client.py b/google/cloud/errorreporting_v1beta1/gapic/error_stats_service_client.py deleted file mode 100644 index 692f0329..00000000 --- a/google/cloud/errorreporting_v1beta1/gapic/error_stats_service_client.py +++ /dev/null @@ -1,559 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright 2019 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 -# -# https://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. - -"""Accesses the google.devtools.clouderrorreporting.v1beta1 ErrorStatsService API.""" - -import functools -import pkg_resources -import warnings - -from google.oauth2 import service_account -import google.api_core.client_options -import google.api_core.gapic_v1.client_info -import google.api_core.gapic_v1.config -import google.api_core.gapic_v1.method -import google.api_core.gapic_v1.routing_header -import google.api_core.grpc_helpers -import google.api_core.page_iterator -import google.api_core.path_template -import grpc - -from google.cloud.errorreporting_v1beta1.gapic import enums -from google.cloud.errorreporting_v1beta1.gapic import error_stats_service_client_config -from google.cloud.errorreporting_v1beta1.gapic.transports import ( - error_stats_service_grpc_transport, -) -from google.cloud.errorreporting_v1beta1.proto import common_pb2 -from google.cloud.errorreporting_v1beta1.proto import error_group_service_pb2 -from google.cloud.errorreporting_v1beta1.proto import error_group_service_pb2_grpc -from google.cloud.errorreporting_v1beta1.proto import error_stats_service_pb2 -from google.cloud.errorreporting_v1beta1.proto import error_stats_service_pb2_grpc -from google.protobuf import duration_pb2 -from google.protobuf import timestamp_pb2 - - -_GAPIC_LIBRARY_VERSION = pkg_resources.get_distribution( - "google-cloud-error-reporting" -).version - - -class ErrorStatsServiceClient(object): - """ - An API for retrieving and managing error statistics as well as data for - individual events. - """ - - SERVICE_ADDRESS = "clouderrorreporting.googleapis.com:443" - """The default address of the service.""" - - # The name of the interface for this client. This is the key used to - # find the method configuration in the client_config dictionary. - _INTERFACE_NAME = "google.devtools.clouderrorreporting.v1beta1.ErrorStatsService" - - @classmethod - def from_service_account_file(cls, filename, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - ErrorStatsServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file(filename) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @classmethod - def project_path(cls, project): - """Return a fully-qualified project string.""" - return google.api_core.path_template.expand( - "projects/{project}", project=project - ) - - def __init__( - self, - transport=None, - channel=None, - credentials=None, - client_config=None, - client_info=None, - client_options=None, - ): - """Constructor. - - Args: - transport (Union[~.ErrorStatsServiceGrpcTransport, - Callable[[~.Credentials, type], ~.ErrorStatsServiceGrpcTransport]): A transport - instance, responsible for actually making the API calls. - The default transport uses the gRPC protocol. - This argument may also be a callable which returns a - transport instance. Callables will be sent the credentials - as the first argument and the default transport class as - the second argument. - channel (grpc.Channel): DEPRECATED. A ``Channel`` instance - through which to make calls. This argument is mutually exclusive - with ``credentials``; providing both will raise an exception. - credentials (google.auth.credentials.Credentials): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is mutually exclusive with providing a - transport instance to ``transport``; doing so will raise - an exception. - client_config (dict): DEPRECATED. A dictionary of call options for - each method. If not specified, the default configuration is used. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - client_options (Union[dict, google.api_core.client_options.ClientOptions]): - Client options used to set user options on the client. API Endpoint - should be set through client_options. - """ - # Raise deprecation warnings for things we want to go away. - if client_config is not None: - warnings.warn( - "The `client_config` argument is deprecated.", - PendingDeprecationWarning, - stacklevel=2, - ) - else: - client_config = error_stats_service_client_config.config - - if channel: - warnings.warn( - "The `channel` argument is deprecated; use " "`transport` instead.", - PendingDeprecationWarning, - stacklevel=2, - ) - - api_endpoint = self.SERVICE_ADDRESS - if client_options: - if type(client_options) == dict: - client_options = google.api_core.client_options.from_dict( - client_options - ) - if client_options.api_endpoint: - api_endpoint = client_options.api_endpoint - - # Instantiate the transport. - # The transport is responsible for handling serialization and - # deserialization and actually sending data to the service. - if transport: - if callable(transport): - self.transport = transport( - credentials=credentials, - default_class=error_stats_service_grpc_transport.ErrorStatsServiceGrpcTransport, - address=api_endpoint, - ) - else: - if credentials: - raise ValueError( - "Received both a transport instance and " - "credentials; these are mutually exclusive." - ) - self.transport = transport - else: - self.transport = error_stats_service_grpc_transport.ErrorStatsServiceGrpcTransport( - address=api_endpoint, channel=channel, credentials=credentials - ) - - if client_info is None: - client_info = google.api_core.gapic_v1.client_info.ClientInfo( - gapic_version=_GAPIC_LIBRARY_VERSION - ) - else: - client_info.gapic_version = _GAPIC_LIBRARY_VERSION - self._client_info = client_info - - # Parse out the default settings for retry and timeout for each RPC - # from the client configuration. - # (Ordinarily, these are the defaults specified in the `*_config.py` - # file next to this one.) - self._method_configs = google.api_core.gapic_v1.config.parse_method_configs( - client_config["interfaces"][self._INTERFACE_NAME] - ) - - # Save a dictionary of cached API call functions. - # These are the actual callables which invoke the proper - # transport methods, wrapped with `wrap_method` to add retry, - # timeout, and the like. - self._inner_api_calls = {} - - # Service calls - def list_group_stats( - self, - project_name, - time_range, - group_id=None, - service_filter=None, - timed_count_duration=None, - alignment=None, - alignment_time=None, - order=None, - page_size=None, - retry=google.api_core.gapic_v1.method.DEFAULT, - timeout=google.api_core.gapic_v1.method.DEFAULT, - metadata=None, - ): - """ - Lists the specified groups. - - Example: - >>> from google.cloud import errorreporting_v1beta1 - >>> - >>> client = errorreporting_v1beta1.ErrorStatsServiceClient() - >>> - >>> project_name = client.project_path('[PROJECT]') - >>> - >>> # TODO: Initialize `time_range`: - >>> time_range = {} - >>> - >>> # Iterate over all results - >>> for element in client.list_group_stats(project_name, time_range): - ... # process element - ... pass - >>> - >>> - >>> # Alternatively: - >>> - >>> # Iterate over results one page at a time - >>> for page in client.list_group_stats(project_name, time_range).pages: - ... for element in page: - ... # process element - ... pass - - Args: - project_name (str): [Required] The resource name of the Google Cloud Platform project. - Written as projects/ plus the Google Cloud Platform project ID. - - Example: projects/my-project-123. - time_range (Union[dict, ~google.cloud.errorreporting_v1beta1.types.QueryTimeRange]): [Optional] List data for the given time range. If not set a default time - range is used. The field time\_range\_begin in the response will specify - the beginning of this time range. Only ErrorGroupStats with a non-zero - count in the given time range are returned, unless the request contains - an explicit group\_id list. If a group\_id list is given, also - ErrorGroupStats with zero occurrences are returned. - - If a dict is provided, it must be of the same form as the protobuf - message :class:`~google.cloud.errorreporting_v1beta1.types.QueryTimeRange` - group_id (list[str]): [Optional] List all ErrorGroupStats with these IDs. - service_filter (Union[dict, ~google.cloud.errorreporting_v1beta1.types.ServiceContextFilter]): [Optional] List only ErrorGroupStats which belong to a service context - that matches the filter. Data for all service contexts is returned if - this field is not specified. - - If a dict is provided, it must be of the same form as the protobuf - message :class:`~google.cloud.errorreporting_v1beta1.types.ServiceContextFilter` - timed_count_duration (Union[dict, ~google.cloud.errorreporting_v1beta1.types.Duration]): [Optional] The preferred duration for a single returned ``TimedCount``. - If not set, no timed counts are returned. - - If a dict is provided, it must be of the same form as the protobuf - message :class:`~google.cloud.errorreporting_v1beta1.types.Duration` - alignment (~google.cloud.errorreporting_v1beta1.types.TimedCountAlignment): [Optional] The alignment of the timed counts to be returned. Default is - ``ALIGNMENT_EQUAL_AT_END``. - alignment_time (Union[dict, ~google.cloud.errorreporting_v1beta1.types.Timestamp]): [Optional] Time where the timed counts shall be aligned if rounded - alignment is chosen. Default is 00:00 UTC. - - If a dict is provided, it must be of the same form as the protobuf - message :class:`~google.cloud.errorreporting_v1beta1.types.Timestamp` - order (~google.cloud.errorreporting_v1beta1.types.ErrorGroupOrder): [Optional] The sort order in which the results are returned. Default is - ``COUNT_DESC``. - page_size (int): The maximum number of resources contained in the - underlying API response. If page streaming is performed per- - resource, this parameter does not affect the return value. If page - streaming is performed per-page, this determines the maximum number - of resources in a page. - retry (Optional[google.api_core.retry.Retry]): A retry object used - to retry requests. If ``None`` is specified, requests will - be retried using a default configuration. - timeout (Optional[float]): The amount of time, in seconds, to wait - for the request to complete. Note that if ``retry`` is - specified, the timeout applies to each individual attempt. - metadata (Optional[Sequence[Tuple[str, str]]]): Additional metadata - that is provided to the method. - - Returns: - A :class:`~google.api_core.page_iterator.PageIterator` instance. - An iterable of :class:`~google.cloud.errorreporting_v1beta1.types.ErrorGroupStats` instances. - You can also iterate over the pages of the response - using its `pages` property. - - Raises: - google.api_core.exceptions.GoogleAPICallError: If the request - failed for any reason. - google.api_core.exceptions.RetryError: If the request failed due - to a retryable error and retry attempts failed. - ValueError: If the parameters are invalid. - """ - # Wrap the transport method to add retry and timeout logic. - if "list_group_stats" not in self._inner_api_calls: - self._inner_api_calls[ - "list_group_stats" - ] = google.api_core.gapic_v1.method.wrap_method( - self.transport.list_group_stats, - default_retry=self._method_configs["ListGroupStats"].retry, - default_timeout=self._method_configs["ListGroupStats"].timeout, - client_info=self._client_info, - ) - - request = error_stats_service_pb2.ListGroupStatsRequest( - project_name=project_name, - time_range=time_range, - group_id=group_id, - service_filter=service_filter, - timed_count_duration=timed_count_duration, - alignment=alignment, - alignment_time=alignment_time, - order=order, - page_size=page_size, - ) - if metadata is None: - metadata = [] - metadata = list(metadata) - try: - routing_header = [("project_name", project_name)] - except AttributeError: - pass - else: - routing_metadata = google.api_core.gapic_v1.routing_header.to_grpc_metadata( - routing_header - ) - metadata.append(routing_metadata) - - iterator = google.api_core.page_iterator.GRPCIterator( - client=None, - method=functools.partial( - self._inner_api_calls["list_group_stats"], - retry=retry, - timeout=timeout, - metadata=metadata, - ), - request=request, - items_field="error_group_stats", - request_token_field="page_token", - response_token_field="next_page_token", - ) - return iterator - - def list_events( - self, - project_name, - group_id, - service_filter=None, - time_range=None, - page_size=None, - retry=google.api_core.gapic_v1.method.DEFAULT, - timeout=google.api_core.gapic_v1.method.DEFAULT, - metadata=None, - ): - """ - Lists the specified events. - - Example: - >>> from google.cloud import errorreporting_v1beta1 - >>> - >>> client = errorreporting_v1beta1.ErrorStatsServiceClient() - >>> - >>> project_name = client.project_path('[PROJECT]') - >>> - >>> # TODO: Initialize `group_id`: - >>> group_id = '' - >>> - >>> # Iterate over all results - >>> for element in client.list_events(project_name, group_id): - ... # process element - ... pass - >>> - >>> - >>> # Alternatively: - >>> - >>> # Iterate over results one page at a time - >>> for page in client.list_events(project_name, group_id).pages: - ... for element in page: - ... # process element - ... pass - - Args: - project_name (str): [Required] The resource name of the Google Cloud Platform project. - Written as ``projects/`` plus the `Google Cloud Platform project - ID `__. Example: - ``projects/my-project-123``. - group_id (str): [Required] The group for which events shall be returned. - service_filter (Union[dict, ~google.cloud.errorreporting_v1beta1.types.ServiceContextFilter]): [Optional] List only ErrorGroups which belong to a service context that - matches the filter. Data for all service contexts is returned if this - field is not specified. - - If a dict is provided, it must be of the same form as the protobuf - message :class:`~google.cloud.errorreporting_v1beta1.types.ServiceContextFilter` - time_range (Union[dict, ~google.cloud.errorreporting_v1beta1.types.QueryTimeRange]): [Optional] List only data for the given time range. If not set a default - time range is used. The field time\_range\_begin in the response will - specify the beginning of this time range. - - If a dict is provided, it must be of the same form as the protobuf - message :class:`~google.cloud.errorreporting_v1beta1.types.QueryTimeRange` - page_size (int): The maximum number of resources contained in the - underlying API response. If page streaming is performed per- - resource, this parameter does not affect the return value. If page - streaming is performed per-page, this determines the maximum number - of resources in a page. - retry (Optional[google.api_core.retry.Retry]): A retry object used - to retry requests. If ``None`` is specified, requests will - be retried using a default configuration. - timeout (Optional[float]): The amount of time, in seconds, to wait - for the request to complete. Note that if ``retry`` is - specified, the timeout applies to each individual attempt. - metadata (Optional[Sequence[Tuple[str, str]]]): Additional metadata - that is provided to the method. - - Returns: - A :class:`~google.api_core.page_iterator.PageIterator` instance. - An iterable of :class:`~google.cloud.errorreporting_v1beta1.types.ErrorEvent` instances. - You can also iterate over the pages of the response - using its `pages` property. - - Raises: - google.api_core.exceptions.GoogleAPICallError: If the request - failed for any reason. - google.api_core.exceptions.RetryError: If the request failed due - to a retryable error and retry attempts failed. - ValueError: If the parameters are invalid. - """ - # Wrap the transport method to add retry and timeout logic. - if "list_events" not in self._inner_api_calls: - self._inner_api_calls[ - "list_events" - ] = google.api_core.gapic_v1.method.wrap_method( - self.transport.list_events, - default_retry=self._method_configs["ListEvents"].retry, - default_timeout=self._method_configs["ListEvents"].timeout, - client_info=self._client_info, - ) - - request = error_stats_service_pb2.ListEventsRequest( - project_name=project_name, - group_id=group_id, - service_filter=service_filter, - time_range=time_range, - page_size=page_size, - ) - if metadata is None: - metadata = [] - metadata = list(metadata) - try: - routing_header = [("project_name", project_name)] - except AttributeError: - pass - else: - routing_metadata = google.api_core.gapic_v1.routing_header.to_grpc_metadata( - routing_header - ) - metadata.append(routing_metadata) - - iterator = google.api_core.page_iterator.GRPCIterator( - client=None, - method=functools.partial( - self._inner_api_calls["list_events"], - retry=retry, - timeout=timeout, - metadata=metadata, - ), - request=request, - items_field="error_events", - request_token_field="page_token", - response_token_field="next_page_token", - ) - return iterator - - def delete_events( - self, - project_name, - retry=google.api_core.gapic_v1.method.DEFAULT, - timeout=google.api_core.gapic_v1.method.DEFAULT, - metadata=None, - ): - """ - Deletes all error events of a given project. - - Example: - >>> from google.cloud import errorreporting_v1beta1 - >>> - >>> client = errorreporting_v1beta1.ErrorStatsServiceClient() - >>> - >>> project_name = client.project_path('[PROJECT]') - >>> - >>> response = client.delete_events(project_name) - - Args: - project_name (str): [Required] The resource name of the Google Cloud Platform project. - Written as ``projects/`` plus the `Google Cloud Platform project - ID `__. Example: - ``projects/my-project-123``. - retry (Optional[google.api_core.retry.Retry]): A retry object used - to retry requests. If ``None`` is specified, requests will - be retried using a default configuration. - timeout (Optional[float]): The amount of time, in seconds, to wait - for the request to complete. Note that if ``retry`` is - specified, the timeout applies to each individual attempt. - metadata (Optional[Sequence[Tuple[str, str]]]): Additional metadata - that is provided to the method. - - Returns: - A :class:`~google.cloud.errorreporting_v1beta1.types.DeleteEventsResponse` instance. - - Raises: - google.api_core.exceptions.GoogleAPICallError: If the request - failed for any reason. - google.api_core.exceptions.RetryError: If the request failed due - to a retryable error and retry attempts failed. - ValueError: If the parameters are invalid. - """ - # Wrap the transport method to add retry and timeout logic. - if "delete_events" not in self._inner_api_calls: - self._inner_api_calls[ - "delete_events" - ] = google.api_core.gapic_v1.method.wrap_method( - self.transport.delete_events, - default_retry=self._method_configs["DeleteEvents"].retry, - default_timeout=self._method_configs["DeleteEvents"].timeout, - client_info=self._client_info, - ) - - request = error_stats_service_pb2.DeleteEventsRequest(project_name=project_name) - if metadata is None: - metadata = [] - metadata = list(metadata) - try: - routing_header = [("project_name", project_name)] - except AttributeError: - pass - else: - routing_metadata = google.api_core.gapic_v1.routing_header.to_grpc_metadata( - routing_header - ) - metadata.append(routing_metadata) - - return self._inner_api_calls["delete_events"]( - request, retry=retry, timeout=timeout, metadata=metadata - ) diff --git a/google/cloud/errorreporting_v1beta1/gapic/error_stats_service_client_config.py b/google/cloud/errorreporting_v1beta1/gapic/error_stats_service_client_config.py deleted file mode 100644 index fead94c5..00000000 --- a/google/cloud/errorreporting_v1beta1/gapic/error_stats_service_client_config.py +++ /dev/null @@ -1,38 +0,0 @@ -config = { - "interfaces": { - "google.devtools.clouderrorreporting.v1beta1.ErrorStatsService": { - "retry_codes": { - "idempotent": ["DEADLINE_EXCEEDED", "UNAVAILABLE"], - "non_idempotent": [], - }, - "retry_params": { - "default": { - "initial_retry_delay_millis": 100, - "retry_delay_multiplier": 1.3, - "max_retry_delay_millis": 60000, - "initial_rpc_timeout_millis": 20000, - "rpc_timeout_multiplier": 1.0, - "max_rpc_timeout_millis": 20000, - "total_timeout_millis": 600000, - } - }, - "methods": { - "ListGroupStats": { - "timeout_millis": 60000, - "retry_codes_name": "idempotent", - "retry_params_name": "default", - }, - "ListEvents": { - "timeout_millis": 60000, - "retry_codes_name": "idempotent", - "retry_params_name": "default", - }, - "DeleteEvents": { - "timeout_millis": 60000, - "retry_codes_name": "idempotent", - "retry_params_name": "default", - }, - }, - } - } -} diff --git a/google/cloud/errorreporting_v1beta1/gapic/report_errors_service_client.py b/google/cloud/errorreporting_v1beta1/gapic/report_errors_service_client.py deleted file mode 100644 index 7ad37cc1..00000000 --- a/google/cloud/errorreporting_v1beta1/gapic/report_errors_service_client.py +++ /dev/null @@ -1,285 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright 2019 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 -# -# https://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. - -"""Accesses the google.devtools.clouderrorreporting.v1beta1 ReportErrorsService API.""" - -import pkg_resources -import warnings - -from google.oauth2 import service_account -import google.api_core.client_options -import google.api_core.gapic_v1.client_info -import google.api_core.gapic_v1.config -import google.api_core.gapic_v1.method -import google.api_core.gapic_v1.routing_header -import google.api_core.grpc_helpers -import google.api_core.path_template -import grpc - -from google.cloud.errorreporting_v1beta1.gapic import enums -from google.cloud.errorreporting_v1beta1.gapic import ( - report_errors_service_client_config, -) -from google.cloud.errorreporting_v1beta1.gapic.transports import ( - report_errors_service_grpc_transport, -) -from google.cloud.errorreporting_v1beta1.proto import common_pb2 -from google.cloud.errorreporting_v1beta1.proto import error_group_service_pb2 -from google.cloud.errorreporting_v1beta1.proto import error_group_service_pb2_grpc -from google.cloud.errorreporting_v1beta1.proto import error_stats_service_pb2 -from google.cloud.errorreporting_v1beta1.proto import error_stats_service_pb2_grpc -from google.cloud.errorreporting_v1beta1.proto import report_errors_service_pb2 -from google.cloud.errorreporting_v1beta1.proto import report_errors_service_pb2_grpc -from google.protobuf import duration_pb2 -from google.protobuf import timestamp_pb2 - - -_GAPIC_LIBRARY_VERSION = pkg_resources.get_distribution( - "google-cloud-error-reporting" -).version - - -class ReportErrorsServiceClient(object): - """An API for reporting error events.""" - - SERVICE_ADDRESS = "clouderrorreporting.googleapis.com:443" - """The default address of the service.""" - - # The name of the interface for this client. This is the key used to - # find the method configuration in the client_config dictionary. - _INTERFACE_NAME = "google.devtools.clouderrorreporting.v1beta1.ReportErrorsService" - - @classmethod - def from_service_account_file(cls, filename, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - ReportErrorsServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file(filename) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @classmethod - def project_path(cls, project): - """Return a fully-qualified project string.""" - return google.api_core.path_template.expand( - "projects/{project}", project=project - ) - - def __init__( - self, - transport=None, - channel=None, - credentials=None, - client_config=None, - client_info=None, - client_options=None, - ): - """Constructor. - - Args: - transport (Union[~.ReportErrorsServiceGrpcTransport, - Callable[[~.Credentials, type], ~.ReportErrorsServiceGrpcTransport]): A transport - instance, responsible for actually making the API calls. - The default transport uses the gRPC protocol. - This argument may also be a callable which returns a - transport instance. Callables will be sent the credentials - as the first argument and the default transport class as - the second argument. - channel (grpc.Channel): DEPRECATED. A ``Channel`` instance - through which to make calls. This argument is mutually exclusive - with ``credentials``; providing both will raise an exception. - credentials (google.auth.credentials.Credentials): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is mutually exclusive with providing a - transport instance to ``transport``; doing so will raise - an exception. - client_config (dict): DEPRECATED. A dictionary of call options for - each method. If not specified, the default configuration is used. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - client_options (Union[dict, google.api_core.client_options.ClientOptions]): - Client options used to set user options on the client. API Endpoint - should be set through client_options. - """ - # Raise deprecation warnings for things we want to go away. - if client_config is not None: - warnings.warn( - "The `client_config` argument is deprecated.", - PendingDeprecationWarning, - stacklevel=2, - ) - else: - client_config = report_errors_service_client_config.config - - if channel: - warnings.warn( - "The `channel` argument is deprecated; use " "`transport` instead.", - PendingDeprecationWarning, - stacklevel=2, - ) - - api_endpoint = self.SERVICE_ADDRESS - if client_options: - if type(client_options) == dict: - client_options = google.api_core.client_options.from_dict( - client_options - ) - if client_options.api_endpoint: - api_endpoint = client_options.api_endpoint - - # Instantiate the transport. - # The transport is responsible for handling serialization and - # deserialization and actually sending data to the service. - if transport: - if callable(transport): - self.transport = transport( - credentials=credentials, - default_class=report_errors_service_grpc_transport.ReportErrorsServiceGrpcTransport, - address=api_endpoint, - ) - else: - if credentials: - raise ValueError( - "Received both a transport instance and " - "credentials; these are mutually exclusive." - ) - self.transport = transport - else: - self.transport = report_errors_service_grpc_transport.ReportErrorsServiceGrpcTransport( - address=api_endpoint, channel=channel, credentials=credentials - ) - - if client_info is None: - client_info = google.api_core.gapic_v1.client_info.ClientInfo( - gapic_version=_GAPIC_LIBRARY_VERSION - ) - else: - client_info.gapic_version = _GAPIC_LIBRARY_VERSION - self._client_info = client_info - - # Parse out the default settings for retry and timeout for each RPC - # from the client configuration. - # (Ordinarily, these are the defaults specified in the `*_config.py` - # file next to this one.) - self._method_configs = google.api_core.gapic_v1.config.parse_method_configs( - client_config["interfaces"][self._INTERFACE_NAME] - ) - - # Save a dictionary of cached API call functions. - # These are the actual callables which invoke the proper - # transport methods, wrapped with `wrap_method` to add retry, - # timeout, and the like. - self._inner_api_calls = {} - - # Service calls - def report_error_event( - self, - project_name, - event, - retry=google.api_core.gapic_v1.method.DEFAULT, - timeout=google.api_core.gapic_v1.method.DEFAULT, - metadata=None, - ): - """ - Report an individual error event. - - Example: - >>> from google.cloud import errorreporting_v1beta1 - >>> - >>> client = errorreporting_v1beta1.ReportErrorsServiceClient() - >>> - >>> project_name = client.project_path('[PROJECT]') - >>> - >>> # TODO: Initialize `event`: - >>> event = {} - >>> - >>> response = client.report_error_event(project_name, event) - - Args: - project_name (str): [Required] The resource name of the Google Cloud Platform project. - Written as ``projects/`` plus the `Google Cloud Platform project - ID `__. Example: - ``projects/my-project-123``. - event (Union[dict, ~google.cloud.errorreporting_v1beta1.types.ReportedErrorEvent]): [Required] The error event to be reported. - - If a dict is provided, it must be of the same form as the protobuf - message :class:`~google.cloud.errorreporting_v1beta1.types.ReportedErrorEvent` - retry (Optional[google.api_core.retry.Retry]): A retry object used - to retry requests. If ``None`` is specified, requests will - be retried using a default configuration. - timeout (Optional[float]): The amount of time, in seconds, to wait - for the request to complete. Note that if ``retry`` is - specified, the timeout applies to each individual attempt. - metadata (Optional[Sequence[Tuple[str, str]]]): Additional metadata - that is provided to the method. - - Returns: - A :class:`~google.cloud.errorreporting_v1beta1.types.ReportErrorEventResponse` instance. - - Raises: - google.api_core.exceptions.GoogleAPICallError: If the request - failed for any reason. - google.api_core.exceptions.RetryError: If the request failed due - to a retryable error and retry attempts failed. - ValueError: If the parameters are invalid. - """ - # Wrap the transport method to add retry and timeout logic. - if "report_error_event" not in self._inner_api_calls: - self._inner_api_calls[ - "report_error_event" - ] = google.api_core.gapic_v1.method.wrap_method( - self.transport.report_error_event, - default_retry=self._method_configs["ReportErrorEvent"].retry, - default_timeout=self._method_configs["ReportErrorEvent"].timeout, - client_info=self._client_info, - ) - - request = report_errors_service_pb2.ReportErrorEventRequest( - project_name=project_name, event=event - ) - if metadata is None: - metadata = [] - metadata = list(metadata) - try: - routing_header = [("project_name", project_name)] - except AttributeError: - pass - else: - routing_metadata = google.api_core.gapic_v1.routing_header.to_grpc_metadata( - routing_header - ) - metadata.append(routing_metadata) - - return self._inner_api_calls["report_error_event"]( - request, retry=retry, timeout=timeout, metadata=metadata - ) diff --git a/google/cloud/errorreporting_v1beta1/gapic/report_errors_service_client_config.py b/google/cloud/errorreporting_v1beta1/gapic/report_errors_service_client_config.py deleted file mode 100644 index cfefc7eb..00000000 --- a/google/cloud/errorreporting_v1beta1/gapic/report_errors_service_client_config.py +++ /dev/null @@ -1,28 +0,0 @@ -config = { - "interfaces": { - "google.devtools.clouderrorreporting.v1beta1.ReportErrorsService": { - "retry_codes": { - "idempotent": ["DEADLINE_EXCEEDED", "UNAVAILABLE"], - "non_idempotent": [], - }, - "retry_params": { - "default": { - "initial_retry_delay_millis": 100, - "retry_delay_multiplier": 1.3, - "max_retry_delay_millis": 60000, - "initial_rpc_timeout_millis": 20000, - "rpc_timeout_multiplier": 1.0, - "max_rpc_timeout_millis": 20000, - "total_timeout_millis": 600000, - } - }, - "methods": { - "ReportErrorEvent": { - "timeout_millis": 60000, - "retry_codes_name": "non_idempotent", - "retry_params_name": "default", - } - }, - } - } -} diff --git a/google/cloud/errorreporting_v1beta1/gapic/transports/__init__.py b/google/cloud/errorreporting_v1beta1/gapic/transports/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/google/cloud/errorreporting_v1beta1/gapic/transports/error_group_service_grpc_transport.py b/google/cloud/errorreporting_v1beta1/gapic/transports/error_group_service_grpc_transport.py deleted file mode 100644 index cde299b8..00000000 --- a/google/cloud/errorreporting_v1beta1/gapic/transports/error_group_service_grpc_transport.py +++ /dev/null @@ -1,143 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright 2019 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 -# -# https://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. - - -import google.api_core.grpc_helpers - -from google.cloud.errorreporting_v1beta1.proto import error_group_service_pb2_grpc - - -class ErrorGroupServiceGrpcTransport(object): - """gRPC transport class providing stubs for - google.devtools.clouderrorreporting.v1beta1 ErrorGroupService API. - - The transport provides access to the raw gRPC stubs, - which can be used to take advantage of advanced - features of gRPC. - """ - - # The scopes needed to make gRPC calls to all of the methods defined - # in this service. - _OAUTH_SCOPES = ("https://www.googleapis.com/auth/cloud-platform",) - - def __init__( - self, - channel=None, - credentials=None, - address="clouderrorreporting.googleapis.com:443", - ): - """Instantiate the transport class. - - Args: - channel (grpc.Channel): A ``Channel`` instance through - which to make calls. This argument is mutually exclusive - with ``credentials``; providing both will raise an exception. - credentials (google.auth.credentials.Credentials): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If none - are specified, the client will attempt to ascertain the - credentials from the environment. - address (str): The address where the service is hosted. - """ - # If both `channel` and `credentials` are specified, raise an - # exception (channels come with credentials baked in already). - if channel is not None and credentials is not None: - raise ValueError( - "The `channel` and `credentials` arguments are mutually " "exclusive." - ) - - # Create the channel. - if channel is None: - channel = self.create_channel( - address=address, - credentials=credentials, - options={ - "grpc.max_send_message_length": -1, - "grpc.max_receive_message_length": -1, - }.items(), - ) - - self._channel = channel - - # gRPC uses objects called "stubs" that are bound to the - # channel and provide a basic method for each RPC. - self._stubs = { - "error_group_service_stub": error_group_service_pb2_grpc.ErrorGroupServiceStub( - channel - ) - } - - @classmethod - def create_channel( - cls, - address="clouderrorreporting.googleapis.com:443", - credentials=None, - **kwargs - ): - """Create and return a gRPC channel object. - - Args: - address (str): The host for the channel to use. - credentials (~.Credentials): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - kwargs (dict): Keyword arguments, which are passed to the - channel creation. - - Returns: - grpc.Channel: A gRPC channel object. - """ - return google.api_core.grpc_helpers.create_channel( - address, credentials=credentials, scopes=cls._OAUTH_SCOPES, **kwargs - ) - - @property - def channel(self): - """The gRPC channel used by the transport. - - Returns: - grpc.Channel: A gRPC channel object. - """ - return self._channel - - @property - def get_group(self): - """Return the gRPC stub for :meth:`ErrorGroupServiceClient.get_group`. - - Get the specified group. - - Returns: - Callable: A callable which accepts the appropriate - deserialized request object and returns a - deserialized response object. - """ - return self._stubs["error_group_service_stub"].GetGroup - - @property - def update_group(self): - """Return the gRPC stub for :meth:`ErrorGroupServiceClient.update_group`. - - Replace the data for the specified group. - Fails if the group does not exist. - - Returns: - Callable: A callable which accepts the appropriate - deserialized request object and returns a - deserialized response object. - """ - return self._stubs["error_group_service_stub"].UpdateGroup diff --git a/google/cloud/errorreporting_v1beta1/gapic/transports/error_stats_service_grpc_transport.py b/google/cloud/errorreporting_v1beta1/gapic/transports/error_stats_service_grpc_transport.py deleted file mode 100644 index 2ef5f212..00000000 --- a/google/cloud/errorreporting_v1beta1/gapic/transports/error_stats_service_grpc_transport.py +++ /dev/null @@ -1,155 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright 2019 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 -# -# https://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. - - -import google.api_core.grpc_helpers - -from google.cloud.errorreporting_v1beta1.proto import error_stats_service_pb2_grpc - - -class ErrorStatsServiceGrpcTransport(object): - """gRPC transport class providing stubs for - google.devtools.clouderrorreporting.v1beta1 ErrorStatsService API. - - The transport provides access to the raw gRPC stubs, - which can be used to take advantage of advanced - features of gRPC. - """ - - # The scopes needed to make gRPC calls to all of the methods defined - # in this service. - _OAUTH_SCOPES = ("https://www.googleapis.com/auth/cloud-platform",) - - def __init__( - self, - channel=None, - credentials=None, - address="clouderrorreporting.googleapis.com:443", - ): - """Instantiate the transport class. - - Args: - channel (grpc.Channel): A ``Channel`` instance through - which to make calls. This argument is mutually exclusive - with ``credentials``; providing both will raise an exception. - credentials (google.auth.credentials.Credentials): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If none - are specified, the client will attempt to ascertain the - credentials from the environment. - address (str): The address where the service is hosted. - """ - # If both `channel` and `credentials` are specified, raise an - # exception (channels come with credentials baked in already). - if channel is not None and credentials is not None: - raise ValueError( - "The `channel` and `credentials` arguments are mutually " "exclusive." - ) - - # Create the channel. - if channel is None: - channel = self.create_channel( - address=address, - credentials=credentials, - options={ - "grpc.max_send_message_length": -1, - "grpc.max_receive_message_length": -1, - }.items(), - ) - - self._channel = channel - - # gRPC uses objects called "stubs" that are bound to the - # channel and provide a basic method for each RPC. - self._stubs = { - "error_stats_service_stub": error_stats_service_pb2_grpc.ErrorStatsServiceStub( - channel - ) - } - - @classmethod - def create_channel( - cls, - address="clouderrorreporting.googleapis.com:443", - credentials=None, - **kwargs - ): - """Create and return a gRPC channel object. - - Args: - address (str): The host for the channel to use. - credentials (~.Credentials): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - kwargs (dict): Keyword arguments, which are passed to the - channel creation. - - Returns: - grpc.Channel: A gRPC channel object. - """ - return google.api_core.grpc_helpers.create_channel( - address, credentials=credentials, scopes=cls._OAUTH_SCOPES, **kwargs - ) - - @property - def channel(self): - """The gRPC channel used by the transport. - - Returns: - grpc.Channel: A gRPC channel object. - """ - return self._channel - - @property - def list_group_stats(self): - """Return the gRPC stub for :meth:`ErrorStatsServiceClient.list_group_stats`. - - Lists the specified groups. - - Returns: - Callable: A callable which accepts the appropriate - deserialized request object and returns a - deserialized response object. - """ - return self._stubs["error_stats_service_stub"].ListGroupStats - - @property - def list_events(self): - """Return the gRPC stub for :meth:`ErrorStatsServiceClient.list_events`. - - Lists the specified events. - - Returns: - Callable: A callable which accepts the appropriate - deserialized request object and returns a - deserialized response object. - """ - return self._stubs["error_stats_service_stub"].ListEvents - - @property - def delete_events(self): - """Return the gRPC stub for :meth:`ErrorStatsServiceClient.delete_events`. - - Deletes all error events of a given project. - - Returns: - Callable: A callable which accepts the appropriate - deserialized request object and returns a - deserialized response object. - """ - return self._stubs["error_stats_service_stub"].DeleteEvents diff --git a/google/cloud/errorreporting_v1beta1/gapic/transports/report_errors_service_grpc_transport.py b/google/cloud/errorreporting_v1beta1/gapic/transports/report_errors_service_grpc_transport.py deleted file mode 100644 index e367e49c..00000000 --- a/google/cloud/errorreporting_v1beta1/gapic/transports/report_errors_service_grpc_transport.py +++ /dev/null @@ -1,129 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright 2019 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 -# -# https://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. - - -import google.api_core.grpc_helpers - -from google.cloud.errorreporting_v1beta1.proto import report_errors_service_pb2_grpc - - -class ReportErrorsServiceGrpcTransport(object): - """gRPC transport class providing stubs for - google.devtools.clouderrorreporting.v1beta1 ReportErrorsService API. - - The transport provides access to the raw gRPC stubs, - which can be used to take advantage of advanced - features of gRPC. - """ - - # The scopes needed to make gRPC calls to all of the methods defined - # in this service. - _OAUTH_SCOPES = ("https://www.googleapis.com/auth/cloud-platform",) - - def __init__( - self, - channel=None, - credentials=None, - address="clouderrorreporting.googleapis.com:443", - ): - """Instantiate the transport class. - - Args: - channel (grpc.Channel): A ``Channel`` instance through - which to make calls. This argument is mutually exclusive - with ``credentials``; providing both will raise an exception. - credentials (google.auth.credentials.Credentials): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If none - are specified, the client will attempt to ascertain the - credentials from the environment. - address (str): The address where the service is hosted. - """ - # If both `channel` and `credentials` are specified, raise an - # exception (channels come with credentials baked in already). - if channel is not None and credentials is not None: - raise ValueError( - "The `channel` and `credentials` arguments are mutually " "exclusive." - ) - - # Create the channel. - if channel is None: - channel = self.create_channel( - address=address, - credentials=credentials, - options={ - "grpc.max_send_message_length": -1, - "grpc.max_receive_message_length": -1, - }.items(), - ) - - self._channel = channel - - # gRPC uses objects called "stubs" that are bound to the - # channel and provide a basic method for each RPC. - self._stubs = { - "report_errors_service_stub": report_errors_service_pb2_grpc.ReportErrorsServiceStub( - channel - ) - } - - @classmethod - def create_channel( - cls, - address="clouderrorreporting.googleapis.com:443", - credentials=None, - **kwargs - ): - """Create and return a gRPC channel object. - - Args: - address (str): The host for the channel to use. - credentials (~.Credentials): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - kwargs (dict): Keyword arguments, which are passed to the - channel creation. - - Returns: - grpc.Channel: A gRPC channel object. - """ - return google.api_core.grpc_helpers.create_channel( - address, credentials=credentials, scopes=cls._OAUTH_SCOPES, **kwargs - ) - - @property - def channel(self): - """The gRPC channel used by the transport. - - Returns: - grpc.Channel: A gRPC channel object. - """ - return self._channel - - @property - def report_error_event(self): - """Return the gRPC stub for :meth:`ReportErrorsServiceClient.report_error_event`. - - Report an individual error event. - - Returns: - Callable: A callable which accepts the appropriate - deserialized request object and returns a - deserialized response object. - """ - return self._stubs["report_errors_service_stub"].ReportErrorEvent diff --git a/google/cloud/errorreporting_v1beta1/proto/__init__.py b/google/cloud/errorreporting_v1beta1/proto/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/google/cloud/errorreporting_v1beta1/proto/common.proto b/google/cloud/errorreporting_v1beta1/proto/common.proto index 132f1a64..7a1d2003 100644 --- a/google/cloud/errorreporting_v1beta1/proto/common.proto +++ b/google/cloud/errorreporting_v1beta1/proto/common.proto @@ -1,4 +1,4 @@ -// Copyright 2016 Google Inc. +// Copyright 2019 Google LLC. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -17,18 +17,25 @@ syntax = "proto3"; package google.devtools.clouderrorreporting.v1beta1; import "google/api/annotations.proto"; -import "google/api/monitored_resource.proto"; +import "google/api/resource.proto"; import "google/protobuf/timestamp.proto"; +option cc_enable_arenas = true; option csharp_namespace = "Google.Cloud.ErrorReporting.V1Beta1"; option go_package = "google.golang.org/genproto/googleapis/devtools/clouderrorreporting/v1beta1;clouderrorreporting"; option java_multiple_files = true; option java_outer_classname = "CommonProto"; option java_package = "com.google.devtools.clouderrorreporting.v1beta1"; option php_namespace = "Google\\Cloud\\ErrorReporting\\V1beta1"; +option ruby_package = "Google::Cloud::ErrorReporting::V1beta1"; // Description of a group of similar error events. message ErrorGroup { + option (google.api.resource) = { + type: "clouderrorreporting.googleapis.com/ErrorGroup" + pattern: "projects/{project}/groups/{group}" + }; + // The group resource name. // Example: projects/my-project-123/groups/my-groupid string name = 1; @@ -44,7 +51,7 @@ message ErrorGroup { // Information related to tracking the progress on resolving the error. message TrackingIssue { // A URL pointing to a related entry in an issue tracking system. - // Example: https://github.com/user/project/issues/4 + // Example: `https://github.com/user/project/issues/4` string url = 1; } @@ -79,6 +86,8 @@ message ServiceContext { // Represents the source code version that the developer provided, // which could represent a version label or a Git SHA-1 hash, for example. + // For App Engine standard environment, the version is set to the version of + // the app. string version = 3; // Type of the MonitoredResource. List of possible values: @@ -112,8 +121,7 @@ message ErrorContext { // report the error, usually the place where it was logged. // For a logged exception this would be the source line where the // exception is logged, usually close to the place where it was - // caught. This value is in contrast to `Exception.cause_location`, - // which describes the source line where the exception was thrown. + // caught. SourceLocation report_location = 3; } @@ -144,11 +152,10 @@ message HttpRequestContext { string remote_ip = 6; } -// Indicates a location in the source code of the service for which -// errors are reported. -// This data should be provided by the application when reporting an error, -// unless the error report has been generated automatically from Google App -// Engine logs. All fields are optional. +// Indicates a location in the source code of the service for which errors are +// reported. `functionName` must be provided by the application when reporting +// an error, unless the error report contains a `message` with a supported +// exception stack trace. All fields are optional for the later case. message SourceLocation { // The source code filename, which can include a truncated relative // path, or a full path from a production machine. diff --git a/google/cloud/errorreporting_v1beta1/proto/common_pb2.py b/google/cloud/errorreporting_v1beta1/proto/common_pb2.py deleted file mode 100644 index c9ebc4c6..00000000 --- a/google/cloud/errorreporting_v1beta1/proto/common_pb2.py +++ /dev/null @@ -1,825 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: google/devtools/clouderrorreporting_v1beta1/proto/common.proto - -import sys - -_b = sys.version_info[0] < 3 and (lambda x: x) or (lambda x: x.encode("latin1")) -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf import reflection as _reflection -from google.protobuf import symbol_database as _symbol_database - -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from google.api import annotations_pb2 as google_dot_api_dot_annotations__pb2 -from google.api import ( - monitored_resource_pb2 as google_dot_api_dot_monitored__resource__pb2, -) -from google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__pb2 - - -DESCRIPTOR = _descriptor.FileDescriptor( - name="google/devtools/clouderrorreporting_v1beta1/proto/common.proto", - package="google.devtools.clouderrorreporting.v1beta1", - syntax="proto3", - serialized_options=_b( - "\n/com.google.devtools.clouderrorreporting.v1beta1B\013CommonProtoP\001Z^google.golang.org/genproto/googleapis/devtools/clouderrorreporting/v1beta1;clouderrorreporting\252\002#Google.Cloud.ErrorReporting.V1Beta1\312\002#Google\\Cloud\\ErrorReporting\\V1beta1" - ), - serialized_pb=_b( - '\n>google/devtools/clouderrorreporting_v1beta1/proto/common.proto\x12+google.devtools.clouderrorreporting.v1beta1\x1a\x1cgoogle/api/annotations.proto\x1a#google/api/monitored_resource.proto\x1a\x1fgoogle/protobuf/timestamp.proto"\x81\x01\n\nErrorGroup\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x10\n\x08group_id\x18\x02 \x01(\t\x12S\n\x0ftracking_issues\x18\x03 \x03(\x0b\x32:.google.devtools.clouderrorreporting.v1beta1.TrackingIssue"\x1c\n\rTrackingIssue\x12\x0b\n\x03url\x18\x01 \x01(\t"\xef\x01\n\nErrorEvent\x12.\n\nevent_time\x18\x01 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12T\n\x0fservice_context\x18\x02 \x01(\x0b\x32;.google.devtools.clouderrorreporting.v1beta1.ServiceContext\x12\x0f\n\x07message\x18\x03 \x01(\t\x12J\n\x07\x63ontext\x18\x05 \x01(\x0b\x32\x39.google.devtools.clouderrorreporting.v1beta1.ErrorContext"I\n\x0eServiceContext\x12\x0f\n\x07service\x18\x02 \x01(\t\x12\x0f\n\x07version\x18\x03 \x01(\t\x12\x15\n\rresource_type\x18\x04 \x01(\t"\xc9\x01\n\x0c\x45rrorContext\x12U\n\x0chttp_request\x18\x01 \x01(\x0b\x32?.google.devtools.clouderrorreporting.v1beta1.HttpRequestContext\x12\x0c\n\x04user\x18\x02 \x01(\t\x12T\n\x0freport_location\x18\x03 \x01(\x0b\x32;.google.devtools.clouderrorreporting.v1beta1.SourceLocation"\x88\x01\n\x12HttpRequestContext\x12\x0e\n\x06method\x18\x01 \x01(\t\x12\x0b\n\x03url\x18\x02 \x01(\t\x12\x12\n\nuser_agent\x18\x03 \x01(\t\x12\x10\n\x08referrer\x18\x04 \x01(\t\x12\x1c\n\x14response_status_code\x18\x05 \x01(\x05\x12\x11\n\tremote_ip\x18\x06 \x01(\t"O\n\x0eSourceLocation\x12\x11\n\tfile_path\x18\x01 \x01(\t\x12\x13\n\x0bline_number\x18\x02 \x01(\x05\x12\x15\n\rfunction_name\x18\x04 \x01(\tB\xec\x01\n/com.google.devtools.clouderrorreporting.v1beta1B\x0b\x43ommonProtoP\x01Z^google.golang.org/genproto/googleapis/devtools/clouderrorreporting/v1beta1;clouderrorreporting\xaa\x02#Google.Cloud.ErrorReporting.V1Beta1\xca\x02#Google\\Cloud\\ErrorReporting\\V1beta1b\x06proto3' - ), - dependencies=[ - google_dot_api_dot_annotations__pb2.DESCRIPTOR, - google_dot_api_dot_monitored__resource__pb2.DESCRIPTOR, - google_dot_protobuf_dot_timestamp__pb2.DESCRIPTOR, - ], -) - - -_ERRORGROUP = _descriptor.Descriptor( - name="ErrorGroup", - full_name="google.devtools.clouderrorreporting.v1beta1.ErrorGroup", - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name="name", - full_name="google.devtools.clouderrorreporting.v1beta1.ErrorGroup.name", - index=0, - number=1, - type=9, - cpp_type=9, - label=1, - has_default_value=False, - default_value=_b("").decode("utf-8"), - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - ), - _descriptor.FieldDescriptor( - name="group_id", - full_name="google.devtools.clouderrorreporting.v1beta1.ErrorGroup.group_id", - index=1, - number=2, - type=9, - cpp_type=9, - label=1, - has_default_value=False, - default_value=_b("").decode("utf-8"), - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - ), - _descriptor.FieldDescriptor( - name="tracking_issues", - full_name="google.devtools.clouderrorreporting.v1beta1.ErrorGroup.tracking_issues", - index=2, - number=3, - type=11, - cpp_type=10, - label=3, - has_default_value=False, - default_value=[], - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - ), - ], - extensions=[], - nested_types=[], - enum_types=[], - serialized_options=None, - is_extendable=False, - syntax="proto3", - extension_ranges=[], - oneofs=[], - serialized_start=212, - serialized_end=341, -) - - -_TRACKINGISSUE = _descriptor.Descriptor( - name="TrackingIssue", - full_name="google.devtools.clouderrorreporting.v1beta1.TrackingIssue", - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name="url", - full_name="google.devtools.clouderrorreporting.v1beta1.TrackingIssue.url", - index=0, - number=1, - type=9, - cpp_type=9, - label=1, - has_default_value=False, - default_value=_b("").decode("utf-8"), - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - ) - ], - extensions=[], - nested_types=[], - enum_types=[], - serialized_options=None, - is_extendable=False, - syntax="proto3", - extension_ranges=[], - oneofs=[], - serialized_start=343, - serialized_end=371, -) - - -_ERROREVENT = _descriptor.Descriptor( - name="ErrorEvent", - full_name="google.devtools.clouderrorreporting.v1beta1.ErrorEvent", - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name="event_time", - full_name="google.devtools.clouderrorreporting.v1beta1.ErrorEvent.event_time", - index=0, - number=1, - type=11, - cpp_type=10, - label=1, - has_default_value=False, - default_value=None, - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - ), - _descriptor.FieldDescriptor( - name="service_context", - full_name="google.devtools.clouderrorreporting.v1beta1.ErrorEvent.service_context", - index=1, - number=2, - type=11, - cpp_type=10, - label=1, - has_default_value=False, - default_value=None, - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - ), - _descriptor.FieldDescriptor( - name="message", - full_name="google.devtools.clouderrorreporting.v1beta1.ErrorEvent.message", - index=2, - number=3, - type=9, - cpp_type=9, - label=1, - has_default_value=False, - default_value=_b("").decode("utf-8"), - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - ), - _descriptor.FieldDescriptor( - name="context", - full_name="google.devtools.clouderrorreporting.v1beta1.ErrorEvent.context", - index=3, - number=5, - type=11, - cpp_type=10, - label=1, - has_default_value=False, - default_value=None, - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - ), - ], - extensions=[], - nested_types=[], - enum_types=[], - serialized_options=None, - is_extendable=False, - syntax="proto3", - extension_ranges=[], - oneofs=[], - serialized_start=374, - serialized_end=613, -) - - -_SERVICECONTEXT = _descriptor.Descriptor( - name="ServiceContext", - full_name="google.devtools.clouderrorreporting.v1beta1.ServiceContext", - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name="service", - full_name="google.devtools.clouderrorreporting.v1beta1.ServiceContext.service", - index=0, - number=2, - type=9, - cpp_type=9, - label=1, - has_default_value=False, - default_value=_b("").decode("utf-8"), - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - ), - _descriptor.FieldDescriptor( - name="version", - full_name="google.devtools.clouderrorreporting.v1beta1.ServiceContext.version", - index=1, - number=3, - type=9, - cpp_type=9, - label=1, - has_default_value=False, - default_value=_b("").decode("utf-8"), - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - ), - _descriptor.FieldDescriptor( - name="resource_type", - full_name="google.devtools.clouderrorreporting.v1beta1.ServiceContext.resource_type", - index=2, - number=4, - type=9, - cpp_type=9, - label=1, - has_default_value=False, - default_value=_b("").decode("utf-8"), - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - ), - ], - extensions=[], - nested_types=[], - enum_types=[], - serialized_options=None, - is_extendable=False, - syntax="proto3", - extension_ranges=[], - oneofs=[], - serialized_start=615, - serialized_end=688, -) - - -_ERRORCONTEXT = _descriptor.Descriptor( - name="ErrorContext", - full_name="google.devtools.clouderrorreporting.v1beta1.ErrorContext", - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name="http_request", - full_name="google.devtools.clouderrorreporting.v1beta1.ErrorContext.http_request", - index=0, - number=1, - type=11, - cpp_type=10, - label=1, - has_default_value=False, - default_value=None, - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - ), - _descriptor.FieldDescriptor( - name="user", - full_name="google.devtools.clouderrorreporting.v1beta1.ErrorContext.user", - index=1, - number=2, - type=9, - cpp_type=9, - label=1, - has_default_value=False, - default_value=_b("").decode("utf-8"), - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - ), - _descriptor.FieldDescriptor( - name="report_location", - full_name="google.devtools.clouderrorreporting.v1beta1.ErrorContext.report_location", - index=2, - number=3, - type=11, - cpp_type=10, - label=1, - has_default_value=False, - default_value=None, - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - ), - ], - extensions=[], - nested_types=[], - enum_types=[], - serialized_options=None, - is_extendable=False, - syntax="proto3", - extension_ranges=[], - oneofs=[], - serialized_start=691, - serialized_end=892, -) - - -_HTTPREQUESTCONTEXT = _descriptor.Descriptor( - name="HttpRequestContext", - full_name="google.devtools.clouderrorreporting.v1beta1.HttpRequestContext", - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name="method", - full_name="google.devtools.clouderrorreporting.v1beta1.HttpRequestContext.method", - index=0, - number=1, - type=9, - cpp_type=9, - label=1, - has_default_value=False, - default_value=_b("").decode("utf-8"), - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - ), - _descriptor.FieldDescriptor( - name="url", - full_name="google.devtools.clouderrorreporting.v1beta1.HttpRequestContext.url", - index=1, - number=2, - type=9, - cpp_type=9, - label=1, - has_default_value=False, - default_value=_b("").decode("utf-8"), - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - ), - _descriptor.FieldDescriptor( - name="user_agent", - full_name="google.devtools.clouderrorreporting.v1beta1.HttpRequestContext.user_agent", - index=2, - number=3, - type=9, - cpp_type=9, - label=1, - has_default_value=False, - default_value=_b("").decode("utf-8"), - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - ), - _descriptor.FieldDescriptor( - name="referrer", - full_name="google.devtools.clouderrorreporting.v1beta1.HttpRequestContext.referrer", - index=3, - number=4, - type=9, - cpp_type=9, - label=1, - has_default_value=False, - default_value=_b("").decode("utf-8"), - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - ), - _descriptor.FieldDescriptor( - name="response_status_code", - full_name="google.devtools.clouderrorreporting.v1beta1.HttpRequestContext.response_status_code", - index=4, - number=5, - type=5, - cpp_type=1, - label=1, - has_default_value=False, - default_value=0, - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - ), - _descriptor.FieldDescriptor( - name="remote_ip", - full_name="google.devtools.clouderrorreporting.v1beta1.HttpRequestContext.remote_ip", - index=5, - number=6, - type=9, - cpp_type=9, - label=1, - has_default_value=False, - default_value=_b("").decode("utf-8"), - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - ), - ], - extensions=[], - nested_types=[], - enum_types=[], - serialized_options=None, - is_extendable=False, - syntax="proto3", - extension_ranges=[], - oneofs=[], - serialized_start=895, - serialized_end=1031, -) - - -_SOURCELOCATION = _descriptor.Descriptor( - name="SourceLocation", - full_name="google.devtools.clouderrorreporting.v1beta1.SourceLocation", - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name="file_path", - full_name="google.devtools.clouderrorreporting.v1beta1.SourceLocation.file_path", - index=0, - number=1, - type=9, - cpp_type=9, - label=1, - has_default_value=False, - default_value=_b("").decode("utf-8"), - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - ), - _descriptor.FieldDescriptor( - name="line_number", - full_name="google.devtools.clouderrorreporting.v1beta1.SourceLocation.line_number", - index=1, - number=2, - type=5, - cpp_type=1, - label=1, - has_default_value=False, - default_value=0, - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - ), - _descriptor.FieldDescriptor( - name="function_name", - full_name="google.devtools.clouderrorreporting.v1beta1.SourceLocation.function_name", - index=2, - number=4, - type=9, - cpp_type=9, - label=1, - has_default_value=False, - default_value=_b("").decode("utf-8"), - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - ), - ], - extensions=[], - nested_types=[], - enum_types=[], - serialized_options=None, - is_extendable=False, - syntax="proto3", - extension_ranges=[], - oneofs=[], - serialized_start=1033, - serialized_end=1112, -) - -_ERRORGROUP.fields_by_name["tracking_issues"].message_type = _TRACKINGISSUE -_ERROREVENT.fields_by_name[ - "event_time" -].message_type = google_dot_protobuf_dot_timestamp__pb2._TIMESTAMP -_ERROREVENT.fields_by_name["service_context"].message_type = _SERVICECONTEXT -_ERROREVENT.fields_by_name["context"].message_type = _ERRORCONTEXT -_ERRORCONTEXT.fields_by_name["http_request"].message_type = _HTTPREQUESTCONTEXT -_ERRORCONTEXT.fields_by_name["report_location"].message_type = _SOURCELOCATION -DESCRIPTOR.message_types_by_name["ErrorGroup"] = _ERRORGROUP -DESCRIPTOR.message_types_by_name["TrackingIssue"] = _TRACKINGISSUE -DESCRIPTOR.message_types_by_name["ErrorEvent"] = _ERROREVENT -DESCRIPTOR.message_types_by_name["ServiceContext"] = _SERVICECONTEXT -DESCRIPTOR.message_types_by_name["ErrorContext"] = _ERRORCONTEXT -DESCRIPTOR.message_types_by_name["HttpRequestContext"] = _HTTPREQUESTCONTEXT -DESCRIPTOR.message_types_by_name["SourceLocation"] = _SOURCELOCATION -_sym_db.RegisterFileDescriptor(DESCRIPTOR) - -ErrorGroup = _reflection.GeneratedProtocolMessageType( - "ErrorGroup", - (_message.Message,), - dict( - DESCRIPTOR=_ERRORGROUP, - __module__="google.devtools.clouderrorreporting_v1beta1.proto.common_pb2", - __doc__="""Description of a group of similar error events. - - - Attributes: - name: - The group resource name. Example: projects/my- - project-123/groups/my-groupid - group_id: - Group IDs are unique for a given project. If the same kind of - error occurs in different service contexts, it will receive - the same group ID. - tracking_issues: - Associated tracking issues. - """, - # @@protoc_insertion_point(class_scope:google.devtools.clouderrorreporting.v1beta1.ErrorGroup) - ), -) -_sym_db.RegisterMessage(ErrorGroup) - -TrackingIssue = _reflection.GeneratedProtocolMessageType( - "TrackingIssue", - (_message.Message,), - dict( - DESCRIPTOR=_TRACKINGISSUE, - __module__="google.devtools.clouderrorreporting_v1beta1.proto.common_pb2", - __doc__="""Information related to tracking the progress on resolving the error. - - - Attributes: - url: - A URL pointing to a related entry in an issue tracking system. - Example: https://github.com/user/project/issues/4 - """, - # @@protoc_insertion_point(class_scope:google.devtools.clouderrorreporting.v1beta1.TrackingIssue) - ), -) -_sym_db.RegisterMessage(TrackingIssue) - -ErrorEvent = _reflection.GeneratedProtocolMessageType( - "ErrorEvent", - (_message.Message,), - dict( - DESCRIPTOR=_ERROREVENT, - __module__="google.devtools.clouderrorreporting_v1beta1.proto.common_pb2", - __doc__="""An error event which is returned by the Error Reporting system. - - - Attributes: - event_time: - Time when the event occurred as provided in the error report. - If the report did not contain a timestamp, the time the error - was received by the Error Reporting system is used. - service_context: - The ``ServiceContext`` for which this error was reported. - message: - The stack trace that was reported or logged by the service. - context: - Data about the context in which the error occurred. - """, - # @@protoc_insertion_point(class_scope:google.devtools.clouderrorreporting.v1beta1.ErrorEvent) - ), -) -_sym_db.RegisterMessage(ErrorEvent) - -ServiceContext = _reflection.GeneratedProtocolMessageType( - "ServiceContext", - (_message.Message,), - dict( - DESCRIPTOR=_SERVICECONTEXT, - __module__="google.devtools.clouderrorreporting_v1beta1.proto.common_pb2", - __doc__="""Describes a running service that sends errors. Its version changes over - time and multiple versions can run in parallel. - - - Attributes: - service: - An identifier of the service, such as the name of the - executable, job, or Google App Engine service name. This field - is expected to have a low number of values that are relatively - stable over time, as opposed to ``version``, which can be - changed whenever new code is deployed. Contains the service - name for error reports extracted from Google App Engine logs - or ``default`` if the App Engine default service is used. - version: - Represents the source code version that the developer - provided, which could represent a version label or a Git SHA-1 - hash, for example. - resource_type: - Type of the MonitoredResource. List of possible values: - https://cloud.google.com/monitoring/api/resources Value is - set automatically for incoming errors and must not be set when - reporting errors. - """, - # @@protoc_insertion_point(class_scope:google.devtools.clouderrorreporting.v1beta1.ServiceContext) - ), -) -_sym_db.RegisterMessage(ServiceContext) - -ErrorContext = _reflection.GeneratedProtocolMessageType( - "ErrorContext", - (_message.Message,), - dict( - DESCRIPTOR=_ERRORCONTEXT, - __module__="google.devtools.clouderrorreporting_v1beta1.proto.common_pb2", - __doc__="""A description of the context in which an error occurred. This data - should be provided by the application when reporting an error, unless - the error report has been generated automatically from Google App Engine - logs. - - - Attributes: - http_request: - The HTTP request which was processed when the error was - triggered. - user: - The user who caused or was affected by the crash. This can be - a user ID, an email address, or an arbitrary token that - uniquely identifies the user. When sending an error report, - leave this field empty if the user was not logged in. In this - case the Error Reporting system will use other data, such as - remote IP address, to distinguish affected users. See - ``affected_users_count`` in ``ErrorGroupStats``. - report_location: - The location in the source code where the decision was made to - report the error, usually the place where it was logged. For a - logged exception this would be the source line where the - exception is logged, usually close to the place where it was - caught. This value is in contrast to - ``Exception.cause_location``, which describes the source line - where the exception was thrown. - """, - # @@protoc_insertion_point(class_scope:google.devtools.clouderrorreporting.v1beta1.ErrorContext) - ), -) -_sym_db.RegisterMessage(ErrorContext) - -HttpRequestContext = _reflection.GeneratedProtocolMessageType( - "HttpRequestContext", - (_message.Message,), - dict( - DESCRIPTOR=_HTTPREQUESTCONTEXT, - __module__="google.devtools.clouderrorreporting_v1beta1.proto.common_pb2", - __doc__="""HTTP request data that is related to a reported error. This data should - be provided by the application when reporting an error, unless the error - report has been generated automatically from Google App Engine logs. - - - Attributes: - method: - The type of HTTP request, such as ``GET``, ``POST``, etc. - url: - The URL of the request. - user_agent: - The user agent information that is provided with the request. - referrer: - The referrer information that is provided with the request. - response_status_code: - The HTTP response status code for the request. - remote_ip: - The IP address from which the request originated. This can be - IPv4, IPv6, or a token which is derived from the IP address, - depending on the data that has been provided in the error - report. - """, - # @@protoc_insertion_point(class_scope:google.devtools.clouderrorreporting.v1beta1.HttpRequestContext) - ), -) -_sym_db.RegisterMessage(HttpRequestContext) - -SourceLocation = _reflection.GeneratedProtocolMessageType( - "SourceLocation", - (_message.Message,), - dict( - DESCRIPTOR=_SOURCELOCATION, - __module__="google.devtools.clouderrorreporting_v1beta1.proto.common_pb2", - __doc__="""Indicates a location in the source code of the service for which errors - are reported. This data should be provided by the application when - reporting an error, unless the error report has been generated - automatically from Google App Engine logs. All fields are optional. - - - Attributes: - file_path: - The source code filename, which can include a truncated - relative path, or a full path from a production machine. - line_number: - 1-based. 0 indicates that the line number is unknown. - function_name: - Human-readable name of a function or method. The value can - include optional context like the class or package name. For - example, ``my.package.MyClass.method`` in case of Java. - """, - # @@protoc_insertion_point(class_scope:google.devtools.clouderrorreporting.v1beta1.SourceLocation) - ), -) -_sym_db.RegisterMessage(SourceLocation) - - -DESCRIPTOR._options = None -# @@protoc_insertion_point(module_scope) diff --git a/google/cloud/errorreporting_v1beta1/proto/common_pb2_grpc.py b/google/cloud/errorreporting_v1beta1/proto/common_pb2_grpc.py deleted file mode 100644 index 07cb78fe..00000000 --- a/google/cloud/errorreporting_v1beta1/proto/common_pb2_grpc.py +++ /dev/null @@ -1,2 +0,0 @@ -# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! -import grpc diff --git a/google/cloud/errorreporting_v1beta1/proto/error_group_service.proto b/google/cloud/errorreporting_v1beta1/proto/error_group_service.proto index 15086a9e..18182729 100644 --- a/google/cloud/errorreporting_v1beta1/proto/error_group_service.proto +++ b/google/cloud/errorreporting_v1beta1/proto/error_group_service.proto @@ -1,4 +1,4 @@ -// Copyright 2016 Google Inc. +// Copyright 2019 Google LLC. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -11,28 +11,38 @@ // 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. +// syntax = "proto3"; package google.devtools.clouderrorreporting.v1beta1; import "google/api/annotations.proto"; +import "google/api/client.proto"; +import "google/api/field_behavior.proto"; +import "google/api/resource.proto"; import "google/devtools/clouderrorreporting/v1beta1/common.proto"; +option cc_enable_arenas = true; option csharp_namespace = "Google.Cloud.ErrorReporting.V1Beta1"; option go_package = "google.golang.org/genproto/googleapis/devtools/clouderrorreporting/v1beta1;clouderrorreporting"; option java_multiple_files = true; option java_outer_classname = "ErrorGroupServiceProto"; option java_package = "com.google.devtools.clouderrorreporting.v1beta1"; option php_namespace = "Google\\Cloud\\ErrorReporting\\V1beta1"; +option ruby_package = "Google::Cloud::ErrorReporting::V1beta1"; // Service for retrieving and updating individual error groups. service ErrorGroupService { + option (google.api.default_host) = "clouderrorreporting.googleapis.com"; + option (google.api.oauth_scopes) = "https://www.googleapis.com/auth/cloud-platform"; + // Get the specified group. rpc GetGroup(GetGroupRequest) returns (ErrorGroup) { option (google.api.http) = { get: "/v1beta1/{group_name=projects/*/groups/*}" }; + option (google.api.method_signature) = "group_name"; } // Replace the data for the specified group. @@ -42,24 +52,28 @@ service ErrorGroupService { put: "/v1beta1/{group.name=projects/*/groups/*}" body: "group" }; + option (google.api.method_signature) = "group"; } } // A request to return an individual group. message GetGroupRequest { - // [Required] The group resource name. Written as - // projects/projectID/groups/group_name. - // Call - // - // groupStats.list to return a list of groups belonging to - // this project. + // The group resource name. Written as + // `projects/{projectID}/groups/{group_name}`. Call + // [`groupStats.list`](https://cloud.google.com/error-reporting/reference/rest/v1beta1/projects.groupStats/list) + // to return a list of groups belonging to this project. // - // Example: projects/my-project-123/groups/my-group - string group_name = 1; + // Example: `projects/my-project-123/groups/my-group` + string group_name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "clouderrorreporting.googleapis.com/ErrorGroup" + } + ]; } // A request to replace the existing data for the given group. message UpdateGroupRequest { - // [Required] The group which replaces the resource on the server. - ErrorGroup group = 1; + // Required. The group which replaces the resource on the server. + ErrorGroup group = 1 [(google.api.field_behavior) = REQUIRED]; } diff --git a/google/cloud/errorreporting_v1beta1/proto/error_group_service_pb2.py b/google/cloud/errorreporting_v1beta1/proto/error_group_service_pb2.py deleted file mode 100644 index a6406ab0..00000000 --- a/google/cloud/errorreporting_v1beta1/proto/error_group_service_pb2.py +++ /dev/null @@ -1,207 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: google/devtools/clouderrorreporting_v1beta1/proto/error_group_service.proto - -import sys - -_b = sys.version_info[0] < 3 and (lambda x: x) or (lambda x: x.encode("latin1")) -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf import reflection as _reflection -from google.protobuf import symbol_database as _symbol_database - -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from google.api import annotations_pb2 as google_dot_api_dot_annotations__pb2 -from google.cloud.errorreporting_v1beta1.proto import ( - common_pb2 as google_dot_devtools_dot_clouderrorreporting__v1beta1_dot_proto_dot_common__pb2, -) - - -DESCRIPTOR = _descriptor.FileDescriptor( - name="google/devtools/clouderrorreporting_v1beta1/proto/error_group_service.proto", - package="google.devtools.clouderrorreporting.v1beta1", - syntax="proto3", - serialized_options=_b( - "\n/com.google.devtools.clouderrorreporting.v1beta1B\026ErrorGroupServiceProtoP\001Z^google.golang.org/genproto/googleapis/devtools/clouderrorreporting/v1beta1;clouderrorreporting\252\002#Google.Cloud.ErrorReporting.V1Beta1\312\002#Google\\Cloud\\ErrorReporting\\V1beta1" - ), - serialized_pb=_b( - '\nKgoogle/devtools/clouderrorreporting_v1beta1/proto/error_group_service.proto\x12+google.devtools.clouderrorreporting.v1beta1\x1a\x1cgoogle/api/annotations.proto\x1a>google/devtools/clouderrorreporting_v1beta1/proto/common.proto"%\n\x0fGetGroupRequest\x12\x12\n\ngroup_name\x18\x01 \x01(\t"\\\n\x12UpdateGroupRequest\x12\x46\n\x05group\x18\x01 \x01(\x0b\x32\x37.google.devtools.clouderrorreporting.v1beta1.ErrorGroup2\x8e\x03\n\x11\x45rrorGroupService\x12\xb4\x01\n\x08GetGroup\x12<.google.devtools.clouderrorreporting.v1beta1.GetGroupRequest\x1a\x37.google.devtools.clouderrorreporting.v1beta1.ErrorGroup"1\x82\xd3\xe4\x93\x02+\x12)/v1beta1/{group_name=projects/*/groups/*}\x12\xc1\x01\n\x0bUpdateGroup\x12?.google.devtools.clouderrorreporting.v1beta1.UpdateGroupRequest\x1a\x37.google.devtools.clouderrorreporting.v1beta1.ErrorGroup"8\x82\xd3\xe4\x93\x02\x32\x1a)/v1beta1/{group.name=projects/*/groups/*}:\x05groupB\xf7\x01\n/com.google.devtools.clouderrorreporting.v1beta1B\x16\x45rrorGroupServiceProtoP\x01Z^google.golang.org/genproto/googleapis/devtools/clouderrorreporting/v1beta1;clouderrorreporting\xaa\x02#Google.Cloud.ErrorReporting.V1Beta1\xca\x02#Google\\Cloud\\ErrorReporting\\V1beta1b\x06proto3' - ), - dependencies=[ - google_dot_api_dot_annotations__pb2.DESCRIPTOR, - google_dot_devtools_dot_clouderrorreporting__v1beta1_dot_proto_dot_common__pb2.DESCRIPTOR, - ], -) - - -_GETGROUPREQUEST = _descriptor.Descriptor( - name="GetGroupRequest", - full_name="google.devtools.clouderrorreporting.v1beta1.GetGroupRequest", - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name="group_name", - full_name="google.devtools.clouderrorreporting.v1beta1.GetGroupRequest.group_name", - index=0, - number=1, - type=9, - cpp_type=9, - label=1, - has_default_value=False, - default_value=_b("").decode("utf-8"), - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - ) - ], - extensions=[], - nested_types=[], - enum_types=[], - serialized_options=None, - is_extendable=False, - syntax="proto3", - extension_ranges=[], - oneofs=[], - serialized_start=218, - serialized_end=255, -) - - -_UPDATEGROUPREQUEST = _descriptor.Descriptor( - name="UpdateGroupRequest", - full_name="google.devtools.clouderrorreporting.v1beta1.UpdateGroupRequest", - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name="group", - full_name="google.devtools.clouderrorreporting.v1beta1.UpdateGroupRequest.group", - index=0, - number=1, - type=11, - cpp_type=10, - label=1, - has_default_value=False, - default_value=None, - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - ) - ], - extensions=[], - nested_types=[], - enum_types=[], - serialized_options=None, - is_extendable=False, - syntax="proto3", - extension_ranges=[], - oneofs=[], - serialized_start=257, - serialized_end=349, -) - -_UPDATEGROUPREQUEST.fields_by_name[ - "group" -].message_type = ( - google_dot_devtools_dot_clouderrorreporting__v1beta1_dot_proto_dot_common__pb2._ERRORGROUP -) -DESCRIPTOR.message_types_by_name["GetGroupRequest"] = _GETGROUPREQUEST -DESCRIPTOR.message_types_by_name["UpdateGroupRequest"] = _UPDATEGROUPREQUEST -_sym_db.RegisterFileDescriptor(DESCRIPTOR) - -GetGroupRequest = _reflection.GeneratedProtocolMessageType( - "GetGroupRequest", - (_message.Message,), - dict( - DESCRIPTOR=_GETGROUPREQUEST, - __module__="google.devtools.clouderrorreporting_v1beta1.proto.error_group_service_pb2", - __doc__="""A request to return an individual group. - - - Attributes: - group_name: - [Required] The group resource name. Written as - projects/projectID/groups/group\_name. Call groupStats.list to - return a list of groups belonging to this project. Example: - projects/my-project-123/groups/my-group - """, - # @@protoc_insertion_point(class_scope:google.devtools.clouderrorreporting.v1beta1.GetGroupRequest) - ), -) -_sym_db.RegisterMessage(GetGroupRequest) - -UpdateGroupRequest = _reflection.GeneratedProtocolMessageType( - "UpdateGroupRequest", - (_message.Message,), - dict( - DESCRIPTOR=_UPDATEGROUPREQUEST, - __module__="google.devtools.clouderrorreporting_v1beta1.proto.error_group_service_pb2", - __doc__="""A request to replace the existing data for the given group. - - - Attributes: - group: - [Required] The group which replaces the resource on the - server. - """, - # @@protoc_insertion_point(class_scope:google.devtools.clouderrorreporting.v1beta1.UpdateGroupRequest) - ), -) -_sym_db.RegisterMessage(UpdateGroupRequest) - - -DESCRIPTOR._options = None - -_ERRORGROUPSERVICE = _descriptor.ServiceDescriptor( - name="ErrorGroupService", - full_name="google.devtools.clouderrorreporting.v1beta1.ErrorGroupService", - file=DESCRIPTOR, - index=0, - serialized_options=None, - serialized_start=352, - serialized_end=750, - methods=[ - _descriptor.MethodDescriptor( - name="GetGroup", - full_name="google.devtools.clouderrorreporting.v1beta1.ErrorGroupService.GetGroup", - index=0, - containing_service=None, - input_type=_GETGROUPREQUEST, - output_type=google_dot_devtools_dot_clouderrorreporting__v1beta1_dot_proto_dot_common__pb2._ERRORGROUP, - serialized_options=_b( - "\202\323\344\223\002+\022)/v1beta1/{group_name=projects/*/groups/*}" - ), - ), - _descriptor.MethodDescriptor( - name="UpdateGroup", - full_name="google.devtools.clouderrorreporting.v1beta1.ErrorGroupService.UpdateGroup", - index=1, - containing_service=None, - input_type=_UPDATEGROUPREQUEST, - output_type=google_dot_devtools_dot_clouderrorreporting__v1beta1_dot_proto_dot_common__pb2._ERRORGROUP, - serialized_options=_b( - "\202\323\344\223\0022\032)/v1beta1/{group.name=projects/*/groups/*}:\005group" - ), - ), - ], -) -_sym_db.RegisterServiceDescriptor(_ERRORGROUPSERVICE) - -DESCRIPTOR.services_by_name["ErrorGroupService"] = _ERRORGROUPSERVICE - -# @@protoc_insertion_point(module_scope) diff --git a/google/cloud/errorreporting_v1beta1/proto/error_group_service_pb2_grpc.py b/google/cloud/errorreporting_v1beta1/proto/error_group_service_pb2_grpc.py deleted file mode 100644 index 3849772f..00000000 --- a/google/cloud/errorreporting_v1beta1/proto/error_group_service_pb2_grpc.py +++ /dev/null @@ -1,71 +0,0 @@ -# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! -import grpc - -from google.cloud.errorreporting_v1beta1.proto import ( - common_pb2 as google_dot_devtools_dot_clouderrorreporting__v1beta1_dot_proto_dot_common__pb2, -) -from google.cloud.errorreporting_v1beta1.proto import ( - error_group_service_pb2 as google_dot_devtools_dot_clouderrorreporting__v1beta1_dot_proto_dot_error__group__service__pb2, -) - - -class ErrorGroupServiceStub(object): - """Service for retrieving and updating individual error groups. - """ - - def __init__(self, channel): - """Constructor. - - Args: - channel: A grpc.Channel. - """ - self.GetGroup = channel.unary_unary( - "/google.devtools.clouderrorreporting.v1beta1.ErrorGroupService/GetGroup", - request_serializer=google_dot_devtools_dot_clouderrorreporting__v1beta1_dot_proto_dot_error__group__service__pb2.GetGroupRequest.SerializeToString, - response_deserializer=google_dot_devtools_dot_clouderrorreporting__v1beta1_dot_proto_dot_common__pb2.ErrorGroup.FromString, - ) - self.UpdateGroup = channel.unary_unary( - "/google.devtools.clouderrorreporting.v1beta1.ErrorGroupService/UpdateGroup", - request_serializer=google_dot_devtools_dot_clouderrorreporting__v1beta1_dot_proto_dot_error__group__service__pb2.UpdateGroupRequest.SerializeToString, - response_deserializer=google_dot_devtools_dot_clouderrorreporting__v1beta1_dot_proto_dot_common__pb2.ErrorGroup.FromString, - ) - - -class ErrorGroupServiceServicer(object): - """Service for retrieving and updating individual error groups. - """ - - def GetGroup(self, request, context): - """Get the specified group. - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details("Method not implemented!") - raise NotImplementedError("Method not implemented!") - - def UpdateGroup(self, request, context): - """Replace the data for the specified group. - Fails if the group does not exist. - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details("Method not implemented!") - raise NotImplementedError("Method not implemented!") - - -def add_ErrorGroupServiceServicer_to_server(servicer, server): - rpc_method_handlers = { - "GetGroup": grpc.unary_unary_rpc_method_handler( - servicer.GetGroup, - request_deserializer=google_dot_devtools_dot_clouderrorreporting__v1beta1_dot_proto_dot_error__group__service__pb2.GetGroupRequest.FromString, - response_serializer=google_dot_devtools_dot_clouderrorreporting__v1beta1_dot_proto_dot_common__pb2.ErrorGroup.SerializeToString, - ), - "UpdateGroup": grpc.unary_unary_rpc_method_handler( - servicer.UpdateGroup, - request_deserializer=google_dot_devtools_dot_clouderrorreporting__v1beta1_dot_proto_dot_error__group__service__pb2.UpdateGroupRequest.FromString, - response_serializer=google_dot_devtools_dot_clouderrorreporting__v1beta1_dot_proto_dot_common__pb2.ErrorGroup.SerializeToString, - ), - } - generic_handler = grpc.method_handlers_generic_handler( - "google.devtools.clouderrorreporting.v1beta1.ErrorGroupService", - rpc_method_handlers, - ) - server.add_generic_rpc_handlers((generic_handler,)) diff --git a/google/cloud/errorreporting_v1beta1/proto/error_stats_service.proto b/google/cloud/errorreporting_v1beta1/proto/error_stats_service.proto index ffb25b2b..0773f488 100644 --- a/google/cloud/errorreporting_v1beta1/proto/error_stats_service.proto +++ b/google/cloud/errorreporting_v1beta1/proto/error_stats_service.proto @@ -1,4 +1,4 @@ -// Copyright 2016 Google Inc. +// Copyright 2019 Google LLC. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -11,31 +11,41 @@ // 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. +// syntax = "proto3"; package google.devtools.clouderrorreporting.v1beta1; import "google/api/annotations.proto"; +import "google/api/client.proto"; +import "google/api/field_behavior.proto"; +import "google/api/resource.proto"; import "google/devtools/clouderrorreporting/v1beta1/common.proto"; import "google/protobuf/duration.proto"; import "google/protobuf/timestamp.proto"; +option cc_enable_arenas = true; option csharp_namespace = "Google.Cloud.ErrorReporting.V1Beta1"; option go_package = "google.golang.org/genproto/googleapis/devtools/clouderrorreporting/v1beta1;clouderrorreporting"; option java_multiple_files = true; option java_outer_classname = "ErrorStatsServiceProto"; option java_package = "com.google.devtools.clouderrorreporting.v1beta1"; option php_namespace = "Google\\Cloud\\ErrorReporting\\V1beta1"; +option ruby_package = "Google::Cloud::ErrorReporting::V1beta1"; // An API for retrieving and managing error statistics as well as data for // individual events. service ErrorStatsService { + option (google.api.default_host) = "clouderrorreporting.googleapis.com"; + option (google.api.oauth_scopes) = "https://www.googleapis.com/auth/cloud-platform"; + // Lists the specified groups. rpc ListGroupStats(ListGroupStatsRequest) returns (ListGroupStatsResponse) { option (google.api.http) = { get: "/v1beta1/{project_name=projects/*}/groupStats" }; + option (google.api.method_signature) = "project_name,time_range"; } // Lists the specified events. @@ -43,6 +53,7 @@ service ErrorStatsService { option (google.api.http) = { get: "/v1beta1/{project_name=projects/*}/events" }; + option (google.api.method_signature) = "project_name,group_id"; } // Deletes all error events of a given project. @@ -50,60 +61,67 @@ service ErrorStatsService { option (google.api.http) = { delete: "/v1beta1/{project_name=projects/*}/events" }; + option (google.api.method_signature) = "project_name"; } } // Specifies a set of `ErrorGroupStats` to return. message ListGroupStatsRequest { - // [Required] The resource name of the Google Cloud Platform project. Written + // Required. The resource name of the Google Cloud Platform project. Written // as projects/ plus the // Google Cloud // Platform project ID. // // Example: projects/my-project-123. - string project_name = 1; + string project_name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "cloudresourcemanager.googleapis.com/Project" + } + ]; - // [Optional] List all ErrorGroupStats with these IDs. - repeated string group_id = 2; + // Optional. List all ErrorGroupStats with these IDs. + repeated string group_id = 2 [(google.api.field_behavior) = OPTIONAL]; - // [Optional] List only ErrorGroupStats which belong to a service + // Optional. List only ErrorGroupStats which belong to a service // context that matches the filter. // Data for all service contexts is returned if this field is not specified. - ServiceContextFilter service_filter = 3; + ServiceContextFilter service_filter = 3 [(google.api.field_behavior) = OPTIONAL]; - // [Optional] List data for the given time range. - // If not set a default time range is used. The field time_range_begin - // in the response will specify the beginning of this time range. + // Optional. List data for the given time range. + // If not set, a default time range is used. The field + // time_range_begin in the response will specify the beginning + // of this time range. // Only ErrorGroupStats with a non-zero count in the given time - // range are returned, unless the request contains an explicit group_id list. - // If a group_id list is given, also ErrorGroupStats with zero - // occurrences are returned. - QueryTimeRange time_range = 5; + // range are returned, unless the request contains an explicit + // group_id list. If a group_id list is given, also + // ErrorGroupStats with zero occurrences are returned. + QueryTimeRange time_range = 5 [(google.api.field_behavior) = OPTIONAL]; - // [Optional] The preferred duration for a single returned `TimedCount`. + // Optional. The preferred duration for a single returned `TimedCount`. // If not set, no timed counts are returned. - google.protobuf.Duration timed_count_duration = 6; + google.protobuf.Duration timed_count_duration = 6 [(google.api.field_behavior) = OPTIONAL]; - // [Optional] The alignment of the timed counts to be returned. + // Optional. The alignment of the timed counts to be returned. // Default is `ALIGNMENT_EQUAL_AT_END`. - TimedCountAlignment alignment = 7; + TimedCountAlignment alignment = 7 [(google.api.field_behavior) = OPTIONAL]; - // [Optional] Time where the timed counts shall be aligned if rounded + // Optional. Time where the timed counts shall be aligned if rounded // alignment is chosen. Default is 00:00 UTC. - google.protobuf.Timestamp alignment_time = 8; + google.protobuf.Timestamp alignment_time = 8 [(google.api.field_behavior) = OPTIONAL]; - // [Optional] The sort order in which the results are returned. + // Optional. The sort order in which the results are returned. // Default is `COUNT_DESC`. - ErrorGroupOrder order = 9; + ErrorGroupOrder order = 9 [(google.api.field_behavior) = OPTIONAL]; - // [Optional] The maximum number of results to return per response. + // Optional. The maximum number of results to return per response. // Default is 20. - int32 page_size = 11; + int32 page_size = 11 [(google.api.field_behavior) = OPTIONAL]; - // [Optional] A `next_page_token` provided by a previous response. To view + // Optional. A `next_page_token` provided by a previous response. To view // additional results, pass this token along with the identical query // parameters as the first request. - string page_token = 12; + string page_token = 12 [(google.api.field_behavior) = OPTIONAL]; } // Contains a set of requested error group stats. @@ -196,33 +214,79 @@ message TimedCount { google.protobuf.Timestamp end_time = 3; } +// Specifies how the time periods of error group counts are aligned. +enum TimedCountAlignment { + // No alignment specified. + ERROR_COUNT_ALIGNMENT_UNSPECIFIED = 0; + + // The time periods shall be consecutive, have width equal to the + // requested duration, and be aligned at the `alignment_time` provided in + // the request. + // The `alignment_time` does not have to be inside the query period but + // even if it is outside, only time periods are returned which overlap + // with the query period. + // A rounded alignment will typically result in a + // different size of the first or the last time period. + ALIGNMENT_EQUAL_ROUNDED = 1; + + // The time periods shall be consecutive, have width equal to the + // requested duration, and be aligned at the end of the requested time + // period. This can result in a different size of the + // first time period. + ALIGNMENT_EQUAL_AT_END = 2; +} + +// A sorting order of error groups. +enum ErrorGroupOrder { + // No group order specified. + GROUP_ORDER_UNSPECIFIED = 0; + + // Total count of errors in the given time window in descending order. + COUNT_DESC = 1; + + // Timestamp when the group was last seen in the given time window + // in descending order. + LAST_SEEN_DESC = 2; + + // Timestamp when the group was created in descending order. + CREATED_DESC = 3; + + // Number of affected users in the given time window in descending order. + AFFECTED_USERS_DESC = 4; +} + // Specifies a set of error events to return. message ListEventsRequest { - // [Required] The resource name of the Google Cloud Platform project. Written + // Required. The resource name of the Google Cloud Platform project. Written // as `projects/` plus the // [Google Cloud Platform project // ID](https://support.google.com/cloud/answer/6158840). // Example: `projects/my-project-123`. - string project_name = 1; + string project_name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "cloudresourcemanager.googleapis.com/Project" + } + ]; - // [Required] The group for which events shall be returned. - string group_id = 2; + // Required. The group for which events shall be returned. + string group_id = 2 [(google.api.field_behavior) = REQUIRED]; - // [Optional] List only ErrorGroups which belong to a service context that + // Optional. List only ErrorGroups which belong to a service context that // matches the filter. // Data for all service contexts is returned if this field is not specified. - ServiceContextFilter service_filter = 3; + ServiceContextFilter service_filter = 3 [(google.api.field_behavior) = OPTIONAL]; - // [Optional] List only data for the given time range. + // Optional. List only data for the given time range. // If not set a default time range is used. The field time_range_begin // in the response will specify the beginning of this time range. - QueryTimeRange time_range = 4; + QueryTimeRange time_range = 4 [(google.api.field_behavior) = OPTIONAL]; - // [Optional] The maximum number of results to return per response. - int32 page_size = 6; + // Optional. The maximum number of results to return per response. + int32 page_size = 6 [(google.api.field_behavior) = OPTIONAL]; - // [Optional] A `next_page_token` provided by a previous response. - string page_token = 7; + // Optional. A `next_page_token` provided by a previous response. + string page_token = 7 [(google.api.field_behavior) = OPTIONAL]; } // Contains a set of requested error events. @@ -277,69 +341,35 @@ message QueryTimeRange { // Only exact, case-sensitive matches are supported. // If a field is unset or empty, it matches arbitrary values. message ServiceContextFilter { - // [Optional] The exact value to match against + // Optional. The exact value to match against // [`ServiceContext.service`](/error-reporting/reference/rest/v1beta1/ServiceContext#FIELDS.service). - string service = 2; + string service = 2 [(google.api.field_behavior) = OPTIONAL]; - // [Optional] The exact value to match against + // Optional. The exact value to match against // [`ServiceContext.version`](/error-reporting/reference/rest/v1beta1/ServiceContext#FIELDS.version). - string version = 3; + string version = 3 [(google.api.field_behavior) = OPTIONAL]; - // [Optional] The exact value to match against + // Optional. The exact value to match against // [`ServiceContext.resource_type`](/error-reporting/reference/rest/v1beta1/ServiceContext#FIELDS.resource_type). - string resource_type = 4; + string resource_type = 4 [(google.api.field_behavior) = OPTIONAL]; } // Deletes all events in the project. message DeleteEventsRequest { - // [Required] The resource name of the Google Cloud Platform project. Written + // Required. The resource name of the Google Cloud Platform project. Written // as `projects/` plus the // [Google Cloud Platform project // ID](https://support.google.com/cloud/answer/6158840). // Example: `projects/my-project-123`. - string project_name = 1; + string project_name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "cloudresourcemanager.googleapis.com/Project" + } + ]; } // Response message for deleting error events. -message DeleteEventsResponse {} - -// Specifies how the time periods of error group counts are aligned. -enum TimedCountAlignment { - // No alignment specified. - ERROR_COUNT_ALIGNMENT_UNSPECIFIED = 0; - - // The time periods shall be consecutive, have width equal to the - // requested duration, and be aligned at the `alignment_time` provided in - // the request. - // The `alignment_time` does not have to be inside the query period but - // even if it is outside, only time periods are returned which overlap - // with the query period. - // A rounded alignment will typically result in a - // different size of the first or the last time period. - ALIGNMENT_EQUAL_ROUNDED = 1; - - // The time periods shall be consecutive, have width equal to the - // requested duration, and be aligned at the end of the requested time - // period. This can result in a different size of the - // first time period. - ALIGNMENT_EQUAL_AT_END = 2; -} +message DeleteEventsResponse { -// A sorting order of error groups. -enum ErrorGroupOrder { - // No group order specified. - GROUP_ORDER_UNSPECIFIED = 0; - - // Total count of errors in the given time window in descending order. - COUNT_DESC = 1; - - // Timestamp when the group was last seen in the given time window - // in descending order. - LAST_SEEN_DESC = 2; - - // Timestamp when the group was created in descending order. - CREATED_DESC = 3; - - // Number of affected users in the given time window in descending order. - AFFECTED_USERS_DESC = 4; } diff --git a/google/cloud/errorreporting_v1beta1/proto/error_stats_service_pb2.py b/google/cloud/errorreporting_v1beta1/proto/error_stats_service_pb2.py deleted file mode 100644 index a8fe60bd..00000000 --- a/google/cloud/errorreporting_v1beta1/proto/error_stats_service_pb2.py +++ /dev/null @@ -1,1513 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: google/devtools/clouderrorreporting_v1beta1/proto/error_stats_service.proto - -import sys - -_b = sys.version_info[0] < 3 and (lambda x: x) or (lambda x: x.encode("latin1")) -from google.protobuf.internal import enum_type_wrapper -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf import reflection as _reflection -from google.protobuf import symbol_database as _symbol_database - -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from google.api import annotations_pb2 as google_dot_api_dot_annotations__pb2 -from google.cloud.errorreporting_v1beta1.proto import ( - common_pb2 as google_dot_devtools_dot_clouderrorreporting__v1beta1_dot_proto_dot_common__pb2, -) -from google.protobuf import duration_pb2 as google_dot_protobuf_dot_duration__pb2 -from google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__pb2 - - -DESCRIPTOR = _descriptor.FileDescriptor( - name="google/devtools/clouderrorreporting_v1beta1/proto/error_stats_service.proto", - package="google.devtools.clouderrorreporting.v1beta1", - syntax="proto3", - serialized_options=_b( - "\n/com.google.devtools.clouderrorreporting.v1beta1B\026ErrorStatsServiceProtoP\001Z^google.golang.org/genproto/googleapis/devtools/clouderrorreporting/v1beta1;clouderrorreporting\252\002#Google.Cloud.ErrorReporting.V1Beta1\312\002#Google\\Cloud\\ErrorReporting\\V1beta1" - ), - serialized_pb=_b( - '\nKgoogle/devtools/clouderrorreporting_v1beta1/proto/error_stats_service.proto\x12+google.devtools.clouderrorreporting.v1beta1\x1a\x1cgoogle/api/annotations.proto\x1a>google/devtools/clouderrorreporting_v1beta1/proto/common.proto\x1a\x1egoogle/protobuf/duration.proto\x1a\x1fgoogle/protobuf/timestamp.proto"\xa1\x04\n\x15ListGroupStatsRequest\x12\x14\n\x0cproject_name\x18\x01 \x01(\t\x12\x10\n\x08group_id\x18\x02 \x03(\t\x12Y\n\x0eservice_filter\x18\x03 \x01(\x0b\x32\x41.google.devtools.clouderrorreporting.v1beta1.ServiceContextFilter\x12O\n\ntime_range\x18\x05 \x01(\x0b\x32;.google.devtools.clouderrorreporting.v1beta1.QueryTimeRange\x12\x37\n\x14timed_count_duration\x18\x06 \x01(\x0b\x32\x19.google.protobuf.Duration\x12S\n\talignment\x18\x07 \x01(\x0e\x32@.google.devtools.clouderrorreporting.v1beta1.TimedCountAlignment\x12\x32\n\x0e\x61lignment_time\x18\x08 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12K\n\x05order\x18\t \x01(\x0e\x32<.google.devtools.clouderrorreporting.v1beta1.ErrorGroupOrder\x12\x11\n\tpage_size\x18\x0b \x01(\x05\x12\x12\n\npage_token\x18\x0c \x01(\t"\xc0\x01\n\x16ListGroupStatsResponse\x12W\n\x11\x65rror_group_stats\x18\x01 \x03(\x0b\x32<.google.devtools.clouderrorreporting.v1beta1.ErrorGroupStats\x12\x17\n\x0fnext_page_token\x18\x02 \x01(\t\x12\x34\n\x10time_range_begin\x18\x04 \x01(\x0b\x32\x1a.google.protobuf.Timestamp"\x86\x04\n\x0f\x45rrorGroupStats\x12\x46\n\x05group\x18\x01 \x01(\x0b\x32\x37.google.devtools.clouderrorreporting.v1beta1.ErrorGroup\x12\r\n\x05\x63ount\x18\x02 \x01(\x03\x12\x1c\n\x14\x61\x66\x66\x65\x63ted_users_count\x18\x03 \x01(\x03\x12M\n\x0ctimed_counts\x18\x04 \x03(\x0b\x32\x37.google.devtools.clouderrorreporting.v1beta1.TimedCount\x12\x33\n\x0f\x66irst_seen_time\x18\x05 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x32\n\x0elast_seen_time\x18\x06 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12V\n\x11\x61\x66\x66\x65\x63ted_services\x18\x07 \x03(\x0b\x32;.google.devtools.clouderrorreporting.v1beta1.ServiceContext\x12\x1d\n\x15num_affected_services\x18\x08 \x01(\x05\x12O\n\x0erepresentative\x18\t \x01(\x0b\x32\x37.google.devtools.clouderrorreporting.v1beta1.ErrorEvent"y\n\nTimedCount\x12\r\n\x05\x63ount\x18\x01 \x01(\x03\x12.\n\nstart_time\x18\x02 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12,\n\x08\x65nd_time\x18\x03 \x01(\x0b\x32\x1a.google.protobuf.Timestamp"\x8e\x02\n\x11ListEventsRequest\x12\x14\n\x0cproject_name\x18\x01 \x01(\t\x12\x10\n\x08group_id\x18\x02 \x01(\t\x12Y\n\x0eservice_filter\x18\x03 \x01(\x0b\x32\x41.google.devtools.clouderrorreporting.v1beta1.ServiceContextFilter\x12O\n\ntime_range\x18\x04 \x01(\x0b\x32;.google.devtools.clouderrorreporting.v1beta1.QueryTimeRange\x12\x11\n\tpage_size\x18\x06 \x01(\x05\x12\x12\n\npage_token\x18\x07 \x01(\t"\xb2\x01\n\x12ListEventsResponse\x12M\n\x0c\x65rror_events\x18\x01 \x03(\x0b\x32\x37.google.devtools.clouderrorreporting.v1beta1.ErrorEvent\x12\x17\n\x0fnext_page_token\x18\x02 \x01(\t\x12\x34\n\x10time_range_begin\x18\x04 \x01(\x0b\x32\x1a.google.protobuf.Timestamp"\xe7\x01\n\x0eQueryTimeRange\x12R\n\x06period\x18\x01 \x01(\x0e\x32\x42.google.devtools.clouderrorreporting.v1beta1.QueryTimeRange.Period"\x80\x01\n\x06Period\x12\x16\n\x12PERIOD_UNSPECIFIED\x10\x00\x12\x11\n\rPERIOD_1_HOUR\x10\x01\x12\x12\n\x0ePERIOD_6_HOURS\x10\x02\x12\x10\n\x0cPERIOD_1_DAY\x10\x03\x12\x11\n\rPERIOD_1_WEEK\x10\x04\x12\x12\n\x0ePERIOD_30_DAYS\x10\x05"O\n\x14ServiceContextFilter\x12\x0f\n\x07service\x18\x02 \x01(\t\x12\x0f\n\x07version\x18\x03 \x01(\t\x12\x15\n\rresource_type\x18\x04 \x01(\t"+\n\x13\x44\x65leteEventsRequest\x12\x14\n\x0cproject_name\x18\x01 \x01(\t"\x16\n\x14\x44\x65leteEventsResponse*u\n\x13TimedCountAlignment\x12%\n!ERROR_COUNT_ALIGNMENT_UNSPECIFIED\x10\x00\x12\x1b\n\x17\x41LIGNMENT_EQUAL_ROUNDED\x10\x01\x12\x1a\n\x16\x41LIGNMENT_EQUAL_AT_END\x10\x02*}\n\x0f\x45rrorGroupOrder\x12\x1b\n\x17GROUP_ORDER_UNSPECIFIED\x10\x00\x12\x0e\n\nCOUNT_DESC\x10\x01\x12\x12\n\x0eLAST_SEEN_DESC\x10\x02\x12\x10\n\x0c\x43REATED_DESC\x10\x03\x12\x17\n\x13\x41\x46\x46\x45\x43TED_USERS_DESC\x10\x04\x32\xf2\x04\n\x11\x45rrorStatsService\x12\xd0\x01\n\x0eListGroupStats\x12\x42.google.devtools.clouderrorreporting.v1beta1.ListGroupStatsRequest\x1a\x43.google.devtools.clouderrorreporting.v1beta1.ListGroupStatsResponse"5\x82\xd3\xe4\x93\x02/\x12-/v1beta1/{project_name=projects/*}/groupStats\x12\xc0\x01\n\nListEvents\x12>.google.devtools.clouderrorreporting.v1beta1.ListEventsRequest\x1a?.google.devtools.clouderrorreporting.v1beta1.ListEventsResponse"1\x82\xd3\xe4\x93\x02+\x12)/v1beta1/{project_name=projects/*}/events\x12\xc6\x01\n\x0c\x44\x65leteEvents\x12@.google.devtools.clouderrorreporting.v1beta1.DeleteEventsRequest\x1a\x41.google.devtools.clouderrorreporting.v1beta1.DeleteEventsResponse"1\x82\xd3\xe4\x93\x02+*)/v1beta1/{project_name=projects/*}/eventsB\xf7\x01\n/com.google.devtools.clouderrorreporting.v1beta1B\x16\x45rrorStatsServiceProtoP\x01Z^google.golang.org/genproto/googleapis/devtools/clouderrorreporting/v1beta1;clouderrorreporting\xaa\x02#Google.Cloud.ErrorReporting.V1Beta1\xca\x02#Google\\Cloud\\ErrorReporting\\V1beta1b\x06proto3' - ), - dependencies=[ - google_dot_api_dot_annotations__pb2.DESCRIPTOR, - google_dot_devtools_dot_clouderrorreporting__v1beta1_dot_proto_dot_common__pb2.DESCRIPTOR, - google_dot_protobuf_dot_duration__pb2.DESCRIPTOR, - google_dot_protobuf_dot_timestamp__pb2.DESCRIPTOR, - ], -) - -_TIMEDCOUNTALIGNMENT = _descriptor.EnumDescriptor( - name="TimedCountAlignment", - full_name="google.devtools.clouderrorreporting.v1beta1.TimedCountAlignment", - filename=None, - file=DESCRIPTOR, - values=[ - _descriptor.EnumValueDescriptor( - name="ERROR_COUNT_ALIGNMENT_UNSPECIFIED", - index=0, - number=0, - serialized_options=None, - type=None, - ), - _descriptor.EnumValueDescriptor( - name="ALIGNMENT_EQUAL_ROUNDED", - index=1, - number=1, - serialized_options=None, - type=None, - ), - _descriptor.EnumValueDescriptor( - name="ALIGNMENT_EQUAL_AT_END", - index=2, - number=2, - serialized_options=None, - type=None, - ), - ], - containing_type=None, - serialized_options=None, - serialized_start=2508, - serialized_end=2625, -) -_sym_db.RegisterEnumDescriptor(_TIMEDCOUNTALIGNMENT) - -TimedCountAlignment = enum_type_wrapper.EnumTypeWrapper(_TIMEDCOUNTALIGNMENT) -_ERRORGROUPORDER = _descriptor.EnumDescriptor( - name="ErrorGroupOrder", - full_name="google.devtools.clouderrorreporting.v1beta1.ErrorGroupOrder", - filename=None, - file=DESCRIPTOR, - values=[ - _descriptor.EnumValueDescriptor( - name="GROUP_ORDER_UNSPECIFIED", - index=0, - number=0, - serialized_options=None, - type=None, - ), - _descriptor.EnumValueDescriptor( - name="COUNT_DESC", index=1, number=1, serialized_options=None, type=None - ), - _descriptor.EnumValueDescriptor( - name="LAST_SEEN_DESC", index=2, number=2, serialized_options=None, type=None - ), - _descriptor.EnumValueDescriptor( - name="CREATED_DESC", index=3, number=3, serialized_options=None, type=None - ), - _descriptor.EnumValueDescriptor( - name="AFFECTED_USERS_DESC", - index=4, - number=4, - serialized_options=None, - type=None, - ), - ], - containing_type=None, - serialized_options=None, - serialized_start=2627, - serialized_end=2752, -) -_sym_db.RegisterEnumDescriptor(_ERRORGROUPORDER) - -ErrorGroupOrder = enum_type_wrapper.EnumTypeWrapper(_ERRORGROUPORDER) -ERROR_COUNT_ALIGNMENT_UNSPECIFIED = 0 -ALIGNMENT_EQUAL_ROUNDED = 1 -ALIGNMENT_EQUAL_AT_END = 2 -GROUP_ORDER_UNSPECIFIED = 0 -COUNT_DESC = 1 -LAST_SEEN_DESC = 2 -CREATED_DESC = 3 -AFFECTED_USERS_DESC = 4 - - -_QUERYTIMERANGE_PERIOD = _descriptor.EnumDescriptor( - name="Period", - full_name="google.devtools.clouderrorreporting.v1beta1.QueryTimeRange.Period", - filename=None, - file=DESCRIPTOR, - values=[ - _descriptor.EnumValueDescriptor( - name="PERIOD_UNSPECIFIED", - index=0, - number=0, - serialized_options=None, - type=None, - ), - _descriptor.EnumValueDescriptor( - name="PERIOD_1_HOUR", index=1, number=1, serialized_options=None, type=None - ), - _descriptor.EnumValueDescriptor( - name="PERIOD_6_HOURS", index=2, number=2, serialized_options=None, type=None - ), - _descriptor.EnumValueDescriptor( - name="PERIOD_1_DAY", index=3, number=3, serialized_options=None, type=None - ), - _descriptor.EnumValueDescriptor( - name="PERIOD_1_WEEK", index=4, number=4, serialized_options=None, type=None - ), - _descriptor.EnumValueDescriptor( - name="PERIOD_30_DAYS", index=5, number=5, serialized_options=None, type=None - ), - ], - containing_type=None, - serialized_options=None, - serialized_start=2228, - serialized_end=2356, -) -_sym_db.RegisterEnumDescriptor(_QUERYTIMERANGE_PERIOD) - - -_LISTGROUPSTATSREQUEST = _descriptor.Descriptor( - name="ListGroupStatsRequest", - full_name="google.devtools.clouderrorreporting.v1beta1.ListGroupStatsRequest", - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name="project_name", - full_name="google.devtools.clouderrorreporting.v1beta1.ListGroupStatsRequest.project_name", - index=0, - number=1, - type=9, - cpp_type=9, - label=1, - has_default_value=False, - default_value=_b("").decode("utf-8"), - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - ), - _descriptor.FieldDescriptor( - name="group_id", - full_name="google.devtools.clouderrorreporting.v1beta1.ListGroupStatsRequest.group_id", - index=1, - number=2, - type=9, - cpp_type=9, - label=3, - has_default_value=False, - default_value=[], - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - ), - _descriptor.FieldDescriptor( - name="service_filter", - full_name="google.devtools.clouderrorreporting.v1beta1.ListGroupStatsRequest.service_filter", - index=2, - number=3, - type=11, - cpp_type=10, - label=1, - has_default_value=False, - default_value=None, - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - ), - _descriptor.FieldDescriptor( - name="time_range", - full_name="google.devtools.clouderrorreporting.v1beta1.ListGroupStatsRequest.time_range", - index=3, - number=5, - type=11, - cpp_type=10, - label=1, - has_default_value=False, - default_value=None, - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - ), - _descriptor.FieldDescriptor( - name="timed_count_duration", - full_name="google.devtools.clouderrorreporting.v1beta1.ListGroupStatsRequest.timed_count_duration", - index=4, - number=6, - type=11, - cpp_type=10, - label=1, - has_default_value=False, - default_value=None, - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - ), - _descriptor.FieldDescriptor( - name="alignment", - full_name="google.devtools.clouderrorreporting.v1beta1.ListGroupStatsRequest.alignment", - index=5, - number=7, - type=14, - cpp_type=8, - label=1, - has_default_value=False, - default_value=0, - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - ), - _descriptor.FieldDescriptor( - name="alignment_time", - full_name="google.devtools.clouderrorreporting.v1beta1.ListGroupStatsRequest.alignment_time", - index=6, - number=8, - type=11, - cpp_type=10, - label=1, - has_default_value=False, - default_value=None, - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - ), - _descriptor.FieldDescriptor( - name="order", - full_name="google.devtools.clouderrorreporting.v1beta1.ListGroupStatsRequest.order", - index=7, - number=9, - type=14, - cpp_type=8, - label=1, - has_default_value=False, - default_value=0, - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - ), - _descriptor.FieldDescriptor( - name="page_size", - full_name="google.devtools.clouderrorreporting.v1beta1.ListGroupStatsRequest.page_size", - index=8, - number=11, - type=5, - cpp_type=1, - label=1, - has_default_value=False, - default_value=0, - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - ), - _descriptor.FieldDescriptor( - name="page_token", - full_name="google.devtools.clouderrorreporting.v1beta1.ListGroupStatsRequest.page_token", - index=9, - number=12, - type=9, - cpp_type=9, - label=1, - has_default_value=False, - default_value=_b("").decode("utf-8"), - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - ), - ], - extensions=[], - nested_types=[], - enum_types=[], - serialized_options=None, - is_extendable=False, - syntax="proto3", - extension_ranges=[], - oneofs=[], - serialized_start=284, - serialized_end=829, -) - - -_LISTGROUPSTATSRESPONSE = _descriptor.Descriptor( - name="ListGroupStatsResponse", - full_name="google.devtools.clouderrorreporting.v1beta1.ListGroupStatsResponse", - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name="error_group_stats", - full_name="google.devtools.clouderrorreporting.v1beta1.ListGroupStatsResponse.error_group_stats", - index=0, - number=1, - type=11, - cpp_type=10, - label=3, - has_default_value=False, - default_value=[], - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - ), - _descriptor.FieldDescriptor( - name="next_page_token", - full_name="google.devtools.clouderrorreporting.v1beta1.ListGroupStatsResponse.next_page_token", - index=1, - number=2, - type=9, - cpp_type=9, - label=1, - has_default_value=False, - default_value=_b("").decode("utf-8"), - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - ), - _descriptor.FieldDescriptor( - name="time_range_begin", - full_name="google.devtools.clouderrorreporting.v1beta1.ListGroupStatsResponse.time_range_begin", - index=2, - number=4, - type=11, - cpp_type=10, - label=1, - has_default_value=False, - default_value=None, - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - ), - ], - extensions=[], - nested_types=[], - enum_types=[], - serialized_options=None, - is_extendable=False, - syntax="proto3", - extension_ranges=[], - oneofs=[], - serialized_start=832, - serialized_end=1024, -) - - -_ERRORGROUPSTATS = _descriptor.Descriptor( - name="ErrorGroupStats", - full_name="google.devtools.clouderrorreporting.v1beta1.ErrorGroupStats", - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name="group", - full_name="google.devtools.clouderrorreporting.v1beta1.ErrorGroupStats.group", - index=0, - number=1, - type=11, - cpp_type=10, - label=1, - has_default_value=False, - default_value=None, - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - ), - _descriptor.FieldDescriptor( - name="count", - full_name="google.devtools.clouderrorreporting.v1beta1.ErrorGroupStats.count", - index=1, - number=2, - type=3, - cpp_type=2, - label=1, - has_default_value=False, - default_value=0, - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - ), - _descriptor.FieldDescriptor( - name="affected_users_count", - full_name="google.devtools.clouderrorreporting.v1beta1.ErrorGroupStats.affected_users_count", - index=2, - number=3, - type=3, - cpp_type=2, - label=1, - has_default_value=False, - default_value=0, - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - ), - _descriptor.FieldDescriptor( - name="timed_counts", - full_name="google.devtools.clouderrorreporting.v1beta1.ErrorGroupStats.timed_counts", - index=3, - number=4, - type=11, - cpp_type=10, - label=3, - has_default_value=False, - default_value=[], - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - ), - _descriptor.FieldDescriptor( - name="first_seen_time", - full_name="google.devtools.clouderrorreporting.v1beta1.ErrorGroupStats.first_seen_time", - index=4, - number=5, - type=11, - cpp_type=10, - label=1, - has_default_value=False, - default_value=None, - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - ), - _descriptor.FieldDescriptor( - name="last_seen_time", - full_name="google.devtools.clouderrorreporting.v1beta1.ErrorGroupStats.last_seen_time", - index=5, - number=6, - type=11, - cpp_type=10, - label=1, - has_default_value=False, - default_value=None, - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - ), - _descriptor.FieldDescriptor( - name="affected_services", - full_name="google.devtools.clouderrorreporting.v1beta1.ErrorGroupStats.affected_services", - index=6, - number=7, - type=11, - cpp_type=10, - label=3, - has_default_value=False, - default_value=[], - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - ), - _descriptor.FieldDescriptor( - name="num_affected_services", - full_name="google.devtools.clouderrorreporting.v1beta1.ErrorGroupStats.num_affected_services", - index=7, - number=8, - type=5, - cpp_type=1, - label=1, - has_default_value=False, - default_value=0, - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - ), - _descriptor.FieldDescriptor( - name="representative", - full_name="google.devtools.clouderrorreporting.v1beta1.ErrorGroupStats.representative", - index=8, - number=9, - type=11, - cpp_type=10, - label=1, - has_default_value=False, - default_value=None, - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - ), - ], - extensions=[], - nested_types=[], - enum_types=[], - serialized_options=None, - is_extendable=False, - syntax="proto3", - extension_ranges=[], - oneofs=[], - serialized_start=1027, - serialized_end=1545, -) - - -_TIMEDCOUNT = _descriptor.Descriptor( - name="TimedCount", - full_name="google.devtools.clouderrorreporting.v1beta1.TimedCount", - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name="count", - full_name="google.devtools.clouderrorreporting.v1beta1.TimedCount.count", - index=0, - number=1, - type=3, - cpp_type=2, - label=1, - has_default_value=False, - default_value=0, - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - ), - _descriptor.FieldDescriptor( - name="start_time", - full_name="google.devtools.clouderrorreporting.v1beta1.TimedCount.start_time", - index=1, - number=2, - type=11, - cpp_type=10, - label=1, - has_default_value=False, - default_value=None, - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - ), - _descriptor.FieldDescriptor( - name="end_time", - full_name="google.devtools.clouderrorreporting.v1beta1.TimedCount.end_time", - index=2, - number=3, - type=11, - cpp_type=10, - label=1, - has_default_value=False, - default_value=None, - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - ), - ], - extensions=[], - nested_types=[], - enum_types=[], - serialized_options=None, - is_extendable=False, - syntax="proto3", - extension_ranges=[], - oneofs=[], - serialized_start=1547, - serialized_end=1668, -) - - -_LISTEVENTSREQUEST = _descriptor.Descriptor( - name="ListEventsRequest", - full_name="google.devtools.clouderrorreporting.v1beta1.ListEventsRequest", - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name="project_name", - full_name="google.devtools.clouderrorreporting.v1beta1.ListEventsRequest.project_name", - index=0, - number=1, - type=9, - cpp_type=9, - label=1, - has_default_value=False, - default_value=_b("").decode("utf-8"), - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - ), - _descriptor.FieldDescriptor( - name="group_id", - full_name="google.devtools.clouderrorreporting.v1beta1.ListEventsRequest.group_id", - index=1, - number=2, - type=9, - cpp_type=9, - label=1, - has_default_value=False, - default_value=_b("").decode("utf-8"), - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - ), - _descriptor.FieldDescriptor( - name="service_filter", - full_name="google.devtools.clouderrorreporting.v1beta1.ListEventsRequest.service_filter", - index=2, - number=3, - type=11, - cpp_type=10, - label=1, - has_default_value=False, - default_value=None, - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - ), - _descriptor.FieldDescriptor( - name="time_range", - full_name="google.devtools.clouderrorreporting.v1beta1.ListEventsRequest.time_range", - index=3, - number=4, - type=11, - cpp_type=10, - label=1, - has_default_value=False, - default_value=None, - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - ), - _descriptor.FieldDescriptor( - name="page_size", - full_name="google.devtools.clouderrorreporting.v1beta1.ListEventsRequest.page_size", - index=4, - number=6, - type=5, - cpp_type=1, - label=1, - has_default_value=False, - default_value=0, - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - ), - _descriptor.FieldDescriptor( - name="page_token", - full_name="google.devtools.clouderrorreporting.v1beta1.ListEventsRequest.page_token", - index=5, - number=7, - type=9, - cpp_type=9, - label=1, - has_default_value=False, - default_value=_b("").decode("utf-8"), - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - ), - ], - extensions=[], - nested_types=[], - enum_types=[], - serialized_options=None, - is_extendable=False, - syntax="proto3", - extension_ranges=[], - oneofs=[], - serialized_start=1671, - serialized_end=1941, -) - - -_LISTEVENTSRESPONSE = _descriptor.Descriptor( - name="ListEventsResponse", - full_name="google.devtools.clouderrorreporting.v1beta1.ListEventsResponse", - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name="error_events", - full_name="google.devtools.clouderrorreporting.v1beta1.ListEventsResponse.error_events", - index=0, - number=1, - type=11, - cpp_type=10, - label=3, - has_default_value=False, - default_value=[], - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - ), - _descriptor.FieldDescriptor( - name="next_page_token", - full_name="google.devtools.clouderrorreporting.v1beta1.ListEventsResponse.next_page_token", - index=1, - number=2, - type=9, - cpp_type=9, - label=1, - has_default_value=False, - default_value=_b("").decode("utf-8"), - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - ), - _descriptor.FieldDescriptor( - name="time_range_begin", - full_name="google.devtools.clouderrorreporting.v1beta1.ListEventsResponse.time_range_begin", - index=2, - number=4, - type=11, - cpp_type=10, - label=1, - has_default_value=False, - default_value=None, - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - ), - ], - extensions=[], - nested_types=[], - enum_types=[], - serialized_options=None, - is_extendable=False, - syntax="proto3", - extension_ranges=[], - oneofs=[], - serialized_start=1944, - serialized_end=2122, -) - - -_QUERYTIMERANGE = _descriptor.Descriptor( - name="QueryTimeRange", - full_name="google.devtools.clouderrorreporting.v1beta1.QueryTimeRange", - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name="period", - full_name="google.devtools.clouderrorreporting.v1beta1.QueryTimeRange.period", - index=0, - number=1, - type=14, - cpp_type=8, - label=1, - has_default_value=False, - default_value=0, - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - ) - ], - extensions=[], - nested_types=[], - enum_types=[_QUERYTIMERANGE_PERIOD], - serialized_options=None, - is_extendable=False, - syntax="proto3", - extension_ranges=[], - oneofs=[], - serialized_start=2125, - serialized_end=2356, -) - - -_SERVICECONTEXTFILTER = _descriptor.Descriptor( - name="ServiceContextFilter", - full_name="google.devtools.clouderrorreporting.v1beta1.ServiceContextFilter", - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name="service", - full_name="google.devtools.clouderrorreporting.v1beta1.ServiceContextFilter.service", - index=0, - number=2, - type=9, - cpp_type=9, - label=1, - has_default_value=False, - default_value=_b("").decode("utf-8"), - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - ), - _descriptor.FieldDescriptor( - name="version", - full_name="google.devtools.clouderrorreporting.v1beta1.ServiceContextFilter.version", - index=1, - number=3, - type=9, - cpp_type=9, - label=1, - has_default_value=False, - default_value=_b("").decode("utf-8"), - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - ), - _descriptor.FieldDescriptor( - name="resource_type", - full_name="google.devtools.clouderrorreporting.v1beta1.ServiceContextFilter.resource_type", - index=2, - number=4, - type=9, - cpp_type=9, - label=1, - has_default_value=False, - default_value=_b("").decode("utf-8"), - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - ), - ], - extensions=[], - nested_types=[], - enum_types=[], - serialized_options=None, - is_extendable=False, - syntax="proto3", - extension_ranges=[], - oneofs=[], - serialized_start=2358, - serialized_end=2437, -) - - -_DELETEEVENTSREQUEST = _descriptor.Descriptor( - name="DeleteEventsRequest", - full_name="google.devtools.clouderrorreporting.v1beta1.DeleteEventsRequest", - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name="project_name", - full_name="google.devtools.clouderrorreporting.v1beta1.DeleteEventsRequest.project_name", - index=0, - number=1, - type=9, - cpp_type=9, - label=1, - has_default_value=False, - default_value=_b("").decode("utf-8"), - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - ) - ], - extensions=[], - nested_types=[], - enum_types=[], - serialized_options=None, - is_extendable=False, - syntax="proto3", - extension_ranges=[], - oneofs=[], - serialized_start=2439, - serialized_end=2482, -) - - -_DELETEEVENTSRESPONSE = _descriptor.Descriptor( - name="DeleteEventsResponse", - full_name="google.devtools.clouderrorreporting.v1beta1.DeleteEventsResponse", - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[], - extensions=[], - nested_types=[], - enum_types=[], - serialized_options=None, - is_extendable=False, - syntax="proto3", - extension_ranges=[], - oneofs=[], - serialized_start=2484, - serialized_end=2506, -) - -_LISTGROUPSTATSREQUEST.fields_by_name[ - "service_filter" -].message_type = _SERVICECONTEXTFILTER -_LISTGROUPSTATSREQUEST.fields_by_name["time_range"].message_type = _QUERYTIMERANGE -_LISTGROUPSTATSREQUEST.fields_by_name[ - "timed_count_duration" -].message_type = google_dot_protobuf_dot_duration__pb2._DURATION -_LISTGROUPSTATSREQUEST.fields_by_name["alignment"].enum_type = _TIMEDCOUNTALIGNMENT -_LISTGROUPSTATSREQUEST.fields_by_name[ - "alignment_time" -].message_type = google_dot_protobuf_dot_timestamp__pb2._TIMESTAMP -_LISTGROUPSTATSREQUEST.fields_by_name["order"].enum_type = _ERRORGROUPORDER -_LISTGROUPSTATSRESPONSE.fields_by_name[ - "error_group_stats" -].message_type = _ERRORGROUPSTATS -_LISTGROUPSTATSRESPONSE.fields_by_name[ - "time_range_begin" -].message_type = google_dot_protobuf_dot_timestamp__pb2._TIMESTAMP -_ERRORGROUPSTATS.fields_by_name[ - "group" -].message_type = ( - google_dot_devtools_dot_clouderrorreporting__v1beta1_dot_proto_dot_common__pb2._ERRORGROUP -) -_ERRORGROUPSTATS.fields_by_name["timed_counts"].message_type = _TIMEDCOUNT -_ERRORGROUPSTATS.fields_by_name[ - "first_seen_time" -].message_type = google_dot_protobuf_dot_timestamp__pb2._TIMESTAMP -_ERRORGROUPSTATS.fields_by_name[ - "last_seen_time" -].message_type = google_dot_protobuf_dot_timestamp__pb2._TIMESTAMP -_ERRORGROUPSTATS.fields_by_name[ - "affected_services" -].message_type = ( - google_dot_devtools_dot_clouderrorreporting__v1beta1_dot_proto_dot_common__pb2._SERVICECONTEXT -) -_ERRORGROUPSTATS.fields_by_name[ - "representative" -].message_type = ( - google_dot_devtools_dot_clouderrorreporting__v1beta1_dot_proto_dot_common__pb2._ERROREVENT -) -_TIMEDCOUNT.fields_by_name[ - "start_time" -].message_type = google_dot_protobuf_dot_timestamp__pb2._TIMESTAMP -_TIMEDCOUNT.fields_by_name[ - "end_time" -].message_type = google_dot_protobuf_dot_timestamp__pb2._TIMESTAMP -_LISTEVENTSREQUEST.fields_by_name["service_filter"].message_type = _SERVICECONTEXTFILTER -_LISTEVENTSREQUEST.fields_by_name["time_range"].message_type = _QUERYTIMERANGE -_LISTEVENTSRESPONSE.fields_by_name[ - "error_events" -].message_type = ( - google_dot_devtools_dot_clouderrorreporting__v1beta1_dot_proto_dot_common__pb2._ERROREVENT -) -_LISTEVENTSRESPONSE.fields_by_name[ - "time_range_begin" -].message_type = google_dot_protobuf_dot_timestamp__pb2._TIMESTAMP -_QUERYTIMERANGE.fields_by_name["period"].enum_type = _QUERYTIMERANGE_PERIOD -_QUERYTIMERANGE_PERIOD.containing_type = _QUERYTIMERANGE -DESCRIPTOR.message_types_by_name["ListGroupStatsRequest"] = _LISTGROUPSTATSREQUEST -DESCRIPTOR.message_types_by_name["ListGroupStatsResponse"] = _LISTGROUPSTATSRESPONSE -DESCRIPTOR.message_types_by_name["ErrorGroupStats"] = _ERRORGROUPSTATS -DESCRIPTOR.message_types_by_name["TimedCount"] = _TIMEDCOUNT -DESCRIPTOR.message_types_by_name["ListEventsRequest"] = _LISTEVENTSREQUEST -DESCRIPTOR.message_types_by_name["ListEventsResponse"] = _LISTEVENTSRESPONSE -DESCRIPTOR.message_types_by_name["QueryTimeRange"] = _QUERYTIMERANGE -DESCRIPTOR.message_types_by_name["ServiceContextFilter"] = _SERVICECONTEXTFILTER -DESCRIPTOR.message_types_by_name["DeleteEventsRequest"] = _DELETEEVENTSREQUEST -DESCRIPTOR.message_types_by_name["DeleteEventsResponse"] = _DELETEEVENTSRESPONSE -DESCRIPTOR.enum_types_by_name["TimedCountAlignment"] = _TIMEDCOUNTALIGNMENT -DESCRIPTOR.enum_types_by_name["ErrorGroupOrder"] = _ERRORGROUPORDER -_sym_db.RegisterFileDescriptor(DESCRIPTOR) - -ListGroupStatsRequest = _reflection.GeneratedProtocolMessageType( - "ListGroupStatsRequest", - (_message.Message,), - dict( - DESCRIPTOR=_LISTGROUPSTATSREQUEST, - __module__="google.devtools.clouderrorreporting_v1beta1.proto.error_stats_service_pb2", - __doc__="""Specifies a set of ``ErrorGroupStats`` to return. - - - Attributes: - project_name: - [Required] The resource name of the Google Cloud Platform - project. Written as projects/ plus the Google Cloud Platform - project ID. Example: projects/my-project-123. - group_id: - [Optional] List all ErrorGroupStats with these IDs. - service_filter: - [Optional] List only ErrorGroupStats which belong to a service - context that matches the filter. Data for all service contexts - is returned if this field is not specified. - time_range: - [Optional] List data for the given time range. If not set a - default time range is used. The field time\_range\_begin in - the response will specify the beginning of this time range. - Only ErrorGroupStats with a non-zero count in the given time - range are returned, unless the request contains an explicit - group\_id list. If a group\_id list is given, also - ErrorGroupStats with zero occurrences are returned. - timed_count_duration: - [Optional] The preferred duration for a single returned - ``TimedCount``. If not set, no timed counts are returned. - alignment: - [Optional] The alignment of the timed counts to be returned. - Default is ``ALIGNMENT_EQUAL_AT_END``. - alignment_time: - [Optional] Time where the timed counts shall be aligned if - rounded alignment is chosen. Default is 00:00 UTC. - order: - [Optional] The sort order in which the results are returned. - Default is ``COUNT_DESC``. - page_size: - [Optional] The maximum number of results to return per - response. Default is 20. - page_token: - [Optional] A ``next_page_token`` provided by a previous - response. To view additional results, pass this token along - with the identical query parameters as the first request. - """, - # @@protoc_insertion_point(class_scope:google.devtools.clouderrorreporting.v1beta1.ListGroupStatsRequest) - ), -) -_sym_db.RegisterMessage(ListGroupStatsRequest) - -ListGroupStatsResponse = _reflection.GeneratedProtocolMessageType( - "ListGroupStatsResponse", - (_message.Message,), - dict( - DESCRIPTOR=_LISTGROUPSTATSRESPONSE, - __module__="google.devtools.clouderrorreporting_v1beta1.proto.error_stats_service_pb2", - __doc__="""Contains a set of requested error group stats. - - - Attributes: - error_group_stats: - The error group stats which match the given request. - next_page_token: - If non-empty, more results are available. Pass this token, - along with the same query parameters as the first request, to - view the next page of results. - time_range_begin: - The timestamp specifies the start time to which the request - was restricted. The start time is set based on the requested - time range. It may be adjusted to a later time if a project - has exceeded the storage quota and older data has been - deleted. - """, - # @@protoc_insertion_point(class_scope:google.devtools.clouderrorreporting.v1beta1.ListGroupStatsResponse) - ), -) -_sym_db.RegisterMessage(ListGroupStatsResponse) - -ErrorGroupStats = _reflection.GeneratedProtocolMessageType( - "ErrorGroupStats", - (_message.Message,), - dict( - DESCRIPTOR=_ERRORGROUPSTATS, - __module__="google.devtools.clouderrorreporting_v1beta1.proto.error_stats_service_pb2", - __doc__="""Data extracted for a specific group based on certain filter criteria, - such as a given time period and/or service filter. - - - Attributes: - group: - Group data that is independent of the filter criteria. - count: - Approximate total number of events in the given group that - match the filter criteria. - affected_users_count: - Approximate number of affected users in the given group that - match the filter criteria. Users are distinguished by data in - the ``ErrorContext`` of the individual error events, such as - their login name or their remote IP address in case of HTTP - requests. The number of affected users can be zero even if the - number of errors is non-zero if no data was provided from - which the affected user could be deduced. Users are counted - based on data in the request context that was provided in the - error report. If more users are implicitly affected, such as - due to a crash of the whole service, this is not reflected - here. - timed_counts: - Approximate number of occurrences over time. Timed counts - returned by ListGroups are guaranteed to be: - Inside the - requested time interval - Non-overlapping, and - Ordered by - ascending time. - first_seen_time: - Approximate first occurrence that was ever seen for this group - and which matches the given filter criteria, ignoring the - time\_range that was specified in the request. - last_seen_time: - Approximate last occurrence that was ever seen for this group - and which matches the given filter criteria, ignoring the - time\_range that was specified in the request. - affected_services: - Service contexts with a non-zero error count for the given - filter criteria. This list can be truncated if multiple - services are affected. Refer to ``num_affected_services`` for - the total count. - num_affected_services: - The total number of services with a non-zero error count for - the given filter criteria. - representative: - An arbitrary event that is chosen as representative for the - whole group. The representative event is intended to be used - as a quick preview for the whole group. Events in the group - are usually sufficiently similar to each other such that - showing an arbitrary representative provides insight into the - characteristics of the group as a whole. - """, - # @@protoc_insertion_point(class_scope:google.devtools.clouderrorreporting.v1beta1.ErrorGroupStats) - ), -) -_sym_db.RegisterMessage(ErrorGroupStats) - -TimedCount = _reflection.GeneratedProtocolMessageType( - "TimedCount", - (_message.Message,), - dict( - DESCRIPTOR=_TIMEDCOUNT, - __module__="google.devtools.clouderrorreporting_v1beta1.proto.error_stats_service_pb2", - __doc__="""The number of errors in a given time period. All numbers are approximate - since the error events are sampled before counting them. - - - Attributes: - count: - Approximate number of occurrences in the given time period. - start_time: - Start of the time period to which ``count`` refers (included). - end_time: - End of the time period to which ``count`` refers (excluded). - """, - # @@protoc_insertion_point(class_scope:google.devtools.clouderrorreporting.v1beta1.TimedCount) - ), -) -_sym_db.RegisterMessage(TimedCount) - -ListEventsRequest = _reflection.GeneratedProtocolMessageType( - "ListEventsRequest", - (_message.Message,), - dict( - DESCRIPTOR=_LISTEVENTSREQUEST, - __module__="google.devtools.clouderrorreporting_v1beta1.proto.error_stats_service_pb2", - __doc__="""Specifies a set of error events to return. - - - Attributes: - project_name: - [Required] The resource name of the Google Cloud Platform - project. Written as ``projects/`` plus the `Google Cloud - Platform project ID - `__. Example: - ``projects/my-project-123``. - group_id: - [Required] The group for which events shall be returned. - service_filter: - [Optional] List only ErrorGroups which belong to a service - context that matches the filter. Data for all service contexts - is returned if this field is not specified. - time_range: - [Optional] List only data for the given time range. If not set - a default time range is used. The field time\_range\_begin in - the response will specify the beginning of this time range. - page_size: - [Optional] The maximum number of results to return per - response. - page_token: - [Optional] A ``next_page_token`` provided by a previous - response. - """, - # @@protoc_insertion_point(class_scope:google.devtools.clouderrorreporting.v1beta1.ListEventsRequest) - ), -) -_sym_db.RegisterMessage(ListEventsRequest) - -ListEventsResponse = _reflection.GeneratedProtocolMessageType( - "ListEventsResponse", - (_message.Message,), - dict( - DESCRIPTOR=_LISTEVENTSRESPONSE, - __module__="google.devtools.clouderrorreporting_v1beta1.proto.error_stats_service_pb2", - __doc__="""Contains a set of requested error events. - - - Attributes: - error_events: - The error events which match the given request. - next_page_token: - If non-empty, more results are available. Pass this token, - along with the same query parameters as the first request, to - view the next page of results. - time_range_begin: - The timestamp specifies the start time to which the request - was restricted. - """, - # @@protoc_insertion_point(class_scope:google.devtools.clouderrorreporting.v1beta1.ListEventsResponse) - ), -) -_sym_db.RegisterMessage(ListEventsResponse) - -QueryTimeRange = _reflection.GeneratedProtocolMessageType( - "QueryTimeRange", - (_message.Message,), - dict( - DESCRIPTOR=_QUERYTIMERANGE, - __module__="google.devtools.clouderrorreporting_v1beta1.proto.error_stats_service_pb2", - __doc__="""Requests might be rejected or the resulting timed count durations might - be adjusted for lower durations. - - - Attributes: - period: - Restricts the query to the specified time range. - """, - # @@protoc_insertion_point(class_scope:google.devtools.clouderrorreporting.v1beta1.QueryTimeRange) - ), -) -_sym_db.RegisterMessage(QueryTimeRange) - -ServiceContextFilter = _reflection.GeneratedProtocolMessageType( - "ServiceContextFilter", - (_message.Message,), - dict( - DESCRIPTOR=_SERVICECONTEXTFILTER, - __module__="google.devtools.clouderrorreporting_v1beta1.proto.error_stats_service_pb2", - __doc__="""Specifies criteria for filtering a subset of service contexts. The - fields in the filter correspond to the fields in ``ServiceContext``. - Only exact, case-sensitive matches are supported. If a field is unset or - empty, it matches arbitrary values. - - - Attributes: - service: - [Optional] The exact value to match against - ```ServiceContext.service`` `__. - version: - [Optional] The exact value to match against - ```ServiceContext.version`` `__. - resource_type: - [Optional] The exact value to match against - ```ServiceContext.resource_type`` `__. - """, - # @@protoc_insertion_point(class_scope:google.devtools.clouderrorreporting.v1beta1.ServiceContextFilter) - ), -) -_sym_db.RegisterMessage(ServiceContextFilter) - -DeleteEventsRequest = _reflection.GeneratedProtocolMessageType( - "DeleteEventsRequest", - (_message.Message,), - dict( - DESCRIPTOR=_DELETEEVENTSREQUEST, - __module__="google.devtools.clouderrorreporting_v1beta1.proto.error_stats_service_pb2", - __doc__="""Deletes all events in the project. - - - Attributes: - project_name: - [Required] The resource name of the Google Cloud Platform - project. Written as ``projects/`` plus the `Google Cloud - Platform project ID - `__. Example: - ``projects/my-project-123``. - """, - # @@protoc_insertion_point(class_scope:google.devtools.clouderrorreporting.v1beta1.DeleteEventsRequest) - ), -) -_sym_db.RegisterMessage(DeleteEventsRequest) - -DeleteEventsResponse = _reflection.GeneratedProtocolMessageType( - "DeleteEventsResponse", - (_message.Message,), - dict( - DESCRIPTOR=_DELETEEVENTSRESPONSE, - __module__="google.devtools.clouderrorreporting_v1beta1.proto.error_stats_service_pb2", - __doc__="""Response message for deleting error events. - """, - # @@protoc_insertion_point(class_scope:google.devtools.clouderrorreporting.v1beta1.DeleteEventsResponse) - ), -) -_sym_db.RegisterMessage(DeleteEventsResponse) - - -DESCRIPTOR._options = None - -_ERRORSTATSSERVICE = _descriptor.ServiceDescriptor( - name="ErrorStatsService", - full_name="google.devtools.clouderrorreporting.v1beta1.ErrorStatsService", - file=DESCRIPTOR, - index=0, - serialized_options=None, - serialized_start=2755, - serialized_end=3381, - methods=[ - _descriptor.MethodDescriptor( - name="ListGroupStats", - full_name="google.devtools.clouderrorreporting.v1beta1.ErrorStatsService.ListGroupStats", - index=0, - containing_service=None, - input_type=_LISTGROUPSTATSREQUEST, - output_type=_LISTGROUPSTATSRESPONSE, - serialized_options=_b( - "\202\323\344\223\002/\022-/v1beta1/{project_name=projects/*}/groupStats" - ), - ), - _descriptor.MethodDescriptor( - name="ListEvents", - full_name="google.devtools.clouderrorreporting.v1beta1.ErrorStatsService.ListEvents", - index=1, - containing_service=None, - input_type=_LISTEVENTSREQUEST, - output_type=_LISTEVENTSRESPONSE, - serialized_options=_b( - "\202\323\344\223\002+\022)/v1beta1/{project_name=projects/*}/events" - ), - ), - _descriptor.MethodDescriptor( - name="DeleteEvents", - full_name="google.devtools.clouderrorreporting.v1beta1.ErrorStatsService.DeleteEvents", - index=2, - containing_service=None, - input_type=_DELETEEVENTSREQUEST, - output_type=_DELETEEVENTSRESPONSE, - serialized_options=_b( - "\202\323\344\223\002+*)/v1beta1/{project_name=projects/*}/events" - ), - ), - ], -) -_sym_db.RegisterServiceDescriptor(_ERRORSTATSSERVICE) - -DESCRIPTOR.services_by_name["ErrorStatsService"] = _ERRORSTATSSERVICE - -# @@protoc_insertion_point(module_scope) diff --git a/google/cloud/errorreporting_v1beta1/proto/error_stats_service_pb2_grpc.py b/google/cloud/errorreporting_v1beta1/proto/error_stats_service_pb2_grpc.py deleted file mode 100644 index 06944055..00000000 --- a/google/cloud/errorreporting_v1beta1/proto/error_stats_service_pb2_grpc.py +++ /dev/null @@ -1,86 +0,0 @@ -# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! -import grpc - -from google.cloud.errorreporting_v1beta1.proto import ( - error_stats_service_pb2 as google_dot_devtools_dot_clouderrorreporting__v1beta1_dot_proto_dot_error__stats__service__pb2, -) - - -class ErrorStatsServiceStub(object): - """An API for retrieving and managing error statistics as well as data for - individual events. - """ - - def __init__(self, channel): - """Constructor. - - Args: - channel: A grpc.Channel. - """ - self.ListGroupStats = channel.unary_unary( - "/google.devtools.clouderrorreporting.v1beta1.ErrorStatsService/ListGroupStats", - request_serializer=google_dot_devtools_dot_clouderrorreporting__v1beta1_dot_proto_dot_error__stats__service__pb2.ListGroupStatsRequest.SerializeToString, - response_deserializer=google_dot_devtools_dot_clouderrorreporting__v1beta1_dot_proto_dot_error__stats__service__pb2.ListGroupStatsResponse.FromString, - ) - self.ListEvents = channel.unary_unary( - "/google.devtools.clouderrorreporting.v1beta1.ErrorStatsService/ListEvents", - request_serializer=google_dot_devtools_dot_clouderrorreporting__v1beta1_dot_proto_dot_error__stats__service__pb2.ListEventsRequest.SerializeToString, - response_deserializer=google_dot_devtools_dot_clouderrorreporting__v1beta1_dot_proto_dot_error__stats__service__pb2.ListEventsResponse.FromString, - ) - self.DeleteEvents = channel.unary_unary( - "/google.devtools.clouderrorreporting.v1beta1.ErrorStatsService/DeleteEvents", - request_serializer=google_dot_devtools_dot_clouderrorreporting__v1beta1_dot_proto_dot_error__stats__service__pb2.DeleteEventsRequest.SerializeToString, - response_deserializer=google_dot_devtools_dot_clouderrorreporting__v1beta1_dot_proto_dot_error__stats__service__pb2.DeleteEventsResponse.FromString, - ) - - -class ErrorStatsServiceServicer(object): - """An API for retrieving and managing error statistics as well as data for - individual events. - """ - - def ListGroupStats(self, request, context): - """Lists the specified groups. - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details("Method not implemented!") - raise NotImplementedError("Method not implemented!") - - def ListEvents(self, request, context): - """Lists the specified events. - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details("Method not implemented!") - raise NotImplementedError("Method not implemented!") - - def DeleteEvents(self, request, context): - """Deletes all error events of a given project. - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details("Method not implemented!") - raise NotImplementedError("Method not implemented!") - - -def add_ErrorStatsServiceServicer_to_server(servicer, server): - rpc_method_handlers = { - "ListGroupStats": grpc.unary_unary_rpc_method_handler( - servicer.ListGroupStats, - request_deserializer=google_dot_devtools_dot_clouderrorreporting__v1beta1_dot_proto_dot_error__stats__service__pb2.ListGroupStatsRequest.FromString, - response_serializer=google_dot_devtools_dot_clouderrorreporting__v1beta1_dot_proto_dot_error__stats__service__pb2.ListGroupStatsResponse.SerializeToString, - ), - "ListEvents": grpc.unary_unary_rpc_method_handler( - servicer.ListEvents, - request_deserializer=google_dot_devtools_dot_clouderrorreporting__v1beta1_dot_proto_dot_error__stats__service__pb2.ListEventsRequest.FromString, - response_serializer=google_dot_devtools_dot_clouderrorreporting__v1beta1_dot_proto_dot_error__stats__service__pb2.ListEventsResponse.SerializeToString, - ), - "DeleteEvents": grpc.unary_unary_rpc_method_handler( - servicer.DeleteEvents, - request_deserializer=google_dot_devtools_dot_clouderrorreporting__v1beta1_dot_proto_dot_error__stats__service__pb2.DeleteEventsRequest.FromString, - response_serializer=google_dot_devtools_dot_clouderrorreporting__v1beta1_dot_proto_dot_error__stats__service__pb2.DeleteEventsResponse.SerializeToString, - ), - } - generic_handler = grpc.method_handlers_generic_handler( - "google.devtools.clouderrorreporting.v1beta1.ErrorStatsService", - rpc_method_handlers, - ) - server.add_generic_rpc_handlers((generic_handler,)) diff --git a/google/cloud/errorreporting_v1beta1/proto/report_errors_service.proto b/google/cloud/errorreporting_v1beta1/proto/report_errors_service.proto index d77f646c..f46f546d 100644 --- a/google/cloud/errorreporting_v1beta1/proto/report_errors_service.proto +++ b/google/cloud/errorreporting_v1beta1/proto/report_errors_service.proto @@ -1,4 +1,4 @@ -// Copyright 2016 Google Inc. +// Copyright 2019 Google LLC. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -11,75 +11,111 @@ // 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. +// syntax = "proto3"; package google.devtools.clouderrorreporting.v1beta1; import "google/api/annotations.proto"; +import "google/api/client.proto"; +import "google/api/field_behavior.proto"; +import "google/api/resource.proto"; import "google/devtools/clouderrorreporting/v1beta1/common.proto"; import "google/protobuf/timestamp.proto"; +option cc_enable_arenas = true; option csharp_namespace = "Google.Cloud.ErrorReporting.V1Beta1"; option go_package = "google.golang.org/genproto/googleapis/devtools/clouderrorreporting/v1beta1;clouderrorreporting"; option java_multiple_files = true; option java_outer_classname = "ReportErrorsServiceProto"; option java_package = "com.google.devtools.clouderrorreporting.v1beta1"; option php_namespace = "Google\\Cloud\\ErrorReporting\\V1beta1"; +option ruby_package = "Google::Cloud::ErrorReporting::V1beta1"; // An API for reporting error events. service ReportErrorsService { + option (google.api.default_host) = "clouderrorreporting.googleapis.com"; + option (google.api.oauth_scopes) = "https://www.googleapis.com/auth/cloud-platform"; + // Report an individual error event. // - // This endpoint accepts either an OAuth token, - // or an - // API key + // This endpoint accepts **either** an OAuth token, + // **or** an [API key](https://support.google.com/cloud/answer/6158862) // for authentication. To use an API key, append it to the URL as the value of // a `key` parameter. For example: - //
POST
-  // https://clouderrorreporting.googleapis.com/v1beta1/projects/example-project/events:report?key=123ABC456
- rpc ReportErrorEvent(ReportErrorEventRequest) - returns (ReportErrorEventResponse) { + // + // `POST + // https://clouderrorreporting.googleapis.com/v1beta1/projects/example-project/events:report?key=123ABC456` + rpc ReportErrorEvent(ReportErrorEventRequest) returns (ReportErrorEventResponse) { option (google.api.http) = { post: "/v1beta1/{project_name=projects/*}/events:report" body: "event" }; + option (google.api.method_signature) = "project_name,event"; } } // A request for reporting an individual error event. message ReportErrorEventRequest { - // [Required] The resource name of the Google Cloud Platform project. Written + // Required. The resource name of the Google Cloud Platform project. Written // as `projects/` plus the // [Google Cloud Platform project // ID](https://support.google.com/cloud/answer/6158840). Example: // `projects/my-project-123`. - string project_name = 1; + string project_name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "cloudresourcemanager.googleapis.com/Project" + } + ]; - // [Required] The error event to be reported. - ReportedErrorEvent event = 2; + // Required. The error event to be reported. + ReportedErrorEvent event = 2 [(google.api.field_behavior) = REQUIRED]; } // Response for reporting an individual error event. // Data may be added to this message in the future. -message ReportErrorEventResponse {} +message ReportErrorEventResponse { + +} // An error event which is reported to the Error Reporting system. message ReportedErrorEvent { - // [Optional] Time when the event occurred. + // Optional. Time when the event occurred. // If not provided, the time when the event was received by the // Error Reporting system will be used. - google.protobuf.Timestamp event_time = 1; + google.protobuf.Timestamp event_time = 1 [(google.api.field_behavior) = OPTIONAL]; - // [Required] The service context in which this error has occurred. - ServiceContext service_context = 2; + // Required. The service context in which this error has occurred. + ServiceContext service_context = 2 [(google.api.field_behavior) = REQUIRED]; - // [Required] A message describing the error. The message can contain an - // exception stack in one of the supported programming languages and formats. - // In that case, the message is parsed and detailed exception information - // is returned when retrieving the error event again. - string message = 3; + // Required. The error message. + // If no `context.reportLocation` is provided, the message must contain a + // header (typically consisting of the exception type name and an error + // message) and an exception stack trace in one of the supported programming + // languages and formats. + // Supported languages are Java, Python, JavaScript, Ruby, C#, PHP, and Go. + // Supported stack trace formats are: + // + // * **Java**: Must be the return value of + // [`Throwable.printStackTrace()`](https://docs.oracle.com/javase/7/docs/api/java/lang/Throwable.html#printStackTrace%28%29). + // * **Python**: Must be the return value of + // [`traceback.format_exc()`](https://docs.python.org/2/library/traceback.html#traceback.format_exc). + // * **JavaScript**: Must be the value of + // [`error.stack`](https://github.com/v8/v8/wiki/Stack-Trace-API) as returned + // by V8. + // * **Ruby**: Must contain frames returned by + // [`Exception.backtrace`](https://ruby-doc.org/core-2.2.0/Exception.html#method-i-backtrace). + // * **C#**: Must be the return value of + // [`Exception.ToString()`](https://msdn.microsoft.com/en-us/library/system.exception.tostring.aspx). + // * **PHP**: Must start with `PHP (Notice|Parse error|Fatal error|Warning)` + // and contain the result of + // [`(string)$exception`](http://php.net/manual/en/exception.tostring.php). + // * **Go**: Must be the return value of + // [`runtime.Stack()`](https://golang.org/pkg/runtime/debug/#Stack). + string message = 3 [(google.api.field_behavior) = REQUIRED]; - // [Optional] A description of the context in which the error occurred. - ErrorContext context = 4; + // Optional. A description of the context in which the error occurred. + ErrorContext context = 4 [(google.api.field_behavior) = OPTIONAL]; } diff --git a/google/cloud/errorreporting_v1beta1/proto/report_errors_service_pb2.py b/google/cloud/errorreporting_v1beta1/proto/report_errors_service_pb2.py deleted file mode 100644 index 9562dd34..00000000 --- a/google/cloud/errorreporting_v1beta1/proto/report_errors_service_pb2.py +++ /dev/null @@ -1,330 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: google/devtools/clouderrorreporting_v1beta1/proto/report_errors_service.proto - -import sys - -_b = sys.version_info[0] < 3 and (lambda x: x) or (lambda x: x.encode("latin1")) -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf import reflection as _reflection -from google.protobuf import symbol_database as _symbol_database - -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from google.api import annotations_pb2 as google_dot_api_dot_annotations__pb2 -from google.cloud.errorreporting_v1beta1.proto import ( - common_pb2 as google_dot_devtools_dot_clouderrorreporting__v1beta1_dot_proto_dot_common__pb2, -) -from google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__pb2 - - -DESCRIPTOR = _descriptor.FileDescriptor( - name="google/devtools/clouderrorreporting_v1beta1/proto/report_errors_service.proto", - package="google.devtools.clouderrorreporting.v1beta1", - syntax="proto3", - serialized_options=_b( - "\n/com.google.devtools.clouderrorreporting.v1beta1B\030ReportErrorsServiceProtoP\001Z^google.golang.org/genproto/googleapis/devtools/clouderrorreporting/v1beta1;clouderrorreporting\252\002#Google.Cloud.ErrorReporting.V1Beta1\312\002#Google\\Cloud\\ErrorReporting\\V1beta1" - ), - serialized_pb=_b( - '\nMgoogle/devtools/clouderrorreporting_v1beta1/proto/report_errors_service.proto\x12+google.devtools.clouderrorreporting.v1beta1\x1a\x1cgoogle/api/annotations.proto\x1a>google/devtools/clouderrorreporting_v1beta1/proto/common.proto\x1a\x1fgoogle/protobuf/timestamp.proto"\x7f\n\x17ReportErrorEventRequest\x12\x14\n\x0cproject_name\x18\x01 \x01(\t\x12N\n\x05\x65vent\x18\x02 \x01(\x0b\x32?.google.devtools.clouderrorreporting.v1beta1.ReportedErrorEvent"\x1a\n\x18ReportErrorEventResponse"\xf7\x01\n\x12ReportedErrorEvent\x12.\n\nevent_time\x18\x01 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12T\n\x0fservice_context\x18\x02 \x01(\x0b\x32;.google.devtools.clouderrorreporting.v1beta1.ServiceContext\x12\x0f\n\x07message\x18\x03 \x01(\t\x12J\n\x07\x63ontext\x18\x04 \x01(\x0b\x32\x39.google.devtools.clouderrorreporting.v1beta1.ErrorContext2\xf8\x01\n\x13ReportErrorsService\x12\xe0\x01\n\x10ReportErrorEvent\x12\x44.google.devtools.clouderrorreporting.v1beta1.ReportErrorEventRequest\x1a\x45.google.devtools.clouderrorreporting.v1beta1.ReportErrorEventResponse"?\x82\xd3\xe4\x93\x02\x39"0/v1beta1/{project_name=projects/*}/events:report:\x05\x65ventB\xf9\x01\n/com.google.devtools.clouderrorreporting.v1beta1B\x18ReportErrorsServiceProtoP\x01Z^google.golang.org/genproto/googleapis/devtools/clouderrorreporting/v1beta1;clouderrorreporting\xaa\x02#Google.Cloud.ErrorReporting.V1Beta1\xca\x02#Google\\Cloud\\ErrorReporting\\V1beta1b\x06proto3' - ), - dependencies=[ - google_dot_api_dot_annotations__pb2.DESCRIPTOR, - google_dot_devtools_dot_clouderrorreporting__v1beta1_dot_proto_dot_common__pb2.DESCRIPTOR, - google_dot_protobuf_dot_timestamp__pb2.DESCRIPTOR, - ], -) - - -_REPORTERROREVENTREQUEST = _descriptor.Descriptor( - name="ReportErrorEventRequest", - full_name="google.devtools.clouderrorreporting.v1beta1.ReportErrorEventRequest", - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name="project_name", - full_name="google.devtools.clouderrorreporting.v1beta1.ReportErrorEventRequest.project_name", - index=0, - number=1, - type=9, - cpp_type=9, - label=1, - has_default_value=False, - default_value=_b("").decode("utf-8"), - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - ), - _descriptor.FieldDescriptor( - name="event", - full_name="google.devtools.clouderrorreporting.v1beta1.ReportErrorEventRequest.event", - index=1, - number=2, - type=11, - cpp_type=10, - label=1, - has_default_value=False, - default_value=None, - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - ), - ], - extensions=[], - nested_types=[], - enum_types=[], - serialized_options=None, - is_extendable=False, - syntax="proto3", - extension_ranges=[], - oneofs=[], - serialized_start=253, - serialized_end=380, -) - - -_REPORTERROREVENTRESPONSE = _descriptor.Descriptor( - name="ReportErrorEventResponse", - full_name="google.devtools.clouderrorreporting.v1beta1.ReportErrorEventResponse", - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[], - extensions=[], - nested_types=[], - enum_types=[], - serialized_options=None, - is_extendable=False, - syntax="proto3", - extension_ranges=[], - oneofs=[], - serialized_start=382, - serialized_end=408, -) - - -_REPORTEDERROREVENT = _descriptor.Descriptor( - name="ReportedErrorEvent", - full_name="google.devtools.clouderrorreporting.v1beta1.ReportedErrorEvent", - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name="event_time", - full_name="google.devtools.clouderrorreporting.v1beta1.ReportedErrorEvent.event_time", - index=0, - number=1, - type=11, - cpp_type=10, - label=1, - has_default_value=False, - default_value=None, - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - ), - _descriptor.FieldDescriptor( - name="service_context", - full_name="google.devtools.clouderrorreporting.v1beta1.ReportedErrorEvent.service_context", - index=1, - number=2, - type=11, - cpp_type=10, - label=1, - has_default_value=False, - default_value=None, - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - ), - _descriptor.FieldDescriptor( - name="message", - full_name="google.devtools.clouderrorreporting.v1beta1.ReportedErrorEvent.message", - index=2, - number=3, - type=9, - cpp_type=9, - label=1, - has_default_value=False, - default_value=_b("").decode("utf-8"), - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - ), - _descriptor.FieldDescriptor( - name="context", - full_name="google.devtools.clouderrorreporting.v1beta1.ReportedErrorEvent.context", - index=3, - number=4, - type=11, - cpp_type=10, - label=1, - has_default_value=False, - default_value=None, - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - ), - ], - extensions=[], - nested_types=[], - enum_types=[], - serialized_options=None, - is_extendable=False, - syntax="proto3", - extension_ranges=[], - oneofs=[], - serialized_start=411, - serialized_end=658, -) - -_REPORTERROREVENTREQUEST.fields_by_name["event"].message_type = _REPORTEDERROREVENT -_REPORTEDERROREVENT.fields_by_name[ - "event_time" -].message_type = google_dot_protobuf_dot_timestamp__pb2._TIMESTAMP -_REPORTEDERROREVENT.fields_by_name[ - "service_context" -].message_type = ( - google_dot_devtools_dot_clouderrorreporting__v1beta1_dot_proto_dot_common__pb2._SERVICECONTEXT -) -_REPORTEDERROREVENT.fields_by_name[ - "context" -].message_type = ( - google_dot_devtools_dot_clouderrorreporting__v1beta1_dot_proto_dot_common__pb2._ERRORCONTEXT -) -DESCRIPTOR.message_types_by_name["ReportErrorEventRequest"] = _REPORTERROREVENTREQUEST -DESCRIPTOR.message_types_by_name["ReportErrorEventResponse"] = _REPORTERROREVENTRESPONSE -DESCRIPTOR.message_types_by_name["ReportedErrorEvent"] = _REPORTEDERROREVENT -_sym_db.RegisterFileDescriptor(DESCRIPTOR) - -ReportErrorEventRequest = _reflection.GeneratedProtocolMessageType( - "ReportErrorEventRequest", - (_message.Message,), - dict( - DESCRIPTOR=_REPORTERROREVENTREQUEST, - __module__="google.devtools.clouderrorreporting_v1beta1.proto.report_errors_service_pb2", - __doc__="""A request for reporting an individual error event. - - - Attributes: - project_name: - [Required] The resource name of the Google Cloud Platform - project. Written as ``projects/`` plus the `Google Cloud - Platform project ID - `__. Example: - ``projects/my-project-123``. - event: - [Required] The error event to be reported. - """, - # @@protoc_insertion_point(class_scope:google.devtools.clouderrorreporting.v1beta1.ReportErrorEventRequest) - ), -) -_sym_db.RegisterMessage(ReportErrorEventRequest) - -ReportErrorEventResponse = _reflection.GeneratedProtocolMessageType( - "ReportErrorEventResponse", - (_message.Message,), - dict( - DESCRIPTOR=_REPORTERROREVENTRESPONSE, - __module__="google.devtools.clouderrorreporting_v1beta1.proto.report_errors_service_pb2", - __doc__="""Response for reporting an individual error event. Data may be added to - this message in the future. - """, - # @@protoc_insertion_point(class_scope:google.devtools.clouderrorreporting.v1beta1.ReportErrorEventResponse) - ), -) -_sym_db.RegisterMessage(ReportErrorEventResponse) - -ReportedErrorEvent = _reflection.GeneratedProtocolMessageType( - "ReportedErrorEvent", - (_message.Message,), - dict( - DESCRIPTOR=_REPORTEDERROREVENT, - __module__="google.devtools.clouderrorreporting_v1beta1.proto.report_errors_service_pb2", - __doc__="""An error event which is reported to the Error Reporting system. - - - Attributes: - event_time: - [Optional] Time when the event occurred. If not provided, the - time when the event was received by the Error Reporting system - will be used. - service_context: - [Required] The service context in which this error has - occurred. - message: - [Required] A message describing the error. The message can - contain an exception stack in one of the supported programming - languages and formats. In that case, the message is parsed and - detailed exception information is returned when retrieving the - error event again. - context: - [Optional] A description of the context in which the error - occurred. - """, - # @@protoc_insertion_point(class_scope:google.devtools.clouderrorreporting.v1beta1.ReportedErrorEvent) - ), -) -_sym_db.RegisterMessage(ReportedErrorEvent) - - -DESCRIPTOR._options = None - -_REPORTERRORSSERVICE = _descriptor.ServiceDescriptor( - name="ReportErrorsService", - full_name="google.devtools.clouderrorreporting.v1beta1.ReportErrorsService", - file=DESCRIPTOR, - index=0, - serialized_options=None, - serialized_start=661, - serialized_end=909, - methods=[ - _descriptor.MethodDescriptor( - name="ReportErrorEvent", - full_name="google.devtools.clouderrorreporting.v1beta1.ReportErrorsService.ReportErrorEvent", - index=0, - containing_service=None, - input_type=_REPORTERROREVENTREQUEST, - output_type=_REPORTERROREVENTRESPONSE, - serialized_options=_b( - '\202\323\344\223\0029"0/v1beta1/{project_name=projects/*}/events:report:\005event' - ), - ) - ], -) -_sym_db.RegisterServiceDescriptor(_REPORTERRORSSERVICE) - -DESCRIPTOR.services_by_name["ReportErrorsService"] = _REPORTERRORSSERVICE - -# @@protoc_insertion_point(module_scope) diff --git a/google/cloud/errorreporting_v1beta1/proto/report_errors_service_pb2_grpc.py b/google/cloud/errorreporting_v1beta1/proto/report_errors_service_pb2_grpc.py deleted file mode 100644 index 12f6e08e..00000000 --- a/google/cloud/errorreporting_v1beta1/proto/report_errors_service_pb2_grpc.py +++ /dev/null @@ -1,58 +0,0 @@ -# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! -import grpc - -from google.cloud.errorreporting_v1beta1.proto import ( - report_errors_service_pb2 as google_dot_devtools_dot_clouderrorreporting__v1beta1_dot_proto_dot_report__errors__service__pb2, -) - - -class ReportErrorsServiceStub(object): - """An API for reporting error events. - """ - - def __init__(self, channel): - """Constructor. - - Args: - channel: A grpc.Channel. - """ - self.ReportErrorEvent = channel.unary_unary( - "/google.devtools.clouderrorreporting.v1beta1.ReportErrorsService/ReportErrorEvent", - request_serializer=google_dot_devtools_dot_clouderrorreporting__v1beta1_dot_proto_dot_report__errors__service__pb2.ReportErrorEventRequest.SerializeToString, - response_deserializer=google_dot_devtools_dot_clouderrorreporting__v1beta1_dot_proto_dot_report__errors__service__pb2.ReportErrorEventResponse.FromString, - ) - - -class ReportErrorsServiceServicer(object): - """An API for reporting error events. - """ - - def ReportErrorEvent(self, request, context): - """Report an individual error event. - - This endpoint accepts either an OAuth token, - or an - API key - for authentication. To use an API key, append it to the URL as the value of - a `key` parameter. For example: -
POST
-    https://clouderrorreporting.googleapis.com/v1beta1/projects/example-project/events:report?key=123ABC456
- """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details("Method not implemented!") - raise NotImplementedError("Method not implemented!") - - -def add_ReportErrorsServiceServicer_to_server(servicer, server): - rpc_method_handlers = { - "ReportErrorEvent": grpc.unary_unary_rpc_method_handler( - servicer.ReportErrorEvent, - request_deserializer=google_dot_devtools_dot_clouderrorreporting__v1beta1_dot_proto_dot_report__errors__service__pb2.ReportErrorEventRequest.FromString, - response_serializer=google_dot_devtools_dot_clouderrorreporting__v1beta1_dot_proto_dot_report__errors__service__pb2.ReportErrorEventResponse.SerializeToString, - ) - } - generic_handler = grpc.method_handlers_generic_handler( - "google.devtools.clouderrorreporting.v1beta1.ReportErrorsService", - rpc_method_handlers, - ) - server.add_generic_rpc_handlers((generic_handler,)) diff --git a/google/cloud/errorreporting_v1beta1/proto/synth.metadata b/google/cloud/errorreporting_v1beta1/proto/synth.metadata deleted file mode 100644 index aa85442f..00000000 --- a/google/cloud/errorreporting_v1beta1/proto/synth.metadata +++ /dev/null @@ -1,3 +0,0 @@ -{ - "updateTime": "2019-01-23T23:03:31.526988Z" -} \ No newline at end of file diff --git a/google/cloud/errorreporting_v1beta1/py.typed b/google/cloud/errorreporting_v1beta1/py.typed new file mode 100644 index 00000000..20bf6ac6 --- /dev/null +++ b/google/cloud/errorreporting_v1beta1/py.typed @@ -0,0 +1,2 @@ +# Marker file for PEP 561. +# The google-cloud-errorreporting package uses inline types. diff --git a/google/__init__.py b/google/cloud/errorreporting_v1beta1/services/__init__.py similarity index 73% rename from google/__init__.py rename to google/cloud/errorreporting_v1beta1/services/__init__.py index 0e1bc513..42ffdf2b 100644 --- a/google/__init__.py +++ b/google/cloud/errorreporting_v1beta1/services/__init__.py @@ -1,4 +1,6 @@ -# Copyright 2016 Google LLC +# -*- 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. @@ -11,12 +13,4 @@ # 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. - -try: - import pkg_resources - - pkg_resources.declare_namespace(__name__) -except ImportError: - import pkgutil - - __path__ = pkgutil.extend_path(__path__, __name__) +# diff --git a/google/cloud/errorreporting_v1beta1/services/error_group_service/__init__.py b/google/cloud/errorreporting_v1beta1/services/error_group_service/__init__.py new file mode 100644 index 00000000..aff59ad1 --- /dev/null +++ b/google/cloud/errorreporting_v1beta1/services/error_group_service/__init__.py @@ -0,0 +1,24 @@ +# -*- 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. +# + +from .client import ErrorGroupServiceClient +from .async_client import ErrorGroupServiceAsyncClient + +__all__ = ( + "ErrorGroupServiceClient", + "ErrorGroupServiceAsyncClient", +) diff --git a/google/cloud/errorreporting_v1beta1/services/error_group_service/async_client.py b/google/cloud/errorreporting_v1beta1/services/error_group_service/async_client.py new file mode 100644 index 00000000..8caf2ad7 --- /dev/null +++ b/google/cloud/errorreporting_v1beta1/services/error_group_service/async_client.py @@ -0,0 +1,263 @@ +# -*- 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. +# + +from collections import OrderedDict +import functools +import re +from typing import Dict, Sequence, Tuple, Type, Union +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 gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.cloud.errorreporting_v1beta1.types import common +from google.cloud.errorreporting_v1beta1.types import error_group_service + +from .transports.base import ErrorGroupServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc_asyncio import ErrorGroupServiceGrpcAsyncIOTransport +from .client import ErrorGroupServiceClient + + +class ErrorGroupServiceAsyncClient: + """Service for retrieving and updating individual error groups.""" + + _client: ErrorGroupServiceClient + + DEFAULT_ENDPOINT = ErrorGroupServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = ErrorGroupServiceClient.DEFAULT_MTLS_ENDPOINT + + error_group_path = staticmethod(ErrorGroupServiceClient.error_group_path) + + from_service_account_file = ErrorGroupServiceClient.from_service_account_file + from_service_account_json = from_service_account_file + + get_transport_class = functools.partial( + type(ErrorGroupServiceClient).get_transport_class, type(ErrorGroupServiceClient) + ) + + def __init__( + self, + *, + credentials: credentials.Credentials = None, + transport: Union[str, ErrorGroupServiceTransport] = "grpc_asyncio", + client_options: ClientOptions = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiate the error group service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, ~.ErrorGroupServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (ClientOptions): Custom options for the client. It + won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint, this is the default value for + the environment variable) and "auto" (auto switch to the default + mTLS endpoint if client SSL credentials is present). However, + the ``api_endpoint`` property takes precedence if provided. + (2) The ``client_cert_source`` property is used to provide client + SSL credentials for mutual TLS transport. If not provided, the + default SSL credentials will be used if present. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + + self._client = ErrorGroupServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + async def get_group( + self, + request: error_group_service.GetGroupRequest = None, + *, + group_name: str = None, + retry: retries.Retry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> common.ErrorGroup: + r"""Get the specified group. + + Args: + request (:class:`~.error_group_service.GetGroupRequest`): + The request object. A request to return an individual + group. + group_name (:class:`str`): + The group resource name. Written as + ``projects/{projectID}/groups/{group_name}``. Call + ```groupStats.list`` `__ + to return a list of groups belonging to this project. + + Example: ``projects/my-project-123/groups/my-group`` + This corresponds to the ``group_name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.common.ErrorGroup: + Description of a group of similar + error events. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + if request is not None and any([group_name]): + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = error_group_service.GetGroupRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + + if group_name is not None: + request.group_name = group_name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.get_group, + 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( + (("group_name", request.group_name),) + ), + ) + + # Send the request. + response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + async def update_group( + self, + request: error_group_service.UpdateGroupRequest = None, + *, + group: common.ErrorGroup = None, + retry: retries.Retry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> common.ErrorGroup: + r"""Replace the data for the specified group. + Fails if the group does not exist. + + Args: + request (:class:`~.error_group_service.UpdateGroupRequest`): + The request object. A request to replace the existing + data for the given group. + group (:class:`~.common.ErrorGroup`): + Required. The group which replaces + the resource on the server. + This corresponds to the ``group`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.common.ErrorGroup: + Description of a group of similar + error events. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + if request is not None and any([group]): + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = error_group_service.UpdateGroupRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + + if group is not None: + request.group = group + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.update_group, + 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( + (("group.name", request.group.name),) + ), + ) + + # Send the request. + response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution( + "google-cloud-errorreporting", + ).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("ErrorGroupServiceAsyncClient",) diff --git a/google/cloud/errorreporting_v1beta1/services/error_group_service/client.py b/google/cloud/errorreporting_v1beta1/services/error_group_service/client.py new file mode 100644 index 00000000..3cd79780 --- /dev/null +++ b/google/cloud/errorreporting_v1beta1/services/error_group_service/client.py @@ -0,0 +1,407 @@ +# -*- 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. +# + +from collections import OrderedDict +import os +import re +from typing import Callable, Dict, Sequence, Tuple, Type, Union +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 gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.cloud.errorreporting_v1beta1.types import common +from google.cloud.errorreporting_v1beta1.types import error_group_service + +from .transports.base import ErrorGroupServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import ErrorGroupServiceGrpcTransport +from .transports.grpc_asyncio import ErrorGroupServiceGrpcAsyncIOTransport + + +class ErrorGroupServiceClientMeta(type): + """Metaclass for the ErrorGroupService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[ErrorGroupServiceTransport]] + _transport_registry["grpc"] = ErrorGroupServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ErrorGroupServiceGrpcAsyncIOTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[ErrorGroupServiceTransport]: + """Return an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class ErrorGroupServiceClient(metaclass=ErrorGroupServiceClientMeta): + """Service for retrieving and updating individual error groups.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Convert api endpoint to mTLS endpoint. + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "clouderrorreporting.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + {@api.name}: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file(filename) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @staticmethod + def error_group_path(project: str, group: str,) -> str: + """Return a fully-qualified error_group string.""" + return "projects/{project}/groups/{group}".format(project=project, group=group,) + + @staticmethod + def parse_error_group_path(path: str) -> Dict[str, str]: + """Parse a error_group path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/groups/(?P.+?)$", path) + return m.groupdict() if m else {} + + def __init__( + self, + *, + credentials: credentials.Credentials = None, + transport: Union[str, ErrorGroupServiceTransport] = None, + client_options: ClientOptions = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiate the error group service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, ~.ErrorGroupServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (ClientOptions): Custom options for the client. It + won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint, this is the default value for + the environment variable) and "auto" (auto switch to the default + mTLS endpoint if client SSL credentials is present). However, + the ``api_endpoint`` property takes precedence if provided. + (2) The ``client_cert_source`` property is used to provide client + SSL credentials for mutual TLS transport. If not provided, the + default SSL credentials will be used if present. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = ClientOptions.from_dict(client_options) + if client_options is None: + client_options = ClientOptions.ClientOptions() + + if client_options.api_endpoint is None: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS", "never") + if use_mtls_env == "never": + client_options.api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + client_options.api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + has_client_cert_source = ( + client_options.client_cert_source is not None + or mtls.has_default_client_cert_source() + ) + client_options.api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if has_client_cert_source + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS value. Accepted values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, ErrorGroupServiceTransport): + # transport is a ErrorGroupServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, " + "provide its scopes directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=client_options.api_endpoint, + scopes=client_options.scopes, + api_mtls_endpoint=client_options.api_endpoint, + client_cert_source=client_options.client_cert_source, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + ) + + def get_group( + self, + request: error_group_service.GetGroupRequest = None, + *, + group_name: str = None, + retry: retries.Retry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> common.ErrorGroup: + r"""Get the specified group. + + Args: + request (:class:`~.error_group_service.GetGroupRequest`): + The request object. A request to return an individual + group. + group_name (:class:`str`): + The group resource name. Written as + ``projects/{projectID}/groups/{group_name}``. Call + ```groupStats.list`` `__ + to return a list of groups belonging to this project. + + Example: ``projects/my-project-123/groups/my-group`` + This corresponds to the ``group_name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.common.ErrorGroup: + Description of a group of similar + error events. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([group_name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a error_group_service.GetGroupRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, error_group_service.GetGroupRequest): + request = error_group_service.GetGroupRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + + if group_name is not None: + request.group_name = group_name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.get_group] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("group_name", request.group_name),) + ), + ) + + # Send the request. + response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + def update_group( + self, + request: error_group_service.UpdateGroupRequest = None, + *, + group: common.ErrorGroup = None, + retry: retries.Retry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> common.ErrorGroup: + r"""Replace the data for the specified group. + Fails if the group does not exist. + + Args: + request (:class:`~.error_group_service.UpdateGroupRequest`): + The request object. A request to replace the existing + data for the given group. + group (:class:`~.common.ErrorGroup`): + Required. The group which replaces + the resource on the server. + This corresponds to the ``group`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.common.ErrorGroup: + Description of a group of similar + error events. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([group]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a error_group_service.UpdateGroupRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, error_group_service.UpdateGroupRequest): + request = error_group_service.UpdateGroupRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + + if group is not None: + request.group = group + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.update_group] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("group.name", request.group.name),) + ), + ) + + # Send the request. + response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution( + "google-cloud-errorreporting", + ).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("ErrorGroupServiceClient",) diff --git a/google/cloud/errorreporting_v1beta1/services/error_group_service/transports/__init__.py b/google/cloud/errorreporting_v1beta1/services/error_group_service/transports/__init__.py new file mode 100644 index 00000000..b2784eaa --- /dev/null +++ b/google/cloud/errorreporting_v1beta1/services/error_group_service/transports/__init__.py @@ -0,0 +1,36 @@ +# -*- 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. +# + +from collections import OrderedDict +from typing import Dict, Type + +from .base import ErrorGroupServiceTransport +from .grpc import ErrorGroupServiceGrpcTransport +from .grpc_asyncio import ErrorGroupServiceGrpcAsyncIOTransport + + +# Compile a registry of transports. +_transport_registry = OrderedDict() # type: Dict[str, Type[ErrorGroupServiceTransport]] +_transport_registry["grpc"] = ErrorGroupServiceGrpcTransport +_transport_registry["grpc_asyncio"] = ErrorGroupServiceGrpcAsyncIOTransport + + +__all__ = ( + "ErrorGroupServiceTransport", + "ErrorGroupServiceGrpcTransport", + "ErrorGroupServiceGrpcAsyncIOTransport", +) diff --git a/google/cloud/errorreporting_v1beta1/services/error_group_service/transports/base.py b/google/cloud/errorreporting_v1beta1/services/error_group_service/transports/base.py new file mode 100644 index 00000000..794cf769 --- /dev/null +++ b/google/cloud/errorreporting_v1beta1/services/error_group_service/transports/base.py @@ -0,0 +1,137 @@ +# -*- 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. +# + +import abc +import typing +import pkg_resources + +from google import auth # type: ignore +from google.api_core import 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.cloud.errorreporting_v1beta1.types import common +from google.cloud.errorreporting_v1beta1.types import error_group_service + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution( + "google-cloud-errorreporting", + ).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class ErrorGroupServiceTransport(abc.ABC): + """Abstract transport class for ErrorGroupService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/cloud-platform",) + + def __init__( + self, + *, + host: str = "clouderrorreporting.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, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + 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 + are specified, the client will attempt to ascertain the + credentials from the environment. + 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. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = auth.load_credentials_from_file( + credentials_file, scopes=scopes, quota_project_id=quota_project_id + ) + + elif credentials is None: + credentials, _ = auth.default( + scopes=scopes, quota_project_id=quota_project_id + ) + + # Save the credentials. + self._credentials = credentials + + # Lifted into its own function so it can be stubbed out during tests. + self._prep_wrapped_messages(client_info) + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.get_group: gapic_v1.method.wrap_method( + self.get_group, default_timeout=None, client_info=client_info, + ), + self.update_group: gapic_v1.method.wrap_method( + self.update_group, default_timeout=None, client_info=client_info, + ), + } + + @property + def get_group( + self, + ) -> typing.Callable[ + [error_group_service.GetGroupRequest], + typing.Union[common.ErrorGroup, typing.Awaitable[common.ErrorGroup]], + ]: + raise NotImplementedError() + + @property + def update_group( + self, + ) -> typing.Callable[ + [error_group_service.UpdateGroupRequest], + typing.Union[common.ErrorGroup, typing.Awaitable[common.ErrorGroup]], + ]: + raise NotImplementedError() + + +__all__ = ("ErrorGroupServiceTransport",) diff --git a/google/cloud/errorreporting_v1beta1/services/error_group_service/transports/grpc.py b/google/cloud/errorreporting_v1beta1/services/error_group_service/transports/grpc.py new file mode 100644 index 00000000..d6091a89 --- /dev/null +++ b/google/cloud/errorreporting_v1beta1/services/error_group_service/transports/grpc.py @@ -0,0 +1,269 @@ +# -*- 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. +# + +from typing import Callable, Dict, Optional, Sequence, Tuple + +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 +from google.auth.transport.grpc import SslCredentials # type: ignore + + +import grpc # type: ignore + +from google.cloud.errorreporting_v1beta1.types import common +from google.cloud.errorreporting_v1beta1.types import error_group_service + +from .base import ErrorGroupServiceTransport, DEFAULT_CLIENT_INFO + + +class ErrorGroupServiceGrpcTransport(ErrorGroupServiceTransport): + """gRPC backend transport for ErrorGroupService. + + Service for retrieving and updating individual error groups. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "clouderrorreporting.googleapis.com", + credentials: credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiate the transport. + + Args: + 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 + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): The mutual TLS endpoint. If + provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or applicatin default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): A + callback to provide client SSL certificate bytes and private key + bytes, both in PEM format. It is ignored if ``api_mtls_endpoint`` + is None. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + if channel: + # Sanity check: Ensure that channel and credentials are not both + # provided. + credentials = False + + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + elif api_mtls_endpoint: + host = ( + api_mtls_endpoint + if ":" in api_mtls_endpoint + else api_mtls_endpoint + ":443" + ) + + if credentials is None: + credentials, _ = auth.default( + scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id + ) + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + ssl_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + ssl_credentials = SslCredentials().ssl_credentials + + # create a new channel. The provided one is ignored. + self._grpc_channel = type(self).create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + ssl_credentials=ssl_credentials, + scopes=scopes or self.AUTH_SCOPES, + quota_project_id=quota_project_id, + ) + + self._stubs = {} # type: Dict[str, Callable] + + # Run the base constructor. + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes or self.AUTH_SCOPES, + quota_project_id=quota_project_id, + client_info=client_info, + ) + + @classmethod + def create_channel( + cls, + host: str = "clouderrorreporting.googleapis.com", + credentials: credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + address (Optionsl[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + 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. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + scopes = scopes or cls.AUTH_SCOPES + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Sanity check: Only create a new channel if we do not already + # have one. + if not hasattr(self, "_grpc_channel"): + self._grpc_channel = self.create_channel( + self._host, credentials=self._credentials, + ) + + # Return the channel from cache. + return self._grpc_channel + + @property + def get_group( + self, + ) -> Callable[[error_group_service.GetGroupRequest], common.ErrorGroup]: + r"""Return a callable for the get group method over gRPC. + + Get the specified group. + + Returns: + Callable[[~.GetGroupRequest], + ~.ErrorGroup]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "get_group" not in self._stubs: + self._stubs["get_group"] = self.grpc_channel.unary_unary( + "/google.devtools.clouderrorreporting.v1beta1.ErrorGroupService/GetGroup", + request_serializer=error_group_service.GetGroupRequest.serialize, + response_deserializer=common.ErrorGroup.deserialize, + ) + return self._stubs["get_group"] + + @property + def update_group( + self, + ) -> Callable[[error_group_service.UpdateGroupRequest], common.ErrorGroup]: + r"""Return a callable for the update group method over gRPC. + + Replace the data for the specified group. + Fails if the group does not exist. + + Returns: + Callable[[~.UpdateGroupRequest], + ~.ErrorGroup]: + 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 "update_group" not in self._stubs: + self._stubs["update_group"] = self.grpc_channel.unary_unary( + "/google.devtools.clouderrorreporting.v1beta1.ErrorGroupService/UpdateGroup", + request_serializer=error_group_service.UpdateGroupRequest.serialize, + response_deserializer=common.ErrorGroup.deserialize, + ) + return self._stubs["update_group"] + + +__all__ = ("ErrorGroupServiceGrpcTransport",) diff --git a/google/cloud/errorreporting_v1beta1/services/error_group_service/transports/grpc_asyncio.py b/google/cloud/errorreporting_v1beta1/services/error_group_service/transports/grpc_asyncio.py new file mode 100644 index 00000000..2386dd7f --- /dev/null +++ b/google/cloud/errorreporting_v1beta1/services/error_group_service/transports/grpc_asyncio.py @@ -0,0 +1,264 @@ +# -*- 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. +# + +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import gapic_v1 # type: ignore +from google.api_core import grpc_helpers_async # type: ignore +from google.auth import credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore +from grpc.experimental import aio # type: ignore + +from google.cloud.errorreporting_v1beta1.types import common +from google.cloud.errorreporting_v1beta1.types import error_group_service + +from .base import ErrorGroupServiceTransport, DEFAULT_CLIENT_INFO +from .grpc import ErrorGroupServiceGrpcTransport + + +class ErrorGroupServiceGrpcAsyncIOTransport(ErrorGroupServiceTransport): + """gRPC AsyncIO backend transport for ErrorGroupService. + + Service for retrieving and updating individual error groups. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "clouderrorreporting.googleapis.com", + credentials: credentials.Credentials = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + address (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + scopes = scopes or cls.AUTH_SCOPES + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "clouderrorreporting.googleapis.com", + credentials: credentials.Credentials = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: aio.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id=None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiate the transport. + + Args: + 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 + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[aio.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): The mutual TLS endpoint. If + provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or applicatin default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): A + callback to provide client SSL certificate bytes and private key + bytes, both in PEM format. It is ignored if ``api_mtls_endpoint`` + is None. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + if channel: + # Sanity check: Ensure that channel and credentials are not both + # provided. + credentials = False + + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + elif api_mtls_endpoint: + host = ( + api_mtls_endpoint + if ":" in api_mtls_endpoint + else api_mtls_endpoint + ":443" + ) + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + ssl_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + ssl_credentials = SslCredentials().ssl_credentials + + # create a new channel. The provided one is ignored. + self._grpc_channel = type(self).create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + ssl_credentials=ssl_credentials, + scopes=scopes or self.AUTH_SCOPES, + quota_project_id=quota_project_id, + ) + + # Run the base constructor. + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes or self.AUTH_SCOPES, + quota_project_id=quota_project_id, + client_info=client_info, + ) + + self._stubs = {} + + @property + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Sanity check: Only create a new channel if we do not already + # have one. + if not hasattr(self, "_grpc_channel"): + self._grpc_channel = self.create_channel( + self._host, credentials=self._credentials, + ) + + # Return the channel from cache. + return self._grpc_channel + + @property + def get_group( + self, + ) -> Callable[[error_group_service.GetGroupRequest], Awaitable[common.ErrorGroup]]: + r"""Return a callable for the get group method over gRPC. + + Get the specified group. + + Returns: + Callable[[~.GetGroupRequest], + Awaitable[~.ErrorGroup]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "get_group" not in self._stubs: + self._stubs["get_group"] = self.grpc_channel.unary_unary( + "/google.devtools.clouderrorreporting.v1beta1.ErrorGroupService/GetGroup", + request_serializer=error_group_service.GetGroupRequest.serialize, + response_deserializer=common.ErrorGroup.deserialize, + ) + return self._stubs["get_group"] + + @property + def update_group( + self, + ) -> Callable[ + [error_group_service.UpdateGroupRequest], Awaitable[common.ErrorGroup] + ]: + r"""Return a callable for the update group method over gRPC. + + Replace the data for the specified group. + Fails if the group does not exist. + + Returns: + Callable[[~.UpdateGroupRequest], + Awaitable[~.ErrorGroup]]: + 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 "update_group" not in self._stubs: + self._stubs["update_group"] = self.grpc_channel.unary_unary( + "/google.devtools.clouderrorreporting.v1beta1.ErrorGroupService/UpdateGroup", + request_serializer=error_group_service.UpdateGroupRequest.serialize, + response_deserializer=common.ErrorGroup.deserialize, + ) + return self._stubs["update_group"] + + +__all__ = ("ErrorGroupServiceGrpcAsyncIOTransport",) diff --git a/google/cloud/errorreporting_v1beta1/services/error_stats_service/__init__.py b/google/cloud/errorreporting_v1beta1/services/error_stats_service/__init__.py new file mode 100644 index 00000000..53872971 --- /dev/null +++ b/google/cloud/errorreporting_v1beta1/services/error_stats_service/__init__.py @@ -0,0 +1,24 @@ +# -*- 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. +# + +from .client import ErrorStatsServiceClient +from .async_client import ErrorStatsServiceAsyncClient + +__all__ = ( + "ErrorStatsServiceClient", + "ErrorStatsServiceAsyncClient", +) diff --git a/google/cloud/errorreporting_v1beta1/services/error_stats_service/async_client.py b/google/cloud/errorreporting_v1beta1/services/error_stats_service/async_client.py new file mode 100644 index 00000000..96fd687e --- /dev/null +++ b/google/cloud/errorreporting_v1beta1/services/error_stats_service/async_client.py @@ -0,0 +1,385 @@ +# -*- 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. +# + +from collections import OrderedDict +import functools +import re +from typing import Dict, Sequence, Tuple, Type, Union +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 gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.cloud.errorreporting_v1beta1.services.error_stats_service import pagers +from google.cloud.errorreporting_v1beta1.types import common +from google.cloud.errorreporting_v1beta1.types import error_stats_service + +from .transports.base import ErrorStatsServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc_asyncio import ErrorStatsServiceGrpcAsyncIOTransport +from .client import ErrorStatsServiceClient + + +class ErrorStatsServiceAsyncClient: + """An API for retrieving and managing error statistics as well + as data for individual events. + """ + + _client: ErrorStatsServiceClient + + DEFAULT_ENDPOINT = ErrorStatsServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = ErrorStatsServiceClient.DEFAULT_MTLS_ENDPOINT + + from_service_account_file = ErrorStatsServiceClient.from_service_account_file + from_service_account_json = from_service_account_file + + get_transport_class = functools.partial( + type(ErrorStatsServiceClient).get_transport_class, type(ErrorStatsServiceClient) + ) + + def __init__( + self, + *, + credentials: credentials.Credentials = None, + transport: Union[str, ErrorStatsServiceTransport] = "grpc_asyncio", + client_options: ClientOptions = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiate the error stats service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, ~.ErrorStatsServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (ClientOptions): Custom options for the client. It + won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint, this is the default value for + the environment variable) and "auto" (auto switch to the default + mTLS endpoint if client SSL credentials is present). However, + the ``api_endpoint`` property takes precedence if provided. + (2) The ``client_cert_source`` property is used to provide client + SSL credentials for mutual TLS transport. If not provided, the + default SSL credentials will be used if present. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + + self._client = ErrorStatsServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + async def list_group_stats( + self, + request: error_stats_service.ListGroupStatsRequest = None, + *, + project_name: str = None, + time_range: error_stats_service.QueryTimeRange = None, + retry: retries.Retry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ListGroupStatsAsyncPager: + r"""Lists the specified groups. + + Args: + request (:class:`~.error_stats_service.ListGroupStatsRequest`): + The request object. Specifies a set of `ErrorGroupStats` + to return. + project_name (:class:`str`): + Required. The resource name of the + Google Cloud Platform project. Written + as projects/ plus the Google + Cloud Platform project ID. + + Example: projects/my- + project-123. + This corresponds to the ``project_name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + time_range (:class:`~.error_stats_service.QueryTimeRange`): + Optional. List data for the given time range. If not + set, a default time range is used. The field + time_range_begin in the response will specify the + beginning of this time range. Only ErrorGroupStats with + a non-zero count in the given time range are returned, + unless the request contains an explicit group_id list. + If a group_id list is given, also ErrorGroupStats with + zero occurrences are returned. + This corresponds to the ``time_range`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.pagers.ListGroupStatsAsyncPager: + Contains a set of requested error + group stats. + Iterating over this object will yield + results and resolve additional pages + automatically. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + if request is not None and any([project_name, time_range]): + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = error_stats_service.ListGroupStatsRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + + if project_name is not None: + request.project_name = project_name + if time_range is not None: + request.time_range = time_range + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.list_group_stats, + 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( + (("project_name", request.project_name),) + ), + ) + + # Send the request. + response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # This method is paged; wrap the response in a pager, which provides + # an `__aiter__` convenience method. + response = pagers.ListGroupStatsAsyncPager( + method=rpc, request=request, response=response, metadata=metadata, + ) + + # Done; return the response. + return response + + async def list_events( + self, + request: error_stats_service.ListEventsRequest = None, + *, + project_name: str = None, + group_id: str = None, + retry: retries.Retry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ListEventsAsyncPager: + r"""Lists the specified events. + + Args: + request (:class:`~.error_stats_service.ListEventsRequest`): + The request object. Specifies a set of error events to + return. + project_name (:class:`str`): + Required. The resource name of the Google Cloud Platform + project. Written as ``projects/`` plus the `Google Cloud + Platform project + ID `__. + Example: ``projects/my-project-123``. + This corresponds to the ``project_name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + group_id (:class:`str`): + Required. The group for which events + shall be returned. + This corresponds to the ``group_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.pagers.ListEventsAsyncPager: + Contains a set of requested error + events. + Iterating over this object will yield + results and resolve additional pages + automatically. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + if request is not None and any([project_name, group_id]): + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = error_stats_service.ListEventsRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + + if project_name is not None: + request.project_name = project_name + if group_id is not None: + request.group_id = group_id + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.list_events, + 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( + (("project_name", request.project_name),) + ), + ) + + # Send the request. + response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # This method is paged; wrap the response in a pager, which provides + # an `__aiter__` convenience method. + response = pagers.ListEventsAsyncPager( + method=rpc, request=request, response=response, metadata=metadata, + ) + + # Done; return the response. + return response + + async def delete_events( + self, + request: error_stats_service.DeleteEventsRequest = None, + *, + project_name: str = None, + retry: retries.Retry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> error_stats_service.DeleteEventsResponse: + r"""Deletes all error events of a given project. + + Args: + request (:class:`~.error_stats_service.DeleteEventsRequest`): + The request object. Deletes all events in the project. + project_name (:class:`str`): + Required. The resource name of the Google Cloud Platform + project. Written as ``projects/`` plus the `Google Cloud + Platform project + ID `__. + Example: ``projects/my-project-123``. + This corresponds to the ``project_name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.error_stats_service.DeleteEventsResponse: + Response message for deleting error + events. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + if request is not None and any([project_name]): + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = error_stats_service.DeleteEventsRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + + if project_name is not None: + request.project_name = project_name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.delete_events, + 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( + (("project_name", request.project_name),) + ), + ) + + # Send the request. + response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution( + "google-cloud-errorreporting", + ).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("ErrorStatsServiceAsyncClient",) diff --git a/google/cloud/errorreporting_v1beta1/services/error_stats_service/client.py b/google/cloud/errorreporting_v1beta1/services/error_stats_service/client.py new file mode 100644 index 00000000..52df793a --- /dev/null +++ b/google/cloud/errorreporting_v1beta1/services/error_stats_service/client.py @@ -0,0 +1,522 @@ +# -*- 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. +# + +from collections import OrderedDict +import os +import re +from typing import Callable, Dict, Sequence, Tuple, Type, Union +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 gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.cloud.errorreporting_v1beta1.services.error_stats_service import pagers +from google.cloud.errorreporting_v1beta1.types import common +from google.cloud.errorreporting_v1beta1.types import error_stats_service + +from .transports.base import ErrorStatsServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import ErrorStatsServiceGrpcTransport +from .transports.grpc_asyncio import ErrorStatsServiceGrpcAsyncIOTransport + + +class ErrorStatsServiceClientMeta(type): + """Metaclass for the ErrorStatsService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[ErrorStatsServiceTransport]] + _transport_registry["grpc"] = ErrorStatsServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ErrorStatsServiceGrpcAsyncIOTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[ErrorStatsServiceTransport]: + """Return an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class ErrorStatsServiceClient(metaclass=ErrorStatsServiceClientMeta): + """An API for retrieving and managing error statistics as well + as data for individual events. + """ + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Convert api endpoint to mTLS endpoint. + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "clouderrorreporting.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + {@api.name}: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file(filename) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + def __init__( + self, + *, + credentials: credentials.Credentials = None, + transport: Union[str, ErrorStatsServiceTransport] = None, + client_options: ClientOptions = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiate the error stats service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, ~.ErrorStatsServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (ClientOptions): Custom options for the client. It + won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint, this is the default value for + the environment variable) and "auto" (auto switch to the default + mTLS endpoint if client SSL credentials is present). However, + the ``api_endpoint`` property takes precedence if provided. + (2) The ``client_cert_source`` property is used to provide client + SSL credentials for mutual TLS transport. If not provided, the + default SSL credentials will be used if present. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = ClientOptions.from_dict(client_options) + if client_options is None: + client_options = ClientOptions.ClientOptions() + + if client_options.api_endpoint is None: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS", "never") + if use_mtls_env == "never": + client_options.api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + client_options.api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + has_client_cert_source = ( + client_options.client_cert_source is not None + or mtls.has_default_client_cert_source() + ) + client_options.api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if has_client_cert_source + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS value. Accepted values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, ErrorStatsServiceTransport): + # transport is a ErrorStatsServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, " + "provide its scopes directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=client_options.api_endpoint, + scopes=client_options.scopes, + api_mtls_endpoint=client_options.api_endpoint, + client_cert_source=client_options.client_cert_source, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + ) + + def list_group_stats( + self, + request: error_stats_service.ListGroupStatsRequest = None, + *, + project_name: str = None, + time_range: error_stats_service.QueryTimeRange = None, + retry: retries.Retry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ListGroupStatsPager: + r"""Lists the specified groups. + + Args: + request (:class:`~.error_stats_service.ListGroupStatsRequest`): + The request object. Specifies a set of `ErrorGroupStats` + to return. + project_name (:class:`str`): + Required. The resource name of the + Google Cloud Platform project. Written + as projects/ plus the Google + Cloud Platform project ID. + + Example: projects/my- + project-123. + This corresponds to the ``project_name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + time_range (:class:`~.error_stats_service.QueryTimeRange`): + Optional. List data for the given time range. If not + set, a default time range is used. The field + time_range_begin in the response will specify the + beginning of this time range. Only ErrorGroupStats with + a non-zero count in the given time range are returned, + unless the request contains an explicit group_id list. + If a group_id list is given, also ErrorGroupStats with + zero occurrences are returned. + This corresponds to the ``time_range`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.pagers.ListGroupStatsPager: + Contains a set of requested error + group stats. + Iterating over this object will yield + results and resolve additional pages + automatically. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([project_name, time_range]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a error_stats_service.ListGroupStatsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, error_stats_service.ListGroupStatsRequest): + request = error_stats_service.ListGroupStatsRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + + if project_name is not None: + request.project_name = project_name + if time_range is not None: + request.time_range = time_range + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.list_group_stats] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("project_name", request.project_name),) + ), + ) + + # Send the request. + response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # This method is paged; wrap the response in a pager, which provides + # an `__iter__` convenience method. + response = pagers.ListGroupStatsPager( + method=rpc, request=request, response=response, metadata=metadata, + ) + + # Done; return the response. + return response + + def list_events( + self, + request: error_stats_service.ListEventsRequest = None, + *, + project_name: str = None, + group_id: str = None, + retry: retries.Retry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ListEventsPager: + r"""Lists the specified events. + + Args: + request (:class:`~.error_stats_service.ListEventsRequest`): + The request object. Specifies a set of error events to + return. + project_name (:class:`str`): + Required. The resource name of the Google Cloud Platform + project. Written as ``projects/`` plus the `Google Cloud + Platform project + ID `__. + Example: ``projects/my-project-123``. + This corresponds to the ``project_name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + group_id (:class:`str`): + Required. The group for which events + shall be returned. + This corresponds to the ``group_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.pagers.ListEventsPager: + Contains a set of requested error + events. + Iterating over this object will yield + results and resolve additional pages + automatically. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([project_name, group_id]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a error_stats_service.ListEventsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, error_stats_service.ListEventsRequest): + request = error_stats_service.ListEventsRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + + if project_name is not None: + request.project_name = project_name + if group_id is not None: + request.group_id = group_id + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.list_events] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("project_name", request.project_name),) + ), + ) + + # Send the request. + response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # This method is paged; wrap the response in a pager, which provides + # an `__iter__` convenience method. + response = pagers.ListEventsPager( + method=rpc, request=request, response=response, metadata=metadata, + ) + + # Done; return the response. + return response + + def delete_events( + self, + request: error_stats_service.DeleteEventsRequest = None, + *, + project_name: str = None, + retry: retries.Retry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> error_stats_service.DeleteEventsResponse: + r"""Deletes all error events of a given project. + + Args: + request (:class:`~.error_stats_service.DeleteEventsRequest`): + The request object. Deletes all events in the project. + project_name (:class:`str`): + Required. The resource name of the Google Cloud Platform + project. Written as ``projects/`` plus the `Google Cloud + Platform project + ID `__. + Example: ``projects/my-project-123``. + This corresponds to the ``project_name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.error_stats_service.DeleteEventsResponse: + Response message for deleting error + events. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([project_name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a error_stats_service.DeleteEventsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, error_stats_service.DeleteEventsRequest): + request = error_stats_service.DeleteEventsRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + + if project_name is not None: + request.project_name = project_name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.delete_events] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("project_name", request.project_name),) + ), + ) + + # Send the request. + response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution( + "google-cloud-errorreporting", + ).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("ErrorStatsServiceClient",) diff --git a/google/cloud/errorreporting_v1beta1/services/error_stats_service/pagers.py b/google/cloud/errorreporting_v1beta1/services/error_stats_service/pagers.py new file mode 100644 index 00000000..02a4faa4 --- /dev/null +++ b/google/cloud/errorreporting_v1beta1/services/error_stats_service/pagers.py @@ -0,0 +1,277 @@ +# -*- 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. +# + +from typing import Any, AsyncIterable, Awaitable, Callable, Iterable, Sequence, Tuple + +from google.cloud.errorreporting_v1beta1.types import common +from google.cloud.errorreporting_v1beta1.types import error_stats_service + + +class ListGroupStatsPager: + """A pager for iterating through ``list_group_stats`` requests. + + This class thinly wraps an initial + :class:`~.error_stats_service.ListGroupStatsResponse` object, and + provides an ``__iter__`` method to iterate through its + ``error_group_stats`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListGroupStats`` requests and continue to iterate + through the ``error_group_stats`` field on the + corresponding responses. + + All the usual :class:`~.error_stats_service.ListGroupStatsResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + + def __init__( + self, + method: Callable[..., error_stats_service.ListGroupStatsResponse], + request: error_stats_service.ListGroupStatsRequest, + response: error_stats_service.ListGroupStatsResponse, + *, + metadata: Sequence[Tuple[str, str]] = () + ): + """Instantiate the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (:class:`~.error_stats_service.ListGroupStatsRequest`): + The initial request object. + response (:class:`~.error_stats_service.ListGroupStatsResponse`): + The initial response object. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = error_stats_service.ListGroupStatsRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages(self) -> Iterable[error_stats_service.ListGroupStatsResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = self._method(self._request, metadata=self._metadata) + yield self._response + + def __iter__(self) -> Iterable[error_stats_service.ErrorGroupStats]: + for page in self.pages: + yield from page.error_group_stats + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) + + +class ListGroupStatsAsyncPager: + """A pager for iterating through ``list_group_stats`` requests. + + This class thinly wraps an initial + :class:`~.error_stats_service.ListGroupStatsResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``error_group_stats`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``ListGroupStats`` requests and continue to iterate + through the ``error_group_stats`` field on the + corresponding responses. + + All the usual :class:`~.error_stats_service.ListGroupStatsResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + + def __init__( + self, + method: Callable[..., Awaitable[error_stats_service.ListGroupStatsResponse]], + request: error_stats_service.ListGroupStatsRequest, + response: error_stats_service.ListGroupStatsResponse, + *, + metadata: Sequence[Tuple[str, str]] = () + ): + """Instantiate the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (:class:`~.error_stats_service.ListGroupStatsRequest`): + The initial request object. + response (:class:`~.error_stats_service.ListGroupStatsResponse`): + The initial response object. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = error_stats_service.ListGroupStatsRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages(self) -> AsyncIterable[error_stats_service.ListGroupStatsResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = await self._method(self._request, metadata=self._metadata) + yield self._response + + def __aiter__(self) -> AsyncIterable[error_stats_service.ErrorGroupStats]: + async def async_generator(): + async for page in self.pages: + for response in page.error_group_stats: + yield response + + return async_generator() + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) + + +class ListEventsPager: + """A pager for iterating through ``list_events`` requests. + + This class thinly wraps an initial + :class:`~.error_stats_service.ListEventsResponse` object, and + provides an ``__iter__`` method to iterate through its + ``error_events`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListEvents`` requests and continue to iterate + through the ``error_events`` field on the + corresponding responses. + + All the usual :class:`~.error_stats_service.ListEventsResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + + def __init__( + self, + method: Callable[..., error_stats_service.ListEventsResponse], + request: error_stats_service.ListEventsRequest, + response: error_stats_service.ListEventsResponse, + *, + metadata: Sequence[Tuple[str, str]] = () + ): + """Instantiate the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (:class:`~.error_stats_service.ListEventsRequest`): + The initial request object. + response (:class:`~.error_stats_service.ListEventsResponse`): + The initial response object. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = error_stats_service.ListEventsRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages(self) -> Iterable[error_stats_service.ListEventsResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = self._method(self._request, metadata=self._metadata) + yield self._response + + def __iter__(self) -> Iterable[common.ErrorEvent]: + for page in self.pages: + yield from page.error_events + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) + + +class ListEventsAsyncPager: + """A pager for iterating through ``list_events`` requests. + + This class thinly wraps an initial + :class:`~.error_stats_service.ListEventsResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``error_events`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``ListEvents`` requests and continue to iterate + through the ``error_events`` field on the + corresponding responses. + + All the usual :class:`~.error_stats_service.ListEventsResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + + def __init__( + self, + method: Callable[..., Awaitable[error_stats_service.ListEventsResponse]], + request: error_stats_service.ListEventsRequest, + response: error_stats_service.ListEventsResponse, + *, + metadata: Sequence[Tuple[str, str]] = () + ): + """Instantiate the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (:class:`~.error_stats_service.ListEventsRequest`): + The initial request object. + response (:class:`~.error_stats_service.ListEventsResponse`): + The initial response object. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = error_stats_service.ListEventsRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages(self) -> AsyncIterable[error_stats_service.ListEventsResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = await self._method(self._request, metadata=self._metadata) + yield self._response + + def __aiter__(self) -> AsyncIterable[common.ErrorEvent]: + async def async_generator(): + async for page in self.pages: + for response in page.error_events: + yield response + + return async_generator() + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) diff --git a/google/cloud/errorreporting_v1beta1/services/error_stats_service/transports/__init__.py b/google/cloud/errorreporting_v1beta1/services/error_stats_service/transports/__init__.py new file mode 100644 index 00000000..58886966 --- /dev/null +++ b/google/cloud/errorreporting_v1beta1/services/error_stats_service/transports/__init__.py @@ -0,0 +1,36 @@ +# -*- 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. +# + +from collections import OrderedDict +from typing import Dict, Type + +from .base import ErrorStatsServiceTransport +from .grpc import ErrorStatsServiceGrpcTransport +from .grpc_asyncio import ErrorStatsServiceGrpcAsyncIOTransport + + +# Compile a registry of transports. +_transport_registry = OrderedDict() # type: Dict[str, Type[ErrorStatsServiceTransport]] +_transport_registry["grpc"] = ErrorStatsServiceGrpcTransport +_transport_registry["grpc_asyncio"] = ErrorStatsServiceGrpcAsyncIOTransport + + +__all__ = ( + "ErrorStatsServiceTransport", + "ErrorStatsServiceGrpcTransport", + "ErrorStatsServiceGrpcAsyncIOTransport", +) diff --git a/google/cloud/errorreporting_v1beta1/services/error_stats_service/transports/base.py b/google/cloud/errorreporting_v1beta1/services/error_stats_service/transports/base.py new file mode 100644 index 00000000..9ee79c34 --- /dev/null +++ b/google/cloud/errorreporting_v1beta1/services/error_stats_service/transports/base.py @@ -0,0 +1,157 @@ +# -*- 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. +# + +import abc +import typing +import pkg_resources + +from google import auth # type: ignore +from google.api_core import 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.cloud.errorreporting_v1beta1.types import error_stats_service + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution( + "google-cloud-errorreporting", + ).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class ErrorStatsServiceTransport(abc.ABC): + """Abstract transport class for ErrorStatsService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/cloud-platform",) + + def __init__( + self, + *, + host: str = "clouderrorreporting.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, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + 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 + are specified, the client will attempt to ascertain the + credentials from the environment. + 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. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = auth.load_credentials_from_file( + credentials_file, scopes=scopes, quota_project_id=quota_project_id + ) + + elif credentials is None: + credentials, _ = auth.default( + scopes=scopes, quota_project_id=quota_project_id + ) + + # Save the credentials. + self._credentials = credentials + + # Lifted into its own function so it can be stubbed out during tests. + self._prep_wrapped_messages(client_info) + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.list_group_stats: gapic_v1.method.wrap_method( + self.list_group_stats, default_timeout=None, client_info=client_info, + ), + self.list_events: gapic_v1.method.wrap_method( + self.list_events, default_timeout=None, client_info=client_info, + ), + self.delete_events: gapic_v1.method.wrap_method( + self.delete_events, default_timeout=None, client_info=client_info, + ), + } + + @property + def list_group_stats( + self, + ) -> typing.Callable[ + [error_stats_service.ListGroupStatsRequest], + typing.Union[ + error_stats_service.ListGroupStatsResponse, + typing.Awaitable[error_stats_service.ListGroupStatsResponse], + ], + ]: + raise NotImplementedError() + + @property + def list_events( + self, + ) -> typing.Callable[ + [error_stats_service.ListEventsRequest], + typing.Union[ + error_stats_service.ListEventsResponse, + typing.Awaitable[error_stats_service.ListEventsResponse], + ], + ]: + raise NotImplementedError() + + @property + def delete_events( + self, + ) -> typing.Callable[ + [error_stats_service.DeleteEventsRequest], + typing.Union[ + error_stats_service.DeleteEventsResponse, + typing.Awaitable[error_stats_service.DeleteEventsResponse], + ], + ]: + raise NotImplementedError() + + +__all__ = ("ErrorStatsServiceTransport",) diff --git a/google/cloud/errorreporting_v1beta1/services/error_stats_service/transports/grpc.py b/google/cloud/errorreporting_v1beta1/services/error_stats_service/transports/grpc.py new file mode 100644 index 00000000..37bfe51c --- /dev/null +++ b/google/cloud/errorreporting_v1beta1/services/error_stats_service/transports/grpc.py @@ -0,0 +1,302 @@ +# -*- 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. +# + +from typing import Callable, Dict, Optional, Sequence, Tuple + +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 +from google.auth.transport.grpc import SslCredentials # type: ignore + + +import grpc # type: ignore + +from google.cloud.errorreporting_v1beta1.types import error_stats_service + +from .base import ErrorStatsServiceTransport, DEFAULT_CLIENT_INFO + + +class ErrorStatsServiceGrpcTransport(ErrorStatsServiceTransport): + """gRPC backend transport for ErrorStatsService. + + An API for retrieving and managing error statistics as well + as data for individual events. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "clouderrorreporting.googleapis.com", + credentials: credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiate the transport. + + Args: + 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 + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): The mutual TLS endpoint. If + provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or applicatin default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): A + callback to provide client SSL certificate bytes and private key + bytes, both in PEM format. It is ignored if ``api_mtls_endpoint`` + is None. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + if channel: + # Sanity check: Ensure that channel and credentials are not both + # provided. + credentials = False + + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + elif api_mtls_endpoint: + host = ( + api_mtls_endpoint + if ":" in api_mtls_endpoint + else api_mtls_endpoint + ":443" + ) + + if credentials is None: + credentials, _ = auth.default( + scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id + ) + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + ssl_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + ssl_credentials = SslCredentials().ssl_credentials + + # create a new channel. The provided one is ignored. + self._grpc_channel = type(self).create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + ssl_credentials=ssl_credentials, + scopes=scopes or self.AUTH_SCOPES, + quota_project_id=quota_project_id, + ) + + self._stubs = {} # type: Dict[str, Callable] + + # Run the base constructor. + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes or self.AUTH_SCOPES, + quota_project_id=quota_project_id, + client_info=client_info, + ) + + @classmethod + def create_channel( + cls, + host: str = "clouderrorreporting.googleapis.com", + credentials: credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + address (Optionsl[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + 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. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + scopes = scopes or cls.AUTH_SCOPES + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Sanity check: Only create a new channel if we do not already + # have one. + if not hasattr(self, "_grpc_channel"): + self._grpc_channel = self.create_channel( + self._host, credentials=self._credentials, + ) + + # Return the channel from cache. + return self._grpc_channel + + @property + def list_group_stats( + self, + ) -> Callable[ + [error_stats_service.ListGroupStatsRequest], + error_stats_service.ListGroupStatsResponse, + ]: + r"""Return a callable for the list group stats method over gRPC. + + Lists the specified groups. + + Returns: + Callable[[~.ListGroupStatsRequest], + ~.ListGroupStatsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_group_stats" not in self._stubs: + self._stubs["list_group_stats"] = self.grpc_channel.unary_unary( + "/google.devtools.clouderrorreporting.v1beta1.ErrorStatsService/ListGroupStats", + request_serializer=error_stats_service.ListGroupStatsRequest.serialize, + response_deserializer=error_stats_service.ListGroupStatsResponse.deserialize, + ) + return self._stubs["list_group_stats"] + + @property + def list_events( + self, + ) -> Callable[ + [error_stats_service.ListEventsRequest], error_stats_service.ListEventsResponse + ]: + r"""Return a callable for the list events method over gRPC. + + Lists the specified events. + + Returns: + Callable[[~.ListEventsRequest], + ~.ListEventsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_events" not in self._stubs: + self._stubs["list_events"] = self.grpc_channel.unary_unary( + "/google.devtools.clouderrorreporting.v1beta1.ErrorStatsService/ListEvents", + request_serializer=error_stats_service.ListEventsRequest.serialize, + response_deserializer=error_stats_service.ListEventsResponse.deserialize, + ) + return self._stubs["list_events"] + + @property + def delete_events( + self, + ) -> Callable[ + [error_stats_service.DeleteEventsRequest], + error_stats_service.DeleteEventsResponse, + ]: + r"""Return a callable for the delete events method over gRPC. + + Deletes all error events of a given project. + + Returns: + Callable[[~.DeleteEventsRequest], + ~.DeleteEventsResponse]: + 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 "delete_events" not in self._stubs: + self._stubs["delete_events"] = self.grpc_channel.unary_unary( + "/google.devtools.clouderrorreporting.v1beta1.ErrorStatsService/DeleteEvents", + request_serializer=error_stats_service.DeleteEventsRequest.serialize, + response_deserializer=error_stats_service.DeleteEventsResponse.deserialize, + ) + return self._stubs["delete_events"] + + +__all__ = ("ErrorStatsServiceGrpcTransport",) diff --git a/google/cloud/errorreporting_v1beta1/services/error_stats_service/transports/grpc_asyncio.py b/google/cloud/errorreporting_v1beta1/services/error_stats_service/transports/grpc_asyncio.py new file mode 100644 index 00000000..16ba1ba8 --- /dev/null +++ b/google/cloud/errorreporting_v1beta1/services/error_stats_service/transports/grpc_asyncio.py @@ -0,0 +1,296 @@ +# -*- 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. +# + +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import gapic_v1 # type: ignore +from google.api_core import grpc_helpers_async # type: ignore +from google.auth import credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore +from grpc.experimental import aio # type: ignore + +from google.cloud.errorreporting_v1beta1.types import error_stats_service + +from .base import ErrorStatsServiceTransport, DEFAULT_CLIENT_INFO +from .grpc import ErrorStatsServiceGrpcTransport + + +class ErrorStatsServiceGrpcAsyncIOTransport(ErrorStatsServiceTransport): + """gRPC AsyncIO backend transport for ErrorStatsService. + + An API for retrieving and managing error statistics as well + as data for individual events. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "clouderrorreporting.googleapis.com", + credentials: credentials.Credentials = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + address (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + scopes = scopes or cls.AUTH_SCOPES + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "clouderrorreporting.googleapis.com", + credentials: credentials.Credentials = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: aio.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id=None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiate the transport. + + Args: + 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 + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[aio.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): The mutual TLS endpoint. If + provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or applicatin default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): A + callback to provide client SSL certificate bytes and private key + bytes, both in PEM format. It is ignored if ``api_mtls_endpoint`` + is None. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + if channel: + # Sanity check: Ensure that channel and credentials are not both + # provided. + credentials = False + + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + elif api_mtls_endpoint: + host = ( + api_mtls_endpoint + if ":" in api_mtls_endpoint + else api_mtls_endpoint + ":443" + ) + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + ssl_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + ssl_credentials = SslCredentials().ssl_credentials + + # create a new channel. The provided one is ignored. + self._grpc_channel = type(self).create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + ssl_credentials=ssl_credentials, + scopes=scopes or self.AUTH_SCOPES, + quota_project_id=quota_project_id, + ) + + # Run the base constructor. + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes or self.AUTH_SCOPES, + quota_project_id=quota_project_id, + client_info=client_info, + ) + + self._stubs = {} + + @property + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Sanity check: Only create a new channel if we do not already + # have one. + if not hasattr(self, "_grpc_channel"): + self._grpc_channel = self.create_channel( + self._host, credentials=self._credentials, + ) + + # Return the channel from cache. + return self._grpc_channel + + @property + def list_group_stats( + self, + ) -> Callable[ + [error_stats_service.ListGroupStatsRequest], + Awaitable[error_stats_service.ListGroupStatsResponse], + ]: + r"""Return a callable for the list group stats method over gRPC. + + Lists the specified groups. + + Returns: + Callable[[~.ListGroupStatsRequest], + Awaitable[~.ListGroupStatsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_group_stats" not in self._stubs: + self._stubs["list_group_stats"] = self.grpc_channel.unary_unary( + "/google.devtools.clouderrorreporting.v1beta1.ErrorStatsService/ListGroupStats", + request_serializer=error_stats_service.ListGroupStatsRequest.serialize, + response_deserializer=error_stats_service.ListGroupStatsResponse.deserialize, + ) + return self._stubs["list_group_stats"] + + @property + def list_events( + self, + ) -> Callable[ + [error_stats_service.ListEventsRequest], + Awaitable[error_stats_service.ListEventsResponse], + ]: + r"""Return a callable for the list events method over gRPC. + + Lists the specified events. + + Returns: + Callable[[~.ListEventsRequest], + Awaitable[~.ListEventsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_events" not in self._stubs: + self._stubs["list_events"] = self.grpc_channel.unary_unary( + "/google.devtools.clouderrorreporting.v1beta1.ErrorStatsService/ListEvents", + request_serializer=error_stats_service.ListEventsRequest.serialize, + response_deserializer=error_stats_service.ListEventsResponse.deserialize, + ) + return self._stubs["list_events"] + + @property + def delete_events( + self, + ) -> Callable[ + [error_stats_service.DeleteEventsRequest], + Awaitable[error_stats_service.DeleteEventsResponse], + ]: + r"""Return a callable for the delete events method over gRPC. + + Deletes all error events of a given project. + + Returns: + Callable[[~.DeleteEventsRequest], + Awaitable[~.DeleteEventsResponse]]: + 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 "delete_events" not in self._stubs: + self._stubs["delete_events"] = self.grpc_channel.unary_unary( + "/google.devtools.clouderrorreporting.v1beta1.ErrorStatsService/DeleteEvents", + request_serializer=error_stats_service.DeleteEventsRequest.serialize, + response_deserializer=error_stats_service.DeleteEventsResponse.deserialize, + ) + return self._stubs["delete_events"] + + +__all__ = ("ErrorStatsServiceGrpcAsyncIOTransport",) diff --git a/google/cloud/errorreporting_v1beta1/services/report_errors_service/__init__.py b/google/cloud/errorreporting_v1beta1/services/report_errors_service/__init__.py new file mode 100644 index 00000000..0a9dd71e --- /dev/null +++ b/google/cloud/errorreporting_v1beta1/services/report_errors_service/__init__.py @@ -0,0 +1,24 @@ +# -*- 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. +# + +from .client import ReportErrorsServiceClient +from .async_client import ReportErrorsServiceAsyncClient + +__all__ = ( + "ReportErrorsServiceClient", + "ReportErrorsServiceAsyncClient", +) diff --git a/google/cloud/errorreporting_v1beta1/services/report_errors_service/async_client.py b/google/cloud/errorreporting_v1beta1/services/report_errors_service/async_client.py new file mode 100644 index 00000000..a1c281ac --- /dev/null +++ b/google/cloud/errorreporting_v1beta1/services/report_errors_service/async_client.py @@ -0,0 +1,203 @@ +# -*- 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. +# + +from collections import OrderedDict +import functools +import re +from typing import Dict, Sequence, Tuple, Type, Union +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 gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.cloud.errorreporting_v1beta1.types import report_errors_service + +from .transports.base import ReportErrorsServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc_asyncio import ReportErrorsServiceGrpcAsyncIOTransport +from .client import ReportErrorsServiceClient + + +class ReportErrorsServiceAsyncClient: + """An API for reporting error events.""" + + _client: ReportErrorsServiceClient + + DEFAULT_ENDPOINT = ReportErrorsServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = ReportErrorsServiceClient.DEFAULT_MTLS_ENDPOINT + + from_service_account_file = ReportErrorsServiceClient.from_service_account_file + from_service_account_json = from_service_account_file + + get_transport_class = functools.partial( + type(ReportErrorsServiceClient).get_transport_class, + type(ReportErrorsServiceClient), + ) + + def __init__( + self, + *, + credentials: credentials.Credentials = None, + transport: Union[str, ReportErrorsServiceTransport] = "grpc_asyncio", + client_options: ClientOptions = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiate the report errors service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, ~.ReportErrorsServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (ClientOptions): Custom options for the client. It + won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint, this is the default value for + the environment variable) and "auto" (auto switch to the default + mTLS endpoint if client SSL credentials is present). However, + the ``api_endpoint`` property takes precedence if provided. + (2) The ``client_cert_source`` property is used to provide client + SSL credentials for mutual TLS transport. If not provided, the + default SSL credentials will be used if present. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + + self._client = ReportErrorsServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + async def report_error_event( + self, + request: report_errors_service.ReportErrorEventRequest = None, + *, + project_name: str = None, + event: report_errors_service.ReportedErrorEvent = None, + retry: retries.Retry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> report_errors_service.ReportErrorEventResponse: + r"""Report an individual error event. + + This endpoint accepts **either** an OAuth token, **or** an `API + key `__ for + authentication. To use an API key, append it to the URL as the + value of a ``key`` parameter. For example: + + ``POST https://clouderrorreporting.googleapis.com/v1beta1/projects/example-project/events:report?key=123ABC456`` + + Args: + request (:class:`~.report_errors_service.ReportErrorEventRequest`): + The request object. A request for reporting an + individual error event. + project_name (:class:`str`): + Required. The resource name of the Google Cloud Platform + project. Written as ``projects/`` plus the `Google Cloud + Platform project + ID `__. + Example: ``projects/my-project-123``. + This corresponds to the ``project_name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + event (:class:`~.report_errors_service.ReportedErrorEvent`): + Required. The error event to be + reported. + This corresponds to the ``event`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.report_errors_service.ReportErrorEventResponse: + Response for reporting an individual + error event. Data may be added to this + message in the future. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + if request is not None and any([project_name, event]): + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = report_errors_service.ReportErrorEventRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + + if project_name is not None: + request.project_name = project_name + if event is not None: + request.event = event + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.report_error_event, + 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( + (("project_name", request.project_name),) + ), + ) + + # Send the request. + response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution( + "google-cloud-errorreporting", + ).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("ReportErrorsServiceAsyncClient",) diff --git a/google/cloud/errorreporting_v1beta1/services/report_errors_service/client.py b/google/cloud/errorreporting_v1beta1/services/report_errors_service/client.py new file mode 100644 index 00000000..04e07ce8 --- /dev/null +++ b/google/cloud/errorreporting_v1beta1/services/report_errors_service/client.py @@ -0,0 +1,335 @@ +# -*- 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. +# + +from collections import OrderedDict +import os +import re +from typing import Callable, Dict, Sequence, Tuple, Type, Union +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 gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.cloud.errorreporting_v1beta1.types import report_errors_service + +from .transports.base import ReportErrorsServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import ReportErrorsServiceGrpcTransport +from .transports.grpc_asyncio import ReportErrorsServiceGrpcAsyncIOTransport + + +class ReportErrorsServiceClientMeta(type): + """Metaclass for the ReportErrorsService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[ReportErrorsServiceTransport]] + _transport_registry["grpc"] = ReportErrorsServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ReportErrorsServiceGrpcAsyncIOTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[ReportErrorsServiceTransport]: + """Return an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class ReportErrorsServiceClient(metaclass=ReportErrorsServiceClientMeta): + """An API for reporting error events.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Convert api endpoint to mTLS endpoint. + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "clouderrorreporting.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + {@api.name}: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file(filename) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + def __init__( + self, + *, + credentials: credentials.Credentials = None, + transport: Union[str, ReportErrorsServiceTransport] = None, + client_options: ClientOptions = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiate the report errors service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, ~.ReportErrorsServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (ClientOptions): Custom options for the client. It + won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint, this is the default value for + the environment variable) and "auto" (auto switch to the default + mTLS endpoint if client SSL credentials is present). However, + the ``api_endpoint`` property takes precedence if provided. + (2) The ``client_cert_source`` property is used to provide client + SSL credentials for mutual TLS transport. If not provided, the + default SSL credentials will be used if present. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = ClientOptions.from_dict(client_options) + if client_options is None: + client_options = ClientOptions.ClientOptions() + + if client_options.api_endpoint is None: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS", "never") + if use_mtls_env == "never": + client_options.api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + client_options.api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + has_client_cert_source = ( + client_options.client_cert_source is not None + or mtls.has_default_client_cert_source() + ) + client_options.api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if has_client_cert_source + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS value. Accepted values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, ReportErrorsServiceTransport): + # transport is a ReportErrorsServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, " + "provide its scopes directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=client_options.api_endpoint, + scopes=client_options.scopes, + api_mtls_endpoint=client_options.api_endpoint, + client_cert_source=client_options.client_cert_source, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + ) + + def report_error_event( + self, + request: report_errors_service.ReportErrorEventRequest = None, + *, + project_name: str = None, + event: report_errors_service.ReportedErrorEvent = None, + retry: retries.Retry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> report_errors_service.ReportErrorEventResponse: + r"""Report an individual error event. + + This endpoint accepts **either** an OAuth token, **or** an `API + key `__ for + authentication. To use an API key, append it to the URL as the + value of a ``key`` parameter. For example: + + ``POST https://clouderrorreporting.googleapis.com/v1beta1/projects/example-project/events:report?key=123ABC456`` + + Args: + request (:class:`~.report_errors_service.ReportErrorEventRequest`): + The request object. A request for reporting an + individual error event. + project_name (:class:`str`): + Required. The resource name of the Google Cloud Platform + project. Written as ``projects/`` plus the `Google Cloud + Platform project + ID `__. + Example: ``projects/my-project-123``. + This corresponds to the ``project_name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + event (:class:`~.report_errors_service.ReportedErrorEvent`): + Required. The error event to be + reported. + This corresponds to the ``event`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.report_errors_service.ReportErrorEventResponse: + Response for reporting an individual + error event. Data may be added to this + message in the future. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([project_name, event]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a report_errors_service.ReportErrorEventRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, report_errors_service.ReportErrorEventRequest): + request = report_errors_service.ReportErrorEventRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + + if project_name is not None: + request.project_name = project_name + if event is not None: + request.event = event + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.report_error_event] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("project_name", request.project_name),) + ), + ) + + # Send the request. + response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution( + "google-cloud-errorreporting", + ).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("ReportErrorsServiceClient",) diff --git a/google/cloud/errorreporting_v1beta1/services/report_errors_service/transports/__init__.py b/google/cloud/errorreporting_v1beta1/services/report_errors_service/transports/__init__.py new file mode 100644 index 00000000..8226c948 --- /dev/null +++ b/google/cloud/errorreporting_v1beta1/services/report_errors_service/transports/__init__.py @@ -0,0 +1,38 @@ +# -*- 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. +# + +from collections import OrderedDict +from typing import Dict, Type + +from .base import ReportErrorsServiceTransport +from .grpc import ReportErrorsServiceGrpcTransport +from .grpc_asyncio import ReportErrorsServiceGrpcAsyncIOTransport + + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[ReportErrorsServiceTransport]] +_transport_registry["grpc"] = ReportErrorsServiceGrpcTransport +_transport_registry["grpc_asyncio"] = ReportErrorsServiceGrpcAsyncIOTransport + + +__all__ = ( + "ReportErrorsServiceTransport", + "ReportErrorsServiceGrpcTransport", + "ReportErrorsServiceGrpcAsyncIOTransport", +) diff --git a/google/cloud/errorreporting_v1beta1/services/report_errors_service/transports/base.py b/google/cloud/errorreporting_v1beta1/services/report_errors_service/transports/base.py new file mode 100644 index 00000000..f1a66243 --- /dev/null +++ b/google/cloud/errorreporting_v1beta1/services/report_errors_service/transports/base.py @@ -0,0 +1,127 @@ +# -*- 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. +# + +import abc +import typing +import pkg_resources + +from google import auth # type: ignore +from google.api_core import 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.cloud.errorreporting_v1beta1.types import report_errors_service + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution( + "google-cloud-errorreporting", + ).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class ReportErrorsServiceTransport(abc.ABC): + """Abstract transport class for ReportErrorsService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/cloud-platform",) + + def __init__( + self, + *, + host: str = "clouderrorreporting.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, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + 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 + are specified, the client will attempt to ascertain the + credentials from the environment. + 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. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = auth.load_credentials_from_file( + credentials_file, scopes=scopes, quota_project_id=quota_project_id + ) + + elif credentials is None: + credentials, _ = auth.default( + scopes=scopes, quota_project_id=quota_project_id + ) + + # Save the credentials. + self._credentials = credentials + + # Lifted into its own function so it can be stubbed out during tests. + self._prep_wrapped_messages(client_info) + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.report_error_event: gapic_v1.method.wrap_method( + self.report_error_event, default_timeout=None, client_info=client_info, + ), + } + + @property + def report_error_event( + self, + ) -> typing.Callable[ + [report_errors_service.ReportErrorEventRequest], + typing.Union[ + report_errors_service.ReportErrorEventResponse, + typing.Awaitable[report_errors_service.ReportErrorEventResponse], + ], + ]: + raise NotImplementedError() + + +__all__ = ("ReportErrorsServiceTransport",) diff --git a/google/cloud/errorreporting_v1beta1/services/report_errors_service/transports/grpc.py b/google/cloud/errorreporting_v1beta1/services/report_errors_service/transports/grpc.py new file mode 100644 index 00000000..c542ff0b --- /dev/null +++ b/google/cloud/errorreporting_v1beta1/services/report_errors_service/transports/grpc.py @@ -0,0 +1,251 @@ +# -*- 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. +# + +from typing import Callable, Dict, Optional, Sequence, Tuple + +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 +from google.auth.transport.grpc import SslCredentials # type: ignore + + +import grpc # type: ignore + +from google.cloud.errorreporting_v1beta1.types import report_errors_service + +from .base import ReportErrorsServiceTransport, DEFAULT_CLIENT_INFO + + +class ReportErrorsServiceGrpcTransport(ReportErrorsServiceTransport): + """gRPC backend transport for ReportErrorsService. + + An API for reporting error events. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "clouderrorreporting.googleapis.com", + credentials: credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiate the transport. + + Args: + 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 + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): The mutual TLS endpoint. If + provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or applicatin default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): A + callback to provide client SSL certificate bytes and private key + bytes, both in PEM format. It is ignored if ``api_mtls_endpoint`` + is None. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + if channel: + # Sanity check: Ensure that channel and credentials are not both + # provided. + credentials = False + + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + elif api_mtls_endpoint: + host = ( + api_mtls_endpoint + if ":" in api_mtls_endpoint + else api_mtls_endpoint + ":443" + ) + + if credentials is None: + credentials, _ = auth.default( + scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id + ) + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + ssl_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + ssl_credentials = SslCredentials().ssl_credentials + + # create a new channel. The provided one is ignored. + self._grpc_channel = type(self).create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + ssl_credentials=ssl_credentials, + scopes=scopes or self.AUTH_SCOPES, + quota_project_id=quota_project_id, + ) + + self._stubs = {} # type: Dict[str, Callable] + + # Run the base constructor. + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes or self.AUTH_SCOPES, + quota_project_id=quota_project_id, + client_info=client_info, + ) + + @classmethod + def create_channel( + cls, + host: str = "clouderrorreporting.googleapis.com", + credentials: credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + address (Optionsl[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + 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. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + scopes = scopes or cls.AUTH_SCOPES + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Sanity check: Only create a new channel if we do not already + # have one. + if not hasattr(self, "_grpc_channel"): + self._grpc_channel = self.create_channel( + self._host, credentials=self._credentials, + ) + + # Return the channel from cache. + return self._grpc_channel + + @property + def report_error_event( + self, + ) -> Callable[ + [report_errors_service.ReportErrorEventRequest], + report_errors_service.ReportErrorEventResponse, + ]: + r"""Return a callable for the report error event method over gRPC. + + Report an individual error event. + + This endpoint accepts **either** an OAuth token, **or** an `API + key `__ for + authentication. To use an API key, append it to the URL as the + value of a ``key`` parameter. For example: + + ``POST https://clouderrorreporting.googleapis.com/v1beta1/projects/example-project/events:report?key=123ABC456`` + + Returns: + Callable[[~.ReportErrorEventRequest], + ~.ReportErrorEventResponse]: + 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 "report_error_event" not in self._stubs: + self._stubs["report_error_event"] = self.grpc_channel.unary_unary( + "/google.devtools.clouderrorreporting.v1beta1.ReportErrorsService/ReportErrorEvent", + request_serializer=report_errors_service.ReportErrorEventRequest.serialize, + response_deserializer=report_errors_service.ReportErrorEventResponse.deserialize, + ) + return self._stubs["report_error_event"] + + +__all__ = ("ReportErrorsServiceGrpcTransport",) diff --git a/google/cloud/errorreporting_v1beta1/services/report_errors_service/transports/grpc_asyncio.py b/google/cloud/errorreporting_v1beta1/services/report_errors_service/transports/grpc_asyncio.py new file mode 100644 index 00000000..b0ed1fba --- /dev/null +++ b/google/cloud/errorreporting_v1beta1/services/report_errors_service/transports/grpc_asyncio.py @@ -0,0 +1,244 @@ +# -*- 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. +# + +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import gapic_v1 # type: ignore +from google.api_core import grpc_helpers_async # type: ignore +from google.auth import credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore +from grpc.experimental import aio # type: ignore + +from google.cloud.errorreporting_v1beta1.types import report_errors_service + +from .base import ReportErrorsServiceTransport, DEFAULT_CLIENT_INFO +from .grpc import ReportErrorsServiceGrpcTransport + + +class ReportErrorsServiceGrpcAsyncIOTransport(ReportErrorsServiceTransport): + """gRPC AsyncIO backend transport for ReportErrorsService. + + An API for reporting error events. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "clouderrorreporting.googleapis.com", + credentials: credentials.Credentials = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + address (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + scopes = scopes or cls.AUTH_SCOPES + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "clouderrorreporting.googleapis.com", + credentials: credentials.Credentials = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: aio.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id=None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiate the transport. + + Args: + 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 + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[aio.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): The mutual TLS endpoint. If + provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or applicatin default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): A + callback to provide client SSL certificate bytes and private key + bytes, both in PEM format. It is ignored if ``api_mtls_endpoint`` + is None. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + if channel: + # Sanity check: Ensure that channel and credentials are not both + # provided. + credentials = False + + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + elif api_mtls_endpoint: + host = ( + api_mtls_endpoint + if ":" in api_mtls_endpoint + else api_mtls_endpoint + ":443" + ) + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + ssl_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + ssl_credentials = SslCredentials().ssl_credentials + + # create a new channel. The provided one is ignored. + self._grpc_channel = type(self).create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + ssl_credentials=ssl_credentials, + scopes=scopes or self.AUTH_SCOPES, + quota_project_id=quota_project_id, + ) + + # Run the base constructor. + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes or self.AUTH_SCOPES, + quota_project_id=quota_project_id, + client_info=client_info, + ) + + self._stubs = {} + + @property + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Sanity check: Only create a new channel if we do not already + # have one. + if not hasattr(self, "_grpc_channel"): + self._grpc_channel = self.create_channel( + self._host, credentials=self._credentials, + ) + + # Return the channel from cache. + return self._grpc_channel + + @property + def report_error_event( + self, + ) -> Callable[ + [report_errors_service.ReportErrorEventRequest], + Awaitable[report_errors_service.ReportErrorEventResponse], + ]: + r"""Return a callable for the report error event method over gRPC. + + Report an individual error event. + + This endpoint accepts **either** an OAuth token, **or** an `API + key `__ for + authentication. To use an API key, append it to the URL as the + value of a ``key`` parameter. For example: + + ``POST https://clouderrorreporting.googleapis.com/v1beta1/projects/example-project/events:report?key=123ABC456`` + + Returns: + Callable[[~.ReportErrorEventRequest], + Awaitable[~.ReportErrorEventResponse]]: + 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 "report_error_event" not in self._stubs: + self._stubs["report_error_event"] = self.grpc_channel.unary_unary( + "/google.devtools.clouderrorreporting.v1beta1.ReportErrorsService/ReportErrorEvent", + request_serializer=report_errors_service.ReportErrorEventRequest.serialize, + response_deserializer=report_errors_service.ReportErrorEventResponse.deserialize, + ) + return self._stubs["report_error_event"] + + +__all__ = ("ReportErrorsServiceGrpcAsyncIOTransport",) diff --git a/google/cloud/errorreporting_v1beta1/types.py b/google/cloud/errorreporting_v1beta1/types.py deleted file mode 100644 index 388e69bb..00000000 --- a/google/cloud/errorreporting_v1beta1/types.py +++ /dev/null @@ -1,57 +0,0 @@ -# Copyright 2018 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 -# -# https://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 absolute_import -import sys - -from google.api import http_pb2 -from google.api import label_pb2 -from google.api import monitored_resource_pb2 -from google.protobuf import descriptor_pb2 -from google.protobuf import duration_pb2 -from google.protobuf import timestamp_pb2 - -from google.api_core.protobuf_helpers import get_messages -from google.cloud.errorreporting_v1beta1.proto import common_pb2 -from google.cloud.errorreporting_v1beta1.proto import error_group_service_pb2 -from google.cloud.errorreporting_v1beta1.proto import error_stats_service_pb2 -from google.cloud.errorreporting_v1beta1.proto import report_errors_service_pb2 - - -_shared_modules = [ - http_pb2, - label_pb2, - monitored_resource_pb2, - report_errors_service_pb2, - descriptor_pb2, - duration_pb2, - timestamp_pb2, -] - -_local_modules = [common_pb2, error_group_service_pb2, error_stats_service_pb2] - -names = [] - -for module in _shared_modules: - for name, message in get_messages(module).items(): - setattr(sys.modules[__name__], name, message) - names.append(name) - -for module in _local_modules: - for name, message in get_messages(module).items(): - message.__module__ = "google.cloud.errorreporting_v1beta1.types" - setattr(sys.modules[__name__], name, message) - names.append(name) - -__all__ = tuple(sorted(names)) diff --git a/google/cloud/errorreporting_v1beta1/types/__init__.py b/google/cloud/errorreporting_v1beta1/types/__init__.py new file mode 100644 index 00000000..65524373 --- /dev/null +++ b/google/cloud/errorreporting_v1beta1/types/__init__.py @@ -0,0 +1,73 @@ +# -*- 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. +# + +from .common import ( + ErrorGroup, + TrackingIssue, + ErrorEvent, + ServiceContext, + ErrorContext, + HttpRequestContext, + SourceLocation, +) +from .error_group_service import ( + GetGroupRequest, + UpdateGroupRequest, +) +from .error_stats_service import ( + ListGroupStatsRequest, + ListGroupStatsResponse, + ErrorGroupStats, + TimedCount, + ListEventsRequest, + ListEventsResponse, + QueryTimeRange, + ServiceContextFilter, + DeleteEventsRequest, + DeleteEventsResponse, +) +from .report_errors_service import ( + ReportErrorEventRequest, + ReportErrorEventResponse, + ReportedErrorEvent, +) + + +__all__ = ( + "ErrorGroup", + "TrackingIssue", + "ErrorEvent", + "ServiceContext", + "ErrorContext", + "HttpRequestContext", + "SourceLocation", + "GetGroupRequest", + "UpdateGroupRequest", + "ListGroupStatsRequest", + "ListGroupStatsResponse", + "ErrorGroupStats", + "TimedCount", + "ListEventsRequest", + "ListEventsResponse", + "QueryTimeRange", + "ServiceContextFilter", + "DeleteEventsRequest", + "DeleteEventsResponse", + "ReportErrorEventRequest", + "ReportErrorEventResponse", + "ReportedErrorEvent", +) diff --git a/google/cloud/errorreporting_v1beta1/types/common.py b/google/cloud/errorreporting_v1beta1/types/common.py new file mode 100644 index 00000000..779aa453 --- /dev/null +++ b/google/cloud/errorreporting_v1beta1/types/common.py @@ -0,0 +1,249 @@ +# -*- 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. +# + +import proto # type: ignore + + +from google.protobuf import timestamp_pb2 as timestamp # type: ignore + + +__protobuf__ = proto.module( + package="google.devtools.clouderrorreporting.v1beta1", + manifest={ + "ErrorGroup", + "TrackingIssue", + "ErrorEvent", + "ServiceContext", + "ErrorContext", + "HttpRequestContext", + "SourceLocation", + }, +) + + +class ErrorGroup(proto.Message): + r"""Description of a group of similar error events. + + Attributes: + name (str): + The group resource name. + Example: projects/my- + project-123/groups/my-groupid + group_id (str): + Group IDs are unique for a given project. If + the same kind of error occurs in different + service contexts, it will receive the same group + ID. + tracking_issues (Sequence[~.common.TrackingIssue]): + Associated tracking issues. + """ + + name = proto.Field(proto.STRING, number=1) + + group_id = proto.Field(proto.STRING, number=2) + + tracking_issues = proto.RepeatedField( + proto.MESSAGE, number=3, message="TrackingIssue", + ) + + +class TrackingIssue(proto.Message): + r"""Information related to tracking the progress on resolving the + error. + + Attributes: + url (str): + A URL pointing to a related entry in an issue tracking + system. Example: + ``https://github.com/user/project/issues/4`` + """ + + url = proto.Field(proto.STRING, number=1) + + +class ErrorEvent(proto.Message): + r"""An error event which is returned by the Error Reporting + system. + + Attributes: + event_time (~.timestamp.Timestamp): + Time when the event occurred as provided in + the error report. If the report did not contain + a timestamp, the time the error was received by + the Error Reporting system is used. + service_context (~.common.ServiceContext): + The ``ServiceContext`` for which this error was reported. + message (str): + The stack trace that was reported or logged + by the service. + context (~.common.ErrorContext): + Data about the context in which the error + occurred. + """ + + event_time = proto.Field(proto.MESSAGE, number=1, message=timestamp.Timestamp,) + + service_context = proto.Field(proto.MESSAGE, number=2, message="ServiceContext",) + + message = proto.Field(proto.STRING, number=3) + + context = proto.Field(proto.MESSAGE, number=5, message="ErrorContext",) + + +class ServiceContext(proto.Message): + r"""Describes a running service that sends errors. + Its version changes over time and multiple versions can run in + parallel. + + Attributes: + service (str): + An identifier of the service, such as the name of the + executable, job, or Google App Engine service name. This + field is expected to have a low number of values that are + relatively stable over time, as opposed to ``version``, + which can be changed whenever new code is deployed. + + Contains the service name for error reports extracted from + Google App Engine logs or ``default`` if the App Engine + default service is used. + version (str): + Represents the source code version that the + developer provided, which could represent a + version label or a Git SHA-1 hash, for example. + For App Engine standard environment, the version + is set to the version of the app. + resource_type (str): + Type of the MonitoredResource. List of + possible values: + https://cloud.google.com/monitoring/api/resources + Value is set automatically for incoming errors + and must not be set when reporting errors. + """ + + service = proto.Field(proto.STRING, number=2) + + version = proto.Field(proto.STRING, number=3) + + resource_type = proto.Field(proto.STRING, number=4) + + +class ErrorContext(proto.Message): + r"""A description of the context in which an error occurred. + This data should be provided by the application when reporting + an error, unless the + error report has been generated automatically from Google App + Engine logs. + + Attributes: + http_request (~.common.HttpRequestContext): + The HTTP request which was processed when the + error was triggered. + user (str): + The user who caused or was affected by the crash. This can + be a user ID, an email address, or an arbitrary token that + uniquely identifies the user. When sending an error report, + leave this field empty if the user was not logged in. In + this case the Error Reporting system will use other data, + such as remote IP address, to distinguish affected users. + See ``affected_users_count`` in ``ErrorGroupStats``. + report_location (~.common.SourceLocation): + The location in the source code where the + decision was made to report the error, usually + the place where it was logged. For a logged + exception this would be the source line where + the exception is logged, usually close to the + place where it was caught. + """ + + http_request = proto.Field(proto.MESSAGE, number=1, message="HttpRequestContext",) + + user = proto.Field(proto.STRING, number=2) + + report_location = proto.Field(proto.MESSAGE, number=3, message="SourceLocation",) + + +class HttpRequestContext(proto.Message): + r"""HTTP request data that is related to a reported error. + This data should be provided by the application when reporting + an error, unless the + error report has been generated automatically from Google App + Engine logs. + + Attributes: + method (str): + The type of HTTP request, such as ``GET``, ``POST``, etc. + url (str): + The URL of the request. + user_agent (str): + The user agent information that is provided + with the request. + referrer (str): + The referrer information that is provided + with the request. + response_status_code (int): + The HTTP response status code for the + request. + remote_ip (str): + The IP address from which the request + originated. This can be IPv4, IPv6, or a token + which is derived from the IP address, depending + on the data that has been provided in the error + report. + """ + + method = proto.Field(proto.STRING, number=1) + + url = proto.Field(proto.STRING, number=2) + + user_agent = proto.Field(proto.STRING, number=3) + + referrer = proto.Field(proto.STRING, number=4) + + response_status_code = proto.Field(proto.INT32, number=5) + + remote_ip = proto.Field(proto.STRING, number=6) + + +class SourceLocation(proto.Message): + r"""Indicates a location in the source code of the service for which + errors are reported. ``functionName`` must be provided by the + application when reporting an error, unless the error report + contains a ``message`` with a supported exception stack trace. All + fields are optional for the later case. + + Attributes: + file_path (str): + The source code filename, which can include a + truncated relative path, or a full path from a + production machine. + line_number (int): + 1-based. 0 indicates that the line number is + unknown. + function_name (str): + Human-readable name of a function or method. The value can + include optional context like the class or package name. For + example, ``my.package.MyClass.method`` in case of Java. + """ + + file_path = proto.Field(proto.STRING, number=1) + + line_number = proto.Field(proto.INT32, number=2) + + function_name = proto.Field(proto.STRING, number=4) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/cloud/errorreporting_v1beta1/types/error_group_service.py b/google/cloud/errorreporting_v1beta1/types/error_group_service.py new file mode 100644 index 00000000..70aa92a8 --- /dev/null +++ b/google/cloud/errorreporting_v1beta1/types/error_group_service.py @@ -0,0 +1,58 @@ +# -*- 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. +# + +import proto # type: ignore + + +from google.cloud.errorreporting_v1beta1.types import common + + +__protobuf__ = proto.module( + package="google.devtools.clouderrorreporting.v1beta1", + manifest={"GetGroupRequest", "UpdateGroupRequest",}, +) + + +class GetGroupRequest(proto.Message): + r"""A request to return an individual group. + + Attributes: + group_name (str): + The group resource name. Written as + ``projects/{projectID}/groups/{group_name}``. Call + ```groupStats.list`` `__ + to return a list of groups belonging to this project. + + Example: ``projects/my-project-123/groups/my-group`` + """ + + group_name = proto.Field(proto.STRING, number=1) + + +class UpdateGroupRequest(proto.Message): + r"""A request to replace the existing data for the given group. + + Attributes: + group (~.common.ErrorGroup): + Required. The group which replaces the + resource on the server. + """ + + group = proto.Field(proto.MESSAGE, number=1, message=common.ErrorGroup,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/cloud/errorreporting_v1beta1/types/error_stats_service.py b/google/cloud/errorreporting_v1beta1/types/error_stats_service.py new file mode 100644 index 00000000..51a14e89 --- /dev/null +++ b/google/cloud/errorreporting_v1beta1/types/error_stats_service.py @@ -0,0 +1,420 @@ +# -*- 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. +# + +import proto # type: ignore + + +from google.cloud.errorreporting_v1beta1.types import common +from google.protobuf import duration_pb2 as duration # type: ignore +from google.protobuf import timestamp_pb2 as timestamp # type: ignore + + +__protobuf__ = proto.module( + package="google.devtools.clouderrorreporting.v1beta1", + manifest={ + "TimedCountAlignment", + "ErrorGroupOrder", + "ListGroupStatsRequest", + "ListGroupStatsResponse", + "ErrorGroupStats", + "TimedCount", + "ListEventsRequest", + "ListEventsResponse", + "QueryTimeRange", + "ServiceContextFilter", + "DeleteEventsRequest", + "DeleteEventsResponse", + }, +) + + +class TimedCountAlignment(proto.Enum): + r"""Specifies how the time periods of error group counts are + aligned. + """ + ERROR_COUNT_ALIGNMENT_UNSPECIFIED = 0 + ALIGNMENT_EQUAL_ROUNDED = 1 + ALIGNMENT_EQUAL_AT_END = 2 + + +class ErrorGroupOrder(proto.Enum): + r"""A sorting order of error groups.""" + GROUP_ORDER_UNSPECIFIED = 0 + COUNT_DESC = 1 + LAST_SEEN_DESC = 2 + CREATED_DESC = 3 + AFFECTED_USERS_DESC = 4 + + +class ListGroupStatsRequest(proto.Message): + r"""Specifies a set of ``ErrorGroupStats`` to return. + + Attributes: + project_name (str): + Required. The resource name of the Google + Cloud Platform project. Written as + projects/ plus the Google + Cloud Platform project ID. + + Example: projects/my-project-123. + group_id (Sequence[str]): + Optional. List all + ErrorGroupStats with these IDs. + service_filter (~.error_stats_service.ServiceContextFilter): + Optional. List only + ErrorGroupStats which belong to a + service context that matches the filter. Data + for all service contexts is returned if this + field is not specified. + time_range (~.error_stats_service.QueryTimeRange): + Optional. List data for the given time range. If not set, a + default time range is used. The field time_range_begin in + the response will specify the beginning of this time range. + Only ErrorGroupStats with a non-zero count in the given time + range are returned, unless the request contains an explicit + group_id list. If a group_id list is given, also + ErrorGroupStats with zero occurrences are returned. + timed_count_duration (~.duration.Duration): + Optional. The preferred duration for a single returned + ``TimedCount``. If not set, no timed counts are returned. + alignment (~.error_stats_service.TimedCountAlignment): + Optional. The alignment of the timed counts to be returned. + Default is ``ALIGNMENT_EQUAL_AT_END``. + alignment_time (~.timestamp.Timestamp): + Optional. Time where the timed counts shall + be aligned if rounded alignment is chosen. + Default is 00:00 UTC. + order (~.error_stats_service.ErrorGroupOrder): + Optional. The sort order in which the results are returned. + Default is ``COUNT_DESC``. + page_size (int): + Optional. The maximum number of results to + return per response. Default is 20. + page_token (str): + Optional. A ``next_page_token`` provided by a previous + response. To view additional results, pass this token along + with the identical query parameters as the first request. + """ + + project_name = proto.Field(proto.STRING, number=1) + + group_id = proto.RepeatedField(proto.STRING, number=2) + + service_filter = proto.Field( + proto.MESSAGE, number=3, message="ServiceContextFilter", + ) + + time_range = proto.Field(proto.MESSAGE, number=5, message="QueryTimeRange",) + + timed_count_duration = proto.Field( + proto.MESSAGE, number=6, message=duration.Duration, + ) + + alignment = proto.Field(proto.ENUM, number=7, enum="TimedCountAlignment",) + + alignment_time = proto.Field(proto.MESSAGE, number=8, message=timestamp.Timestamp,) + + order = proto.Field(proto.ENUM, number=9, enum="ErrorGroupOrder",) + + page_size = proto.Field(proto.INT32, number=11) + + page_token = proto.Field(proto.STRING, number=12) + + +class ListGroupStatsResponse(proto.Message): + r"""Contains a set of requested error group stats. + + Attributes: + error_group_stats (Sequence[~.error_stats_service.ErrorGroupStats]): + The error group stats which match the given + request. + next_page_token (str): + If non-empty, more results are available. + Pass this token, along with the same query + parameters as the first request, to view the + next page of results. + time_range_begin (~.timestamp.Timestamp): + The timestamp specifies the start time to + which the request was restricted. The start time + is set based on the requested time range. It may + be adjusted to a later time if a project has + exceeded the storage quota and older data has + been deleted. + """ + + @property + def raw_page(self): + return self + + error_group_stats = proto.RepeatedField( + proto.MESSAGE, number=1, message="ErrorGroupStats", + ) + + next_page_token = proto.Field(proto.STRING, number=2) + + time_range_begin = proto.Field( + proto.MESSAGE, number=4, message=timestamp.Timestamp, + ) + + +class ErrorGroupStats(proto.Message): + r"""Data extracted for a specific group based on certain filter + criteria, such as a given time period and/or service filter. + + Attributes: + group (~.common.ErrorGroup): + Group data that is independent of the filter + criteria. + count (int): + Approximate total number of events in the + given group that match the filter criteria. + affected_users_count (int): + Approximate number of affected users in the given group that + match the filter criteria. Users are distinguished by data + in the ``ErrorContext`` of the individual error events, such + as their login name or their remote IP address in case of + HTTP requests. The number of affected users can be zero even + if the number of errors is non-zero if no data was provided + from which the affected user could be deduced. Users are + counted based on data in the request context that was + provided in the error report. If more users are implicitly + affected, such as due to a crash of the whole service, this + is not reflected here. + timed_counts (Sequence[~.error_stats_service.TimedCount]): + Approximate number of occurrences over time. + Timed counts returned by ListGroups are + guaranteed to be: + - Inside the requested time interval + - Non-overlapping, and + - Ordered by ascending time. + first_seen_time (~.timestamp.Timestamp): + Approximate first occurrence that was ever seen for this + group and which matches the given filter criteria, ignoring + the time_range that was specified in the request. + last_seen_time (~.timestamp.Timestamp): + Approximate last occurrence that was ever seen for this + group and which matches the given filter criteria, ignoring + the time_range that was specified in the request. + affected_services (Sequence[~.common.ServiceContext]): + Service contexts with a non-zero error count for the given + filter criteria. This list can be truncated if multiple + services are affected. Refer to ``num_affected_services`` + for the total count. + num_affected_services (int): + The total number of services with a non-zero + error count for the given filter criteria. + representative (~.common.ErrorEvent): + An arbitrary event that is chosen as + representative for the whole group. The + representative event is intended to be used as a + quick preview for the whole group. Events in the + group are usually sufficiently similar to each + other such that showing an arbitrary + representative provides insight into the + characteristics of the group as a whole. + """ + + group = proto.Field(proto.MESSAGE, number=1, message=common.ErrorGroup,) + + count = proto.Field(proto.INT64, number=2) + + affected_users_count = proto.Field(proto.INT64, number=3) + + timed_counts = proto.RepeatedField(proto.MESSAGE, number=4, message="TimedCount",) + + first_seen_time = proto.Field(proto.MESSAGE, number=5, message=timestamp.Timestamp,) + + last_seen_time = proto.Field(proto.MESSAGE, number=6, message=timestamp.Timestamp,) + + affected_services = proto.RepeatedField( + proto.MESSAGE, number=7, message=common.ServiceContext, + ) + + num_affected_services = proto.Field(proto.INT32, number=8) + + representative = proto.Field(proto.MESSAGE, number=9, message=common.ErrorEvent,) + + +class TimedCount(proto.Message): + r"""The number of errors in a given time period. + All numbers are approximate since the error events are sampled + before counting them. + + Attributes: + count (int): + Approximate number of occurrences in the + given time period. + start_time (~.timestamp.Timestamp): + Start of the time period to which ``count`` refers + (included). + end_time (~.timestamp.Timestamp): + End of the time period to which ``count`` refers (excluded). + """ + + count = proto.Field(proto.INT64, number=1) + + start_time = proto.Field(proto.MESSAGE, number=2, message=timestamp.Timestamp,) + + end_time = proto.Field(proto.MESSAGE, number=3, message=timestamp.Timestamp,) + + +class ListEventsRequest(proto.Message): + r"""Specifies a set of error events to return. + + Attributes: + project_name (str): + Required. The resource name of the Google Cloud Platform + project. Written as ``projects/`` plus the `Google Cloud + Platform project + ID `__. + Example: ``projects/my-project-123``. + group_id (str): + Required. The group for which events shall be + returned. + service_filter (~.error_stats_service.ServiceContextFilter): + Optional. List only ErrorGroups which belong + to a service context that matches the filter. + Data for all service contexts is returned if + this field is not specified. + time_range (~.error_stats_service.QueryTimeRange): + Optional. List only data for the given time range. If not + set a default time range is used. The field time_range_begin + in the response will specify the beginning of this time + range. + page_size (int): + Optional. The maximum number of results to + return per response. + page_token (str): + Optional. A ``next_page_token`` provided by a previous + response. + """ + + project_name = proto.Field(proto.STRING, number=1) + + group_id = proto.Field(proto.STRING, number=2) + + service_filter = proto.Field( + proto.MESSAGE, number=3, message="ServiceContextFilter", + ) + + time_range = proto.Field(proto.MESSAGE, number=4, message="QueryTimeRange",) + + page_size = proto.Field(proto.INT32, number=6) + + page_token = proto.Field(proto.STRING, number=7) + + +class ListEventsResponse(proto.Message): + r"""Contains a set of requested error events. + + Attributes: + error_events (Sequence[~.common.ErrorEvent]): + The error events which match the given + request. + next_page_token (str): + If non-empty, more results are available. + Pass this token, along with the same query + parameters as the first request, to view the + next page of results. + time_range_begin (~.timestamp.Timestamp): + The timestamp specifies the start time to + which the request was restricted. + """ + + @property + def raw_page(self): + return self + + error_events = proto.RepeatedField( + proto.MESSAGE, number=1, message=common.ErrorEvent, + ) + + next_page_token = proto.Field(proto.STRING, number=2) + + time_range_begin = proto.Field( + proto.MESSAGE, number=4, message=timestamp.Timestamp, + ) + + +class QueryTimeRange(proto.Message): + r"""Requests might be rejected or the resulting timed count + durations might be adjusted for lower durations. + + Attributes: + period (~.error_stats_service.QueryTimeRange.Period): + Restricts the query to the specified time + range. + """ + + class Period(proto.Enum): + r"""The supported time ranges.""" + PERIOD_UNSPECIFIED = 0 + PERIOD_1_HOUR = 1 + PERIOD_6_HOURS = 2 + PERIOD_1_DAY = 3 + PERIOD_1_WEEK = 4 + PERIOD_30_DAYS = 5 + + period = proto.Field(proto.ENUM, number=1, enum=Period,) + + +class ServiceContextFilter(proto.Message): + r"""Specifies criteria for filtering a subset of service contexts. The + fields in the filter correspond to the fields in ``ServiceContext``. + Only exact, case-sensitive matches are supported. If a field is + unset or empty, it matches arbitrary values. + + Attributes: + service (str): + Optional. The exact value to match against + ```ServiceContext.service`` `__. + version (str): + Optional. The exact value to match against + ```ServiceContext.version`` `__. + resource_type (str): + Optional. The exact value to match against + ```ServiceContext.resource_type`` `__. + """ + + service = proto.Field(proto.STRING, number=2) + + version = proto.Field(proto.STRING, number=3) + + resource_type = proto.Field(proto.STRING, number=4) + + +class DeleteEventsRequest(proto.Message): + r"""Deletes all events in the project. + + Attributes: + project_name (str): + Required. The resource name of the Google Cloud Platform + project. Written as ``projects/`` plus the `Google Cloud + Platform project + ID `__. + Example: ``projects/my-project-123``. + """ + + project_name = proto.Field(proto.STRING, number=1) + + +class DeleteEventsResponse(proto.Message): + r"""Response message for deleting error events.""" + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/cloud/errorreporting_v1beta1/types/report_errors_service.py b/google/cloud/errorreporting_v1beta1/types/report_errors_service.py new file mode 100644 index 00000000..1a66727b --- /dev/null +++ b/google/cloud/errorreporting_v1beta1/types/report_errors_service.py @@ -0,0 +1,115 @@ +# -*- 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. +# + +import proto # type: ignore + + +from google.cloud.errorreporting_v1beta1.types import common +from google.protobuf import timestamp_pb2 as timestamp # type: ignore + + +__protobuf__ = proto.module( + package="google.devtools.clouderrorreporting.v1beta1", + manifest={ + "ReportErrorEventRequest", + "ReportErrorEventResponse", + "ReportedErrorEvent", + }, +) + + +class ReportErrorEventRequest(proto.Message): + r"""A request for reporting an individual error event. + + Attributes: + project_name (str): + Required. The resource name of the Google Cloud Platform + project. Written as ``projects/`` plus the `Google Cloud + Platform project + ID `__. + Example: ``projects/my-project-123``. + event (~.report_errors_service.ReportedErrorEvent): + Required. The error event to be reported. + """ + + project_name = proto.Field(proto.STRING, number=1) + + event = proto.Field(proto.MESSAGE, number=2, message="ReportedErrorEvent",) + + +class ReportErrorEventResponse(proto.Message): + r"""Response for reporting an individual error event. + Data may be added to this message in the future. + """ + + +class ReportedErrorEvent(proto.Message): + r"""An error event which is reported to the Error Reporting + system. + + Attributes: + event_time (~.timestamp.Timestamp): + Optional. Time when the event occurred. + If not provided, the time when the event was + received by the Error Reporting system will be + used. + service_context (~.common.ServiceContext): + Required. The service context in which this + error has occurred. + message (str): + Required. The error message. If no + ``context.reportLocation`` is provided, the message must + contain a header (typically consisting of the exception type + name and an error message) and an exception stack trace in + one of the supported programming languages and formats. + Supported languages are Java, Python, JavaScript, Ruby, C#, + PHP, and Go. Supported stack trace formats are: + + - **Java**: Must be the return value of + ```Throwable.printStackTrace()`` `__. + - **Python**: Must be the return value of + ```traceback.format_exc()`` `__. + - **JavaScript**: Must be the value of + ```error.stack`` `__ + as returned by V8. + - **Ruby**: Must contain frames returned by + ```Exception.backtrace`` `__. + - **C#**: Must be the return value of + ```Exception.ToString()`` `__. + - **PHP**: Must start with + ``PHP (Notice|Parse error|Fatal error|Warning)`` and + contain the result of + ```(string)$exception`` `__. + - **Go**: Must be the return value of + ```runtime.Stack()`` `__. + context (~.common.ErrorContext): + Optional. A description of the context in + which the error occurred. + """ + + event_time = proto.Field(proto.MESSAGE, number=1, message=timestamp.Timestamp,) + + service_context = proto.Field( + proto.MESSAGE, number=2, message=common.ServiceContext, + ) + + message = proto.Field(proto.STRING, number=3) + + context = proto.Field(proto.MESSAGE, number=4, message=common.ErrorContext,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/mypy.ini b/mypy.ini new file mode 100644 index 00000000..4505b485 --- /dev/null +++ b/mypy.ini @@ -0,0 +1,3 @@ +[mypy] +python_version = 3.6 +namespace_packages = True diff --git a/noxfile.py b/noxfile.py index 9e8112b9..c8fd0a7d 100644 --- a/noxfile.py +++ b/noxfile.py @@ -23,14 +23,15 @@ import nox -BLACK_VERSION = "black==19.3b0" +BLACK_VERSION = "black==19.10b0" BLACK_PATHS = ["docs", "google", "tests", "noxfile.py", "setup.py"] -if os.path.exists("samples"): - BLACK_PATHS.append("samples") +DEFAULT_PYTHON_VERSION = "3.8" +SYSTEM_TEST_PYTHON_VERSIONS = ["3.8"] +UNIT_TEST_PYTHON_VERSIONS = ["3.6", "3.7", "3.8"] -@nox.session(python="3.7") +@nox.session(python=DEFAULT_PYTHON_VERSION) def lint(session): """Run linters. @@ -38,7 +39,9 @@ def lint(session): serious code quality issues. """ session.install("flake8", BLACK_VERSION) - session.run("black", "--check", *BLACK_PATHS) + session.run( + "black", "--check", *BLACK_PATHS, + ) session.run("flake8", "google", "tests") @@ -53,10 +56,12 @@ def blacken(session): check the state of the `gcp_ubuntu_config` we use for that Kokoro run. """ session.install(BLACK_VERSION) - session.run("black", *BLACK_PATHS) + session.run( + "black", *BLACK_PATHS, + ) -@nox.session(python="3.7") +@nox.session(python=DEFAULT_PYTHON_VERSION) def lint_setup_py(session): """Verify that setup.py is valid (including RST check).""" session.install("docutils", "pygments") @@ -65,6 +70,8 @@ def lint_setup_py(session): def default(session): # Install all test dependencies, then install this package in-place. + session.install("asyncmock", "pytest-asyncio") + session.install("mock", "pytest", "pytest-cov") session.install("-e", ".") @@ -84,17 +91,21 @@ def default(session): ) -@nox.session(python=["2.7", "3.5", "3.6", "3.7", "3.8"]) +@nox.session(python=UNIT_TEST_PYTHON_VERSIONS) def unit(session): """Run the unit test suite.""" default(session) -@nox.session(python=["2.7", "3.7"]) +@nox.session(python=SYSTEM_TEST_PYTHON_VERSIONS) def system(session): """Run the system test suite.""" system_test_path = os.path.join("tests", "system.py") system_test_folder_path = os.path.join("tests", "system") + + # Check the value of `RUN_SYSTEM_TESTS` env var. It defaults to true. + if os.environ.get("RUN_SYSTEM_TESTS", "true") == "false": + session.skip("RUN_SYSTEM_TESTS is set to false, skipping") # Sanity check: Only run tests if the environment variable is set. if not os.environ.get("GOOGLE_APPLICATION_CREDENTIALS", ""): session.skip("Credentials must be set via environment variable") @@ -110,7 +121,9 @@ def system(session): # Install all test dependencies, then install this package into the # virtualenv's dist-packages. - session.install("mock", "pytest", "google-cloud-testutils") + session.install( + "mock", "pytest", "google-cloud-testutils", + ) session.install("-e", "test_utils") session.install("-e", ".") @@ -121,7 +134,7 @@ def system(session): session.run("py.test", "--quiet", system_test_folder_path, *session.posargs) -@nox.session(python="3.7") +@nox.session(python=DEFAULT_PYTHON_VERSION) def cover(session): """Run the final coverage report. @@ -129,12 +142,12 @@ def cover(session): test runs (not system test runs), and then erases coverage data. """ session.install("coverage", "pytest-cov") - session.run("coverage", "report", "--show-missing", "--fail-under=98") + session.run("coverage", "report", "--show-missing", "--fail-under=100") session.run("coverage", "erase") -@nox.session(python="3.7") +@nox.session(python=DEFAULT_PYTHON_VERSION) def docs(session): """Build the docs for this library.""" @@ -154,3 +167,36 @@ def docs(session): os.path.join("docs", ""), os.path.join("docs", "_build", "html", ""), ) + + +@nox.session(python=DEFAULT_PYTHON_VERSION) +def docfx(session): + """Build the docfx yaml files for this library.""" + + session.install("-e", ".") + session.install("sphinx<3.0.0", "alabaster", "recommonmark", "sphinx-docfx-yaml") + + shutil.rmtree(os.path.join("docs", "_build"), ignore_errors=True) + session.run( + "sphinx-build", + "-T", # show full traceback on exception + "-N", # no colors + "-D", + ( + "extensions=sphinx.ext.autodoc," + "sphinx.ext.autosummary," + "docfx_yaml.extension," + "sphinx.ext.intersphinx," + "sphinx.ext.coverage," + "sphinx.ext.napoleon," + "sphinx.ext.todo," + "sphinx.ext.viewcode," + "recommonmark" + ), + "-b", + "html", + "-d", + os.path.join("docs", "_build", "doctrees", ""), + os.path.join("docs", ""), + os.path.join("docs", "_build", "html", ""), + ) diff --git a/samples/AUTHORING_GUIDE.md b/samples/AUTHORING_GUIDE.md new file mode 100644 index 00000000..55c97b32 --- /dev/null +++ b/samples/AUTHORING_GUIDE.md @@ -0,0 +1 @@ +See https://github.com/GoogleCloudPlatform/python-docs-samples/blob/master/AUTHORING_GUIDE.md \ No newline at end of file diff --git a/samples/CONTRIBUTING.md b/samples/CONTRIBUTING.md new file mode 100644 index 00000000..34c882b6 --- /dev/null +++ b/samples/CONTRIBUTING.md @@ -0,0 +1 @@ +See https://github.com/GoogleCloudPlatform/python-docs-samples/blob/master/CONTRIBUTING.md \ No newline at end of file diff --git a/samples/snippets/api/README.rst b/samples/snippets/api/README.rst new file mode 100644 index 00000000..74bcd639 --- /dev/null +++ b/samples/snippets/api/README.rst @@ -0,0 +1,98 @@ +.. This file is automatically generated. Do not edit this file directly. + +Stackdriver Error Reporting Python Samples +=============================================================================== + +.. image:: https://gstatic.com/cloudssh/images/open-btn.png + :target: https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/GoogleCloudPlatform/python-docs-samples&page=editor&open_in_editor=error_reporting/api/README.rst + + +This directory contains samples for Stackdriver Error Reporting. `Stackdriver Error Reporting`_ aggregates and displays errors produced in + your running cloud services. + + + + +.. _Stackdriver Error Reporting: https://cloud.google.com/error-reporting/docs/ + +Setup +------------------------------------------------------------------------------- + + +Authentication +++++++++++++++ + +This sample requires you to have authentication setup. Refer to the +`Authentication Getting Started Guide`_ for instructions on setting up +credentials for applications. + +.. _Authentication Getting Started Guide: + https://cloud.google.com/docs/authentication/getting-started + +Install Dependencies +++++++++++++++++++++ + +#. Clone python-docs-samples and change directory to the sample directory you want to use. + + .. code-block:: bash + + $ git clone https://github.com/GoogleCloudPlatform/python-docs-samples.git + +#. Install `pip`_ and `virtualenv`_ if you do not already have them. You may want to refer to the `Python Development Environment Setup Guide`_ for Google Cloud Platform for instructions. + + .. _Python Development Environment Setup Guide: + https://cloud.google.com/python/setup + +#. Create a virtualenv. Samples are compatible with Python 2.7 and 3.4+. + + .. code-block:: bash + + $ virtualenv env + $ source env/bin/activate + +#. Install the dependencies needed to run the samples. + + .. code-block:: bash + + $ pip install -r requirements.txt + +.. _pip: https://pip.pypa.io/ +.. _virtualenv: https://virtualenv.pypa.io/ + +Samples +------------------------------------------------------------------------------- + +Report Exception ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +.. image:: https://gstatic.com/cloudssh/images/open-btn.png + :target: https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/GoogleCloudPlatform/python-docs-samples&page=editor&open_in_editor=error_reporting/api/report_exception.py,error_reporting/api/README.rst + + + + +To run this sample: + +.. code-block:: bash + + $ python report_exception.py + + + + +The client library +------------------------------------------------------------------------------- + +This sample uses the `Google Cloud Client Library for Python`_. +You can read the documentation for more details on API usage and use GitHub +to `browse the source`_ and `report issues`_. + +.. _Google Cloud Client Library for Python: + https://googlecloudplatform.github.io/google-cloud-python/ +.. _browse the source: + https://github.com/GoogleCloudPlatform/google-cloud-python +.. _report issues: + https://github.com/GoogleCloudPlatform/google-cloud-python/issues + + +.. _Google Cloud SDK: https://cloud.google.com/sdk/ \ No newline at end of file diff --git a/samples/snippets/api/README.rst.in b/samples/snippets/api/README.rst.in new file mode 100644 index 00000000..ac60cc80 --- /dev/null +++ b/samples/snippets/api/README.rst.in @@ -0,0 +1,21 @@ +# This file is used to generate README.rst + +product: + name: Stackdriver Error Reporting + short_name: Error Reporting + url: https://cloud.google.com/error-reporting/docs/ + description: > + `Stackdriver Error Reporting`_ aggregates and displays errors produced in + your running cloud services. + +setup: +- auth +- install_deps + +samples: +- name: Report Exception + file: report_exception.py + +cloud_client_library: true + +folder: error_reporting/api \ No newline at end of file diff --git a/samples/snippets/api/noxfile.py b/samples/snippets/api/noxfile.py new file mode 100644 index 00000000..ba55d7ce --- /dev/null +++ b/samples/snippets/api/noxfile.py @@ -0,0 +1,224 @@ +# Copyright 2019 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 print_function + +import os +from pathlib import Path +import sys + +import nox + + +# WARNING - WARNING - WARNING - WARNING - WARNING +# WARNING - WARNING - WARNING - WARNING - WARNING +# DO NOT EDIT THIS FILE EVER! +# WARNING - WARNING - WARNING - WARNING - WARNING +# WARNING - WARNING - WARNING - WARNING - WARNING + +# Copy `noxfile_config.py` to your directory and modify it instead. + + +# `TEST_CONFIG` dict is a configuration hook that allows users to +# modify the test configurations. The values here should be in sync +# with `noxfile_config.py`. Users will copy `noxfile_config.py` into +# their directory and modify it. + +TEST_CONFIG = { + # You can opt out from the test for specific Python versions. + 'ignored_versions': ["2.7"], + + # An envvar key for determining the project id to use. Change it + # to 'BUILD_SPECIFIC_GCLOUD_PROJECT' if you want to opt in using a + # build specific Cloud project. You can also use your own string + # to use your own Cloud project. + 'gcloud_project_env': 'GOOGLE_CLOUD_PROJECT', + # 'gcloud_project_env': 'BUILD_SPECIFIC_GCLOUD_PROJECT', + + # A dictionary you want to inject into your test. Don't put any + # secrets here. These values will override predefined values. + 'envs': {}, +} + + +try: + # Ensure we can import noxfile_config in the project's directory. + sys.path.append('.') + from noxfile_config import TEST_CONFIG_OVERRIDE +except ImportError as e: + print("No user noxfile_config found: detail: {}".format(e)) + TEST_CONFIG_OVERRIDE = {} + +# Update the TEST_CONFIG with the user supplied values. +TEST_CONFIG.update(TEST_CONFIG_OVERRIDE) + + +def get_pytest_env_vars(): + """Returns a dict for pytest invocation.""" + ret = {} + + # Override the GCLOUD_PROJECT and the alias. + env_key = TEST_CONFIG['gcloud_project_env'] + # This should error out if not set. + ret['GOOGLE_CLOUD_PROJECT'] = os.environ[env_key] + + # Apply user supplied envs. + ret.update(TEST_CONFIG['envs']) + return ret + + +# DO NOT EDIT - automatically generated. +# All versions used to tested samples. +ALL_VERSIONS = ["2.7", "3.6", "3.7", "3.8"] + +# Any default versions that should be ignored. +IGNORED_VERSIONS = TEST_CONFIG['ignored_versions'] + +TESTED_VERSIONS = sorted([v for v in ALL_VERSIONS if v not in IGNORED_VERSIONS]) + +INSTALL_LIBRARY_FROM_SOURCE = bool(os.environ.get("INSTALL_LIBRARY_FROM_SOURCE", False)) +# +# Style Checks +# + + +def _determine_local_import_names(start_dir): + """Determines all import names that should be considered "local". + + This is used when running the linter to insure that import order is + properly checked. + """ + file_ext_pairs = [os.path.splitext(path) for path in os.listdir(start_dir)] + return [ + basename + for basename, extension in file_ext_pairs + if extension == ".py" + or os.path.isdir(os.path.join(start_dir, basename)) + and basename not in ("__pycache__") + ] + + +# Linting with flake8. +# +# We ignore the following rules: +# E203: whitespace before ‘:’ +# E266: too many leading ‘#’ for block comment +# E501: line too long +# I202: Additional newline in a section of imports +# +# We also need to specify the rules which are ignored by default: +# ['E226', 'W504', 'E126', 'E123', 'W503', 'E24', 'E704', 'E121'] +FLAKE8_COMMON_ARGS = [ + "--show-source", + "--builtin=gettext", + "--max-complexity=20", + "--import-order-style=google", + "--exclude=.nox,.cache,env,lib,generated_pb2,*_pb2.py,*_pb2_grpc.py", + "--ignore=E121,E123,E126,E203,E226,E24,E266,E501,E704,W503,W504,I202", + "--max-line-length=88", +] + + +@nox.session +def lint(session): + session.install("flake8", "flake8-import-order") + + local_names = _determine_local_import_names(".") + args = FLAKE8_COMMON_ARGS + [ + "--application-import-names", + ",".join(local_names), + "." + ] + session.run("flake8", *args) + + +# +# Sample Tests +# + + +PYTEST_COMMON_ARGS = ["--junitxml=sponge_log.xml"] + + +def _session_tests(session, post_install=None): + """Runs py.test for a particular project.""" + if os.path.exists("requirements.txt"): + session.install("-r", "requirements.txt") + + if os.path.exists("requirements-test.txt"): + session.install("-r", "requirements-test.txt") + + if INSTALL_LIBRARY_FROM_SOURCE: + session.install("-e", _get_repo_root()) + + if post_install: + post_install(session) + + session.run( + "pytest", + *(PYTEST_COMMON_ARGS + session.posargs), + # Pytest will return 5 when no tests are collected. This can happen + # on travis where slow and flaky tests are excluded. + # See http://doc.pytest.org/en/latest/_modules/_pytest/main.html + success_codes=[0, 5], + env=get_pytest_env_vars() + ) + + +@nox.session(python=ALL_VERSIONS) +def py(session): + """Runs py.test for a sample using the specified version of Python.""" + if session.python in TESTED_VERSIONS: + _session_tests(session) + else: + session.skip("SKIPPED: {} tests are disabled for this sample.".format( + session.python + )) + + +# +# Readmegen +# + + +def _get_repo_root(): + """ Returns the root folder of the project. """ + # Get root of this repository. Assume we don't have directories nested deeper than 10 items. + p = Path(os.getcwd()) + for i in range(10): + if p is None: + break + if Path(p / ".git").exists(): + return str(p) + p = p.parent + raise Exception("Unable to detect repository root.") + + +GENERATED_READMES = sorted([x for x in Path(".").rglob("*.rst.in")]) + + +@nox.session +@nox.parametrize("path", GENERATED_READMES) +def readmegen(session, path): + """(Re-)generates the readme for a sample.""" + session.install("jinja2", "pyyaml") + dir_ = os.path.dirname(path) + + if os.path.exists(os.path.join(dir_, "requirements.txt")): + session.install("-r", os.path.join(dir_, "requirements.txt")) + + in_file = os.path.join(dir_, "README.rst.in") + session.run( + "python", _get_repo_root() + "/scripts/readme-gen/readme_gen.py", in_file + ) diff --git a/samples/snippets/api/report_exception.py b/samples/snippets/api/report_exception.py new file mode 100644 index 00000000..2b7e8f06 --- /dev/null +++ b/samples/snippets/api/report_exception.py @@ -0,0 +1,46 @@ +# Copyright 2016 Google Inc. All rights reserved. +# +# 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. + + +# [START error_reporting] +# [START error_reporting_quickstart] +# [START error_reporting_setup_python] +def simulate_error(): + from google.cloud import error_reporting + + client = error_reporting.Client() + try: + # simulate calling a method that's not defined + raise NameError + except Exception: + client.report_exception() +# [END error_reporting_setup_python] +# [END error_reporting_quickstart] +# [END error_reporting] + + +# [START error_reporting_manual] +# [START error_reporting_setup_python_manual] +def report_manual_error(): + from google.cloud import error_reporting + + client = error_reporting.Client() + client.report("An error has occurred.") +# [START error_reporting_setup_python_manual] +# [END error_reporting_manual] + + +if __name__ == '__main__': + simulate_error() + report_manual_error() diff --git a/google/cloud/__init__.py b/samples/snippets/api/report_exception_test.py similarity index 72% rename from google/cloud/__init__.py rename to samples/snippets/api/report_exception_test.py index 0e1bc513..042951e9 100644 --- a/google/cloud/__init__.py +++ b/samples/snippets/api/report_exception_test.py @@ -1,4 +1,4 @@ -# Copyright 2016 Google LLC +# Copyright 2016 Google Inc. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -12,11 +12,12 @@ # See the License for the specific language governing permissions and # limitations under the License. -try: - import pkg_resources +import report_exception - pkg_resources.declare_namespace(__name__) -except ImportError: - import pkgutil - __path__ = pkgutil.extend_path(__path__, __name__) +def test_error_sends(): + report_exception.simulate_error() + + +def test_manual_error_sends(): + report_exception.report_manual_error() diff --git a/samples/snippets/api/requirements-test.txt b/samples/snippets/api/requirements-test.txt new file mode 100644 index 00000000..7e460c8c --- /dev/null +++ b/samples/snippets/api/requirements-test.txt @@ -0,0 +1 @@ +pytest==6.0.1 diff --git a/samples/snippets/api/requirements.txt b/samples/snippets/api/requirements.txt new file mode 100644 index 00000000..242254e8 --- /dev/null +++ b/samples/snippets/api/requirements.txt @@ -0,0 +1 @@ +google-cloud-error-reporting==0.34.0 diff --git a/samples/snippets/fluent_on_compute/README.md b/samples/snippets/fluent_on_compute/README.md new file mode 100644 index 00000000..d3a58c16 --- /dev/null +++ b/samples/snippets/fluent_on_compute/README.md @@ -0,0 +1,35 @@ +# Google Error Reorting Samples Samples + +[![Open in Cloud Shell][shell_img]][shell_link] + +[shell_img]: http://gstatic.com/cloudssh/images/open-btn.png +[shell_link]: https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/GoogleCloudPlatform/python-docs-samples&page=editor&open_in_editor=error_reporting/fluent_on_compute/README.md + +This section contains samples for [Google Cloud Error Reporting](https://cloud.google.com/error-reporting). + +A startup script has been provided to demonstrated how to properly provision a GCE +instance with fluentd configured. Note the intallation of fluentd, the addition of the config file, + and the restarting of the fluetnd service. You can start an instance using +it like this: + + gcloud compute instances create example-instance --metadata-from-file startup-script=startup_script.sh + +or simply use it as reference when creating your own instance. + +After fluentd is configured, main.py could be used to simulate an error: + + gcloud compute copy-files main.py example-instance:~/main.py + +Then, + + gcloud compute ssh example-instance + python ~/main.py + +And you will see the message in the Errors Console. + + +These samples are used on the following documentation page: + +> https://cloud.google.com/error-reporting/docs/setting-up-on-compute-engine + + diff --git a/samples/snippets/fluent_on_compute/main.py b/samples/snippets/fluent_on_compute/main.py new file mode 100644 index 00000000..45208c91 --- /dev/null +++ b/samples/snippets/fluent_on_compute/main.py @@ -0,0 +1,42 @@ +# Copyright 2016 Google Inc. All rights reserved. +# +# 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. + +# [START error_reporting] +import traceback + +import fluent.event +import fluent.sender + + +def simulate_error(): + fluent.sender.setup('myapp', host='localhost', port=24224) + + def report(ex): + data = {} + data['message'] = '{0}'.format(ex) + data['serviceContext'] = {'service': 'myapp'} + # ... add more metadata + fluent.event.Event('errors', data) + + # report exception data using: + try: + # simulate calling a method that's not defined + raise NameError + except Exception: + report(traceback.format_exc()) +# [END error_reporting] + + +if __name__ == '__main__': + simulate_error() diff --git a/samples/snippets/fluent_on_compute/main_test.py b/samples/snippets/fluent_on_compute/main_test.py new file mode 100644 index 00000000..11a24d03 --- /dev/null +++ b/samples/snippets/fluent_on_compute/main_test.py @@ -0,0 +1,23 @@ +# Copyright 2016 Google Inc. All rights reserved. +# +# 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. + +import mock + +import main + + +@mock.patch("fluent.event") +def test_error_sends(event_mock): + main.simulate_error() + event_mock.Event.assert_called_once_with(mock.ANY, mock.ANY) diff --git a/samples/snippets/fluent_on_compute/noxfile.py b/samples/snippets/fluent_on_compute/noxfile.py new file mode 100644 index 00000000..ba55d7ce --- /dev/null +++ b/samples/snippets/fluent_on_compute/noxfile.py @@ -0,0 +1,224 @@ +# Copyright 2019 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 print_function + +import os +from pathlib import Path +import sys + +import nox + + +# WARNING - WARNING - WARNING - WARNING - WARNING +# WARNING - WARNING - WARNING - WARNING - WARNING +# DO NOT EDIT THIS FILE EVER! +# WARNING - WARNING - WARNING - WARNING - WARNING +# WARNING - WARNING - WARNING - WARNING - WARNING + +# Copy `noxfile_config.py` to your directory and modify it instead. + + +# `TEST_CONFIG` dict is a configuration hook that allows users to +# modify the test configurations. The values here should be in sync +# with `noxfile_config.py`. Users will copy `noxfile_config.py` into +# their directory and modify it. + +TEST_CONFIG = { + # You can opt out from the test for specific Python versions. + 'ignored_versions': ["2.7"], + + # An envvar key for determining the project id to use. Change it + # to 'BUILD_SPECIFIC_GCLOUD_PROJECT' if you want to opt in using a + # build specific Cloud project. You can also use your own string + # to use your own Cloud project. + 'gcloud_project_env': 'GOOGLE_CLOUD_PROJECT', + # 'gcloud_project_env': 'BUILD_SPECIFIC_GCLOUD_PROJECT', + + # A dictionary you want to inject into your test. Don't put any + # secrets here. These values will override predefined values. + 'envs': {}, +} + + +try: + # Ensure we can import noxfile_config in the project's directory. + sys.path.append('.') + from noxfile_config import TEST_CONFIG_OVERRIDE +except ImportError as e: + print("No user noxfile_config found: detail: {}".format(e)) + TEST_CONFIG_OVERRIDE = {} + +# Update the TEST_CONFIG with the user supplied values. +TEST_CONFIG.update(TEST_CONFIG_OVERRIDE) + + +def get_pytest_env_vars(): + """Returns a dict for pytest invocation.""" + ret = {} + + # Override the GCLOUD_PROJECT and the alias. + env_key = TEST_CONFIG['gcloud_project_env'] + # This should error out if not set. + ret['GOOGLE_CLOUD_PROJECT'] = os.environ[env_key] + + # Apply user supplied envs. + ret.update(TEST_CONFIG['envs']) + return ret + + +# DO NOT EDIT - automatically generated. +# All versions used to tested samples. +ALL_VERSIONS = ["2.7", "3.6", "3.7", "3.8"] + +# Any default versions that should be ignored. +IGNORED_VERSIONS = TEST_CONFIG['ignored_versions'] + +TESTED_VERSIONS = sorted([v for v in ALL_VERSIONS if v not in IGNORED_VERSIONS]) + +INSTALL_LIBRARY_FROM_SOURCE = bool(os.environ.get("INSTALL_LIBRARY_FROM_SOURCE", False)) +# +# Style Checks +# + + +def _determine_local_import_names(start_dir): + """Determines all import names that should be considered "local". + + This is used when running the linter to insure that import order is + properly checked. + """ + file_ext_pairs = [os.path.splitext(path) for path in os.listdir(start_dir)] + return [ + basename + for basename, extension in file_ext_pairs + if extension == ".py" + or os.path.isdir(os.path.join(start_dir, basename)) + and basename not in ("__pycache__") + ] + + +# Linting with flake8. +# +# We ignore the following rules: +# E203: whitespace before ‘:’ +# E266: too many leading ‘#’ for block comment +# E501: line too long +# I202: Additional newline in a section of imports +# +# We also need to specify the rules which are ignored by default: +# ['E226', 'W504', 'E126', 'E123', 'W503', 'E24', 'E704', 'E121'] +FLAKE8_COMMON_ARGS = [ + "--show-source", + "--builtin=gettext", + "--max-complexity=20", + "--import-order-style=google", + "--exclude=.nox,.cache,env,lib,generated_pb2,*_pb2.py,*_pb2_grpc.py", + "--ignore=E121,E123,E126,E203,E226,E24,E266,E501,E704,W503,W504,I202", + "--max-line-length=88", +] + + +@nox.session +def lint(session): + session.install("flake8", "flake8-import-order") + + local_names = _determine_local_import_names(".") + args = FLAKE8_COMMON_ARGS + [ + "--application-import-names", + ",".join(local_names), + "." + ] + session.run("flake8", *args) + + +# +# Sample Tests +# + + +PYTEST_COMMON_ARGS = ["--junitxml=sponge_log.xml"] + + +def _session_tests(session, post_install=None): + """Runs py.test for a particular project.""" + if os.path.exists("requirements.txt"): + session.install("-r", "requirements.txt") + + if os.path.exists("requirements-test.txt"): + session.install("-r", "requirements-test.txt") + + if INSTALL_LIBRARY_FROM_SOURCE: + session.install("-e", _get_repo_root()) + + if post_install: + post_install(session) + + session.run( + "pytest", + *(PYTEST_COMMON_ARGS + session.posargs), + # Pytest will return 5 when no tests are collected. This can happen + # on travis where slow and flaky tests are excluded. + # See http://doc.pytest.org/en/latest/_modules/_pytest/main.html + success_codes=[0, 5], + env=get_pytest_env_vars() + ) + + +@nox.session(python=ALL_VERSIONS) +def py(session): + """Runs py.test for a sample using the specified version of Python.""" + if session.python in TESTED_VERSIONS: + _session_tests(session) + else: + session.skip("SKIPPED: {} tests are disabled for this sample.".format( + session.python + )) + + +# +# Readmegen +# + + +def _get_repo_root(): + """ Returns the root folder of the project. """ + # Get root of this repository. Assume we don't have directories nested deeper than 10 items. + p = Path(os.getcwd()) + for i in range(10): + if p is None: + break + if Path(p / ".git").exists(): + return str(p) + p = p.parent + raise Exception("Unable to detect repository root.") + + +GENERATED_READMES = sorted([x for x in Path(".").rglob("*.rst.in")]) + + +@nox.session +@nox.parametrize("path", GENERATED_READMES) +def readmegen(session, path): + """(Re-)generates the readme for a sample.""" + session.install("jinja2", "pyyaml") + dir_ = os.path.dirname(path) + + if os.path.exists(os.path.join(dir_, "requirements.txt")): + session.install("-r", os.path.join(dir_, "requirements.txt")) + + in_file = os.path.join(dir_, "README.rst.in") + session.run( + "python", _get_repo_root() + "/scripts/readme-gen/readme_gen.py", in_file + ) diff --git a/samples/snippets/fluent_on_compute/requirements-test.txt b/samples/snippets/fluent_on_compute/requirements-test.txt new file mode 100644 index 00000000..2466e250 --- /dev/null +++ b/samples/snippets/fluent_on_compute/requirements-test.txt @@ -0,0 +1,2 @@ +pytest==6.0.1 +mock==4.0.2 diff --git a/samples/snippets/fluent_on_compute/requirements.txt b/samples/snippets/fluent_on_compute/requirements.txt new file mode 100644 index 00000000..d1c2863f --- /dev/null +++ b/samples/snippets/fluent_on_compute/requirements.txt @@ -0,0 +1 @@ +fluent-logger==0.9.6 diff --git a/samples/snippets/fluent_on_compute/startup_script.sh b/samples/snippets/fluent_on_compute/startup_script.sh new file mode 100644 index 00000000..f2ef895d --- /dev/null +++ b/samples/snippets/fluent_on_compute/startup_script.sh @@ -0,0 +1,35 @@ +#!/usr/bin/env bash +# Copyright 2016 Google Inc. All rights reserved. +# +# 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. + +set -v + +curl -sSO "https://dl.google.com/cloudagents/install-logging-agent.sh" +chmod +x install-logging-agent.sh +./install-logging-agent.sh +mkdir -p /etc/google-fluentd/config.d/ +cat < /etc/google-fluentd/config.d/forward.conf + + type forward + port 24224 + +EOF +service google-fluentd restart + +apt-get update +apt-get install -yq \ + git build-essential supervisor python python-dev python-pip libffi-dev \ + libssl-dev +pip install fluent-logger + diff --git a/scripts/decrypt-secrets.sh b/scripts/decrypt-secrets.sh new file mode 100755 index 00000000..ff599eb2 --- /dev/null +++ b/scripts/decrypt-secrets.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +# Copyright 2015 Google Inc. All rights reserved. +# +# 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. + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +ROOT=$( dirname "$DIR" ) + +# Work from the project root. +cd $ROOT + +# Use SECRET_MANAGER_PROJECT if set, fallback to cloud-devrel-kokoro-resources. +PROJECT_ID="${SECRET_MANAGER_PROJECT:-cloud-devrel-kokoro-resources}" + +gcloud secrets versions access latest --secret="python-docs-samples-test-env" \ + > testing/test-env.sh +gcloud secrets versions access latest \ + --secret="python-docs-samples-service-account" \ + > testing/service-account.json +gcloud secrets versions access latest \ + --secret="python-docs-samples-client-secrets" \ + > testing/client-secrets.json \ No newline at end of file diff --git a/scripts/fixup_errorreporting_v1beta1_keywords.py b/scripts/fixup_errorreporting_v1beta1_keywords.py new file mode 100644 index 00000000..fcb0bab9 --- /dev/null +++ b/scripts/fixup_errorreporting_v1beta1_keywords.py @@ -0,0 +1,183 @@ +# -*- 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. +# + +import argparse +import os +import libcst as cst +import pathlib +import sys +from typing import (Any, Callable, Dict, List, Sequence, Tuple) + + +def partition( + predicate: Callable[[Any], bool], + iterator: Sequence[Any] +) -> Tuple[List[Any], List[Any]]: + """A stable, out-of-place partition.""" + results = ([], []) + + for i in iterator: + results[int(predicate(i))].append(i) + + # Returns trueList, falseList + return results[1], results[0] + + +class errorreportingCallTransformer(cst.CSTTransformer): + CTRL_PARAMS: Tuple[str] = ('retry', 'timeout', 'metadata') + METHOD_TO_PARAMS: Dict[str, Tuple[str]] = { + 'delete_events': ('project_name', ), + 'get_group': ('group_name', ), + 'list_events': ('project_name', 'group_id', 'service_filter', 'time_range', 'page_size', 'page_token', ), + 'list_group_stats': ('project_name', 'group_id', 'service_filter', 'time_range', 'timed_count_duration', 'alignment', 'alignment_time', 'order', 'page_size', 'page_token', ), + 'report_error_event': ('project_name', 'event', ), + 'update_group': ('group', ), + + } + + def leave_Call(self, original: cst.Call, updated: cst.Call) -> cst.CSTNode: + try: + key = original.func.attr.value + kword_params = self.METHOD_TO_PARAMS[key] + except (AttributeError, KeyError): + # Either not a method from the API or too convoluted to be sure. + return updated + + # If the existing code is valid, keyword args come after positional args. + # Therefore, all positional args must map to the first parameters. + args, kwargs = partition(lambda a: not bool(a.keyword), updated.args) + if any(k.keyword.value == "request" for k in kwargs): + # We've already fixed this file, don't fix it again. + return updated + + kwargs, ctrl_kwargs = partition( + lambda a: not a.keyword.value in self.CTRL_PARAMS, + kwargs + ) + + args, ctrl_args = args[:len(kword_params)], args[len(kword_params):] + ctrl_kwargs.extend(cst.Arg(value=a.value, keyword=cst.Name(value=ctrl)) + for a, ctrl in zip(ctrl_args, self.CTRL_PARAMS)) + + request_arg = cst.Arg( + value=cst.Dict([ + cst.DictElement( + cst.SimpleString("'{}'".format(name)), + cst.Element(value=arg.value) + ) + # Note: the args + kwargs looks silly, but keep in mind that + # the control parameters had to be stripped out, and that + # those could have been passed positionally or by keyword. + for name, arg in zip(kword_params, args + kwargs)]), + keyword=cst.Name("request") + ) + + return updated.with_changes( + args=[request_arg] + ctrl_kwargs + ) + + +def fix_files( + in_dir: pathlib.Path, + out_dir: pathlib.Path, + *, + transformer=errorreportingCallTransformer(), +): + """Duplicate the input dir to the output dir, fixing file method calls. + + Preconditions: + * in_dir is a real directory + * out_dir is a real, empty directory + """ + pyfile_gen = ( + pathlib.Path(os.path.join(root, f)) + for root, _, files in os.walk(in_dir) + for f in files if os.path.splitext(f)[1] == ".py" + ) + + for fpath in pyfile_gen: + with open(fpath, 'r') as f: + src = f.read() + + # Parse the code and insert method call fixes. + tree = cst.parse_module(src) + updated = tree.visit(transformer) + + # Create the path and directory structure for the new file. + updated_path = out_dir.joinpath(fpath.relative_to(in_dir)) + updated_path.parent.mkdir(parents=True, exist_ok=True) + + # Generate the updated source file at the corresponding path. + with open(updated_path, 'w') as f: + f.write(updated.code) + + +if __name__ == '__main__': + parser = argparse.ArgumentParser( + description="""Fix up source that uses the errorreporting client library. + +The existing sources are NOT overwritten but are copied to output_dir with changes made. + +Note: This tool operates at a best-effort level at converting positional + parameters in client method calls to keyword based parameters. + Cases where it WILL FAIL include + A) * or ** expansion in a method call. + B) Calls via function or method alias (includes free function calls) + C) Indirect or dispatched calls (e.g. the method is looked up dynamically) + + These all constitute false negatives. The tool will also detect false + positives when an API method shares a name with another method. +""") + parser.add_argument( + '-d', + '--input-directory', + required=True, + dest='input_dir', + help='the input directory to walk for python files to fix up', + ) + parser.add_argument( + '-o', + '--output-directory', + required=True, + dest='output_dir', + help='the directory to output files fixed via un-flattening', + ) + args = parser.parse_args() + input_dir = pathlib.Path(args.input_dir) + output_dir = pathlib.Path(args.output_dir) + if not input_dir.is_dir(): + print( + f"input directory '{input_dir}' does not exist or is not a directory", + file=sys.stderr, + ) + sys.exit(-1) + + if not output_dir.is_dir(): + print( + f"output directory '{output_dir}' does not exist or is not a directory", + file=sys.stderr, + ) + sys.exit(-1) + + if os.listdir(output_dir): + print( + f"output directory '{output_dir}' is not empty", + file=sys.stderr, + ) + sys.exit(-1) + + fix_files(input_dir, output_dir) diff --git a/scripts/readme-gen/readme_gen.py b/scripts/readme-gen/readme_gen.py new file mode 100644 index 00000000..d309d6e9 --- /dev/null +++ b/scripts/readme-gen/readme_gen.py @@ -0,0 +1,66 @@ +#!/usr/bin/env python + +# Copyright 2016 Google Inc +# +# 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. + +"""Generates READMEs using configuration defined in yaml.""" + +import argparse +import io +import os +import subprocess + +import jinja2 +import yaml + + +jinja_env = jinja2.Environment( + trim_blocks=True, + loader=jinja2.FileSystemLoader( + os.path.abspath(os.path.join(os.path.dirname(__file__), 'templates')))) + +README_TMPL = jinja_env.get_template('README.tmpl.rst') + + +def get_help(file): + return subprocess.check_output(['python', file, '--help']).decode() + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument('source') + parser.add_argument('--destination', default='README.rst') + + args = parser.parse_args() + + source = os.path.abspath(args.source) + root = os.path.dirname(source) + destination = os.path.join(root, args.destination) + + jinja_env.globals['get_help'] = get_help + + with io.open(source, 'r') as f: + config = yaml.load(f) + + # This allows get_help to execute in the right directory. + os.chdir(root) + + output = README_TMPL.render(config) + + with io.open(destination, 'w') as f: + f.write(output) + + +if __name__ == '__main__': + main() diff --git a/scripts/readme-gen/templates/README.tmpl.rst b/scripts/readme-gen/templates/README.tmpl.rst new file mode 100644 index 00000000..4fd23976 --- /dev/null +++ b/scripts/readme-gen/templates/README.tmpl.rst @@ -0,0 +1,87 @@ +{# The following line is a lie. BUT! Once jinja2 is done with it, it will + become truth! #} +.. This file is automatically generated. Do not edit this file directly. + +{{product.name}} Python Samples +=============================================================================== + +.. image:: https://gstatic.com/cloudssh/images/open-btn.png + :target: https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/GoogleCloudPlatform/python-docs-samples&page=editor&open_in_editor={{folder}}/README.rst + + +This directory contains samples for {{product.name}}. {{product.description}} + +{{description}} + +.. _{{product.name}}: {{product.url}} + +{% if required_api_url %} +To run the sample, you need to enable the API at: {{required_api_url}} +{% endif %} + +{% if required_role %} +To run the sample, you need to have `{{required_role}}` role. +{% endif %} + +{{other_required_steps}} + +{% if setup %} +Setup +------------------------------------------------------------------------------- + +{% for section in setup %} + +{% include section + '.tmpl.rst' %} + +{% endfor %} +{% endif %} + +{% if samples %} +Samples +------------------------------------------------------------------------------- + +{% for sample in samples %} +{{sample.name}} ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +{% if not sample.hide_cloudshell_button %} +.. image:: https://gstatic.com/cloudssh/images/open-btn.png + :target: https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/GoogleCloudPlatform/python-docs-samples&page=editor&open_in_editor={{folder}}/{{sample.file}},{{folder}}/README.rst +{% endif %} + + +{{sample.description}} + +To run this sample: + +.. code-block:: bash + + $ python {{sample.file}} +{% if sample.show_help %} + + {{get_help(sample.file)|indent}} +{% endif %} + + +{% endfor %} +{% endif %} + +{% if cloud_client_library %} + +The client library +------------------------------------------------------------------------------- + +This sample uses the `Google Cloud Client Library for Python`_. +You can read the documentation for more details on API usage and use GitHub +to `browse the source`_ and `report issues`_. + +.. _Google Cloud Client Library for Python: + https://googlecloudplatform.github.io/google-cloud-python/ +.. _browse the source: + https://github.com/GoogleCloudPlatform/google-cloud-python +.. _report issues: + https://github.com/GoogleCloudPlatform/google-cloud-python/issues + +{% endif %} + +.. _Google Cloud SDK: https://cloud.google.com/sdk/ \ No newline at end of file diff --git a/scripts/readme-gen/templates/auth.tmpl.rst b/scripts/readme-gen/templates/auth.tmpl.rst new file mode 100644 index 00000000..1446b94a --- /dev/null +++ b/scripts/readme-gen/templates/auth.tmpl.rst @@ -0,0 +1,9 @@ +Authentication +++++++++++++++ + +This sample requires you to have authentication setup. Refer to the +`Authentication Getting Started Guide`_ for instructions on setting up +credentials for applications. + +.. _Authentication Getting Started Guide: + https://cloud.google.com/docs/authentication/getting-started diff --git a/scripts/readme-gen/templates/auth_api_key.tmpl.rst b/scripts/readme-gen/templates/auth_api_key.tmpl.rst new file mode 100644 index 00000000..11957ce2 --- /dev/null +++ b/scripts/readme-gen/templates/auth_api_key.tmpl.rst @@ -0,0 +1,14 @@ +Authentication +++++++++++++++ + +Authentication for this service is done via an `API Key`_. To obtain an API +Key: + +1. Open the `Cloud Platform Console`_ +2. Make sure that billing is enabled for your project. +3. From the **Credentials** page, create a new **API Key** or use an existing + one for your project. + +.. _API Key: + https://developers.google.com/api-client-library/python/guide/aaa_apikeys +.. _Cloud Console: https://console.cloud.google.com/project?_ diff --git a/scripts/readme-gen/templates/install_deps.tmpl.rst b/scripts/readme-gen/templates/install_deps.tmpl.rst new file mode 100644 index 00000000..a0406dba --- /dev/null +++ b/scripts/readme-gen/templates/install_deps.tmpl.rst @@ -0,0 +1,29 @@ +Install Dependencies +++++++++++++++++++++ + +#. Clone python-docs-samples and change directory to the sample directory you want to use. + + .. code-block:: bash + + $ git clone https://github.com/GoogleCloudPlatform/python-docs-samples.git + +#. Install `pip`_ and `virtualenv`_ if you do not already have them. You may want to refer to the `Python Development Environment Setup Guide`_ for Google Cloud Platform for instructions. + + .. _Python Development Environment Setup Guide: + https://cloud.google.com/python/setup + +#. Create a virtualenv. Samples are compatible with Python 2.7 and 3.4+. + + .. code-block:: bash + + $ virtualenv env + $ source env/bin/activate + +#. Install the dependencies needed to run the samples. + + .. code-block:: bash + + $ pip install -r requirements.txt + +.. _pip: https://pip.pypa.io/ +.. _virtualenv: https://virtualenv.pypa.io/ diff --git a/scripts/readme-gen/templates/install_portaudio.tmpl.rst b/scripts/readme-gen/templates/install_portaudio.tmpl.rst new file mode 100644 index 00000000..5ea33d18 --- /dev/null +++ b/scripts/readme-gen/templates/install_portaudio.tmpl.rst @@ -0,0 +1,35 @@ +Install PortAudio ++++++++++++++++++ + +Install `PortAudio`_. This is required by the `PyAudio`_ library to stream +audio from your computer's microphone. PyAudio depends on PortAudio for cross-platform compatibility, and is installed differently depending on the +platform. + +* For Mac OS X, you can use `Homebrew`_:: + + brew install portaudio + + **Note**: if you encounter an error when running `pip install` that indicates + it can't find `portaudio.h`, try running `pip install` with the following + flags:: + + pip install --global-option='build_ext' \ + --global-option='-I/usr/local/include' \ + --global-option='-L/usr/local/lib' \ + pyaudio + +* For Debian / Ubuntu Linux:: + + apt-get install portaudio19-dev python-all-dev + +* Windows may work without having to install PortAudio explicitly (it will get + installed with PyAudio). + +For more details, see the `PyAudio installation`_ page. + + +.. _PyAudio: https://people.csail.mit.edu/hubert/pyaudio/ +.. _PortAudio: http://www.portaudio.com/ +.. _PyAudio installation: + https://people.csail.mit.edu/hubert/pyaudio/#downloads +.. _Homebrew: http://brew.sh diff --git a/setup.py b/setup.py index 845cfc36..fe3932ed 100644 --- a/setup.py +++ b/setup.py @@ -22,13 +22,18 @@ name = "google-cloud-error-reporting" description = "Stackdriver Error Reporting API client library" -version = "0.34.0" +version = "1.0.0" # Should be one of: # 'Development Status :: 3 - Alpha' # 'Development Status :: 4 - Beta' # 'Development Status :: 5 - Production/Stable' release_status = "Development Status :: 4 - Beta" -dependencies = ["google-cloud-logging>=1.14.0, <2.0dev"] +dependencies = [ + "google-cloud-logging>=1.14.0, <2.0dev", + "google-api-core[grpc] >= 1.22.0, < 2.0.0dev", + "proto-plus >= 1.4.0", + "libcst >= 0.2.5", +] extras = {} @@ -43,7 +48,9 @@ # Only include packages under the 'google' namespace. Do not include tests, # benchmarks, etc. packages = [ - package for package in setuptools.find_packages() if package.startswith("google") + package + for package in setuptools.PEP420PackageFinder.find() + if package.startswith("google") ] # Determine which namespaces are needed. @@ -66,12 +73,10 @@ "Intended Audience :: Developers", "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", - "Programming Language :: Python :: 2", - "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", "Operating System :: OS Independent", "Topic :: Internet", ], @@ -80,7 +85,8 @@ namespace_packages=namespaces, install_requires=dependencies, extras_require=extras, - python_requires=">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*", + python_requires=">=3.6", + scripts=["scripts/fixup_errorreporting_v1beta1_keywords.py"], include_package_data=True, zip_safe=False, ) diff --git a/synth.metadata b/synth.metadata index 8ea0204f..5f054cfd 100644 --- a/synth.metadata +++ b/synth.metadata @@ -1,32 +1,24 @@ { "sources": [ - { - "generator": { - "name": "artman", - "version": "2.0.0", - "dockerImage": "googleapis/artman@sha256:b3b47805231a305d0f40c4bf069df20f6a2635574e6d4259fac651d3f9f6e098" - } - }, { "git": { "name": ".", - "remote": "git@github.com:googleapis/python-error-reporting.git", - "sha": "ff63d75f476e1eb3ff30f35b70d2dfa77dc17504" + "remote": "https://github.com/googleapis/python-error-reporting.git", + "sha": "eb586ff9fdbea553c863ba8803c213a5c001f9dc" } }, { "git": { - "name": "googleapis", - "remote": "https://github.com/googleapis/googleapis.git", - "sha": "756b174de4a122461993c1c583345533d819936d", - "internalRef": "308824110" + "name": "synthtool", + "remote": "https://github.com/googleapis/synthtool.git", + "sha": "cbcd64279572769b4d350bf8078bcd1f151c9684" } }, { "git": { "name": "synthtool", "remote": "https://github.com/googleapis/synthtool.git", - "sha": "01b6f23d24b27878b48667ce597876d66b59780e" + "sha": "cbcd64279572769b4d350bf8078bcd1f151c9684" } } ], @@ -37,8 +29,7 @@ "apiName": "errorreporting", "apiVersion": "v1beta1", "language": "python", - "generator": "gapic", - "config": "google/devtools/clouderrorreporting/artman_errorreporting.yaml" + "generator": "bazel" } } ] diff --git a/synth.py b/synth.py index d554697b..46a9fe17 100644 --- a/synth.py +++ b/synth.py @@ -15,6 +15,7 @@ """This script is used to synthesize generated parts of this library.""" import synthtool as s from synthtool import gcp +from synthtool.languages import python gapic = gcp.GAPICBazel() common = gcp.CommonTemplates() @@ -28,55 +29,25 @@ bazel_target="//google/devtools/clouderrorreporting/v1beta1:devtools-clouderrorreporting-v1beta1-py", include_protos=True, ) - -s.move(library / "google/cloud/devtools/clouderrorreporting_v1beta1/proto", - "google/cloud/errorreporting_v1beta1/proto") -s.move(library / "google/cloud/errorreporting_v1beta1/proto") -s.move(library / "google/cloud/errorreporting_v1beta1/gapic") -s.move(library / "tests/unit/gapic/v1beta1") -s.move(library / "tests/system/gapic/v1beta1") - -s.replace( - [ - "google/cloud/errorreporting_v1beta1/gapic/error_group_service_client.py", - "google/cloud/errorreporting_v1beta1/gapic/error_stats_service_client.py", - "google/cloud/errorreporting_v1beta1/gapic/ereport_errors_service_client.py", - ], - "google-cloud-devtools-clouderrorreporting", - "google-cloud-error-reporting", -) - -# Fix up imports -s.replace( - "google/**/*.py", - r"from google.cloud.devtools.clouderrorreporting_v1beta1.proto import ", - r"from google.cloud.errorreporting_v1beta1.proto import ", -) - -# Fix up docstrings in GAPIC clients -DISCARD_AUTH_BOILERPLATE = r""" - This endpoint accepts either an OAuth token, or an API key for - authentication. To use an API key, append it to the URL as the value of - a ``key`` parameter. For example: - - \.\. raw:: html -
POST
-            .*
-""" - -targets = [ - "google/cloud/errorreporting_v1beta1/gapic/*_client.py", - "google/cloud/errorreporting_v1beta1/gapic/transports/*_transport.py", -] - -s.replace(targets, DISCARD_AUTH_BOILERPLATE, r"") +s.move(library, excludes=["nox.py", "setup.py", "README.rst", "docs/index.rst", "google/cloud/errorreporting/"]) # ---------------------------------------------------------------------------- # Add templated files # ---------------------------------------------------------------------------- templated_files = common.py_library( - unit_cov_level=97, cov_level=98, system_test_dependencies=["test_utils"] + samples=True, # set to True only if there are samples + microgenerator=True, + system_test_dependencies=["test_utils"] ) -s.move(templated_files) +s.move(templated_files, excludes=[".coveragerc"]) # microgenerator has a good .coveragerc file + +# ---------------------------------------------------------------------------- +# Samples templates +# ---------------------------------------------------------------------------- +python.py_samples(skip_readmes=True) + +# TODO(busunkim): Use latest sphinx after microgenerator transition +s.replace("noxfile.py", """['"]sphinx['"]""", '"sphinx<3.0.0"') + s.shell.run(["nox", "-s", "blacken"], hide_output=False) diff --git a/testing/.gitignore b/testing/.gitignore new file mode 100644 index 00000000..b05fbd63 --- /dev/null +++ b/testing/.gitignore @@ -0,0 +1,3 @@ +test-env.sh +service-account.json +client-secrets.json \ No newline at end of file diff --git a/tests/system/gapic/v1beta1/test_system_report_errors_service_v1beta1.py b/tests/system/gapic/v1beta1/test_system_report_errors_service_v1beta1.py index bb423928..674a6997 100644 --- a/tests/system/gapic/v1beta1/test_system_report_errors_service_v1beta1.py +++ b/tests/system/gapic/v1beta1/test_system_report_errors_service_v1beta1.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -# Copyright 2019 Google LLC +# 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. @@ -18,8 +18,6 @@ import time from google.cloud import errorreporting_v1beta1 -from google.cloud.errorreporting_v1beta1.proto import common_pb2 -from google.cloud.errorreporting_v1beta1.proto import report_errors_service_pb2 class TestSystemReportErrorsService(object): @@ -27,7 +25,7 @@ def test_report_error_event(self): project_id = os.environ["PROJECT_ID"] client = errorreporting_v1beta1.ReportErrorsServiceClient() - project_name = client.project_path(project_id) + project_name = f"projects/{project_id}" message = "[MESSAGE]" service = "[SERVICE]" service_context = {"service": service} @@ -45,4 +43,6 @@ def test_report_error_event(self): "service_context": service_context, "context": context, } - response = client.report_error_event(project_name, event) + response = client.report_error_event( + request={"project_name": project_name, "event": event} + ) diff --git a/tests/system/test_system.py b/tests/system/test_system.py index cf454aec..77c00646 100644 --- a/tests/system/test_system.py +++ b/tests/system/test_system.py @@ -17,8 +17,7 @@ import unittest from google.cloud import error_reporting -from google.cloud.errorreporting_v1beta1.gapic import error_stats_service_client -from google.cloud.errorreporting_v1beta1.proto import error_stats_service_pb2 +import google.cloud.errorreporting_v1beta1 from google.protobuf.duration_pb2 import Duration from test_utils.retry import RetryResult @@ -53,20 +52,26 @@ def _list_groups(client): :param client: The client containing a project and credentials. :rtype: :class:`~google.gax.ResourceIterator` - :returns: Iterable of :class:`~.error_stats_service_pb2.ErrorGroupStats`. + :returns: Iterable of :class:`~.google.cloud.errorreporting_v1beta1.ErrorGroupStats`. """ - gax_api = error_stats_service_client.ErrorStatsServiceClient( + gax_api = google.cloud.errorreporting_v1beta1.ErrorStatsServiceClient( credentials=client._credentials ) - project_name = gax_api.project_path(client.project) + project_name = f"projects/{client.project}" - time_range = error_stats_service_pb2.QueryTimeRange() - time_range.period = error_stats_service_pb2.QueryTimeRange.PERIOD_1_HOUR + time_range = google.cloud.errorreporting_v1beta1.QueryTimeRange() + time_range.period = ( + google.cloud.errorreporting_v1beta1.QueryTimeRange.Period.PERIOD_1_HOUR + ) duration = Duration(seconds=60 * 60) return gax_api.list_group_stats( - project_name, time_range, timed_count_duration=duration + request={ + "project_name": project_name, + "time_range": time_range, + "timed_count_duration": duration, + } ) diff --git a/tests/unit/gapic/errorreporting_v1beta1/__init__.py b/tests/unit/gapic/errorreporting_v1beta1/__init__.py new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/tests/unit/gapic/errorreporting_v1beta1/__init__.py @@ -0,0 +1 @@ + diff --git a/tests/unit/gapic/errorreporting_v1beta1/test_error_group_service.py b/tests/unit/gapic/errorreporting_v1beta1/test_error_group_service.py new file mode 100644 index 00000000..cf93f906 --- /dev/null +++ b/tests/unit/gapic/errorreporting_v1beta1/test_error_group_service.py @@ -0,0 +1,1139 @@ +# -*- 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. +# + +import os +import mock + +import grpc +from grpc.experimental import aio +import math +import pytest +from proto.marshal.rules.dates import DurationRule, TimestampRule + +from google import auth +from google.api_core import client_options +from google.api_core import 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.exceptions import MutualTLSChannelError +from google.cloud.errorreporting_v1beta1.services.error_group_service import ( + ErrorGroupServiceAsyncClient, +) +from google.cloud.errorreporting_v1beta1.services.error_group_service import ( + ErrorGroupServiceClient, +) +from google.cloud.errorreporting_v1beta1.services.error_group_service import transports +from google.cloud.errorreporting_v1beta1.types import common +from google.cloud.errorreporting_v1beta1.types import error_group_service +from google.oauth2 import service_account + + +def client_cert_source_callback(): + return b"cert bytes", b"key bytes" + + +# If default endpoint is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint(client): + return ( + "foo.googleapis.com" + if ("localhost" in client.DEFAULT_ENDPOINT) + else client.DEFAULT_ENDPOINT + ) + + +def test__get_default_mtls_endpoint(): + api_endpoint = "example.googleapis.com" + api_mtls_endpoint = "example.mtls.googleapis.com" + sandbox_endpoint = "example.sandbox.googleapis.com" + sandbox_mtls_endpoint = "example.mtls.sandbox.googleapis.com" + non_googleapi = "api.example.com" + + assert ErrorGroupServiceClient._get_default_mtls_endpoint(None) is None + assert ( + ErrorGroupServiceClient._get_default_mtls_endpoint(api_endpoint) + == api_mtls_endpoint + ) + assert ( + ErrorGroupServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) + == api_mtls_endpoint + ) + assert ( + ErrorGroupServiceClient._get_default_mtls_endpoint(sandbox_endpoint) + == sandbox_mtls_endpoint + ) + assert ( + ErrorGroupServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) + == sandbox_mtls_endpoint + ) + assert ( + ErrorGroupServiceClient._get_default_mtls_endpoint(non_googleapi) + == non_googleapi + ) + + +@pytest.mark.parametrize( + "client_class", [ErrorGroupServiceClient, ErrorGroupServiceAsyncClient] +) +def test_error_group_service_client_from_service_account_file(client_class): + creds = credentials.AnonymousCredentials() + with mock.patch.object( + service_account.Credentials, "from_service_account_file" + ) as factory: + factory.return_value = creds + client = client_class.from_service_account_file("dummy/file/path.json") + assert client._transport._credentials == creds + + client = client_class.from_service_account_json("dummy/file/path.json") + assert client._transport._credentials == creds + + assert client._transport._host == "clouderrorreporting.googleapis.com:443" + + +def test_error_group_service_client_get_transport_class(): + transport = ErrorGroupServiceClient.get_transport_class() + assert transport == transports.ErrorGroupServiceGrpcTransport + + transport = ErrorGroupServiceClient.get_transport_class("grpc") + assert transport == transports.ErrorGroupServiceGrpcTransport + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + (ErrorGroupServiceClient, transports.ErrorGroupServiceGrpcTransport, "grpc"), + ( + ErrorGroupServiceAsyncClient, + transports.ErrorGroupServiceGrpcAsyncIOTransport, + "grpc_asyncio", + ), + ], +) +@mock.patch.object( + ErrorGroupServiceClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(ErrorGroupServiceClient), +) +@mock.patch.object( + ErrorGroupServiceAsyncClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(ErrorGroupServiceAsyncClient), +) +def test_error_group_service_client_client_options( + client_class, transport_class, transport_name +): + # Check that if channel is provided we won't create a new one. + with mock.patch.object(ErrorGroupServiceClient, "get_transport_class") as gtc: + transport = transport_class(credentials=credentials.AnonymousCredentials()) + client = client_class(transport=transport) + gtc.assert_not_called() + + # Check that if channel is provided via str we will create a new one. + with mock.patch.object(ErrorGroupServiceClient, "get_transport_class") as gtc: + client = client_class(transport=transport_name) + gtc.assert_called() + + # Check the case api_endpoint is provided. + options = client_options.ClientOptions(api_endpoint="squid.clam.whelk") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + api_mtls_endpoint="squid.clam.whelk", + client_cert_source=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS is + # "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "never"}): + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class() + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + api_mtls_endpoint=client.DEFAULT_ENDPOINT, + client_cert_source=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS is + # "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "always"}): + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class() + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_MTLS_ENDPOINT, + scopes=None, + api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT, + client_cert_source=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + + # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is + # "auto", and client_cert_source is provided. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}): + options = client_options.ClientOptions( + client_cert_source=client_cert_source_callback + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_MTLS_ENDPOINT, + scopes=None, + api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT, + client_cert_source=client_cert_source_callback, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + + # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is + # "auto", and default_client_cert_source is provided. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, + ): + patched.return_value = None + client = client_class() + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_MTLS_ENDPOINT, + scopes=None, + api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT, + client_cert_source=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + + # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is + # "auto", but client_cert_source and default_client_cert_source are None. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, + ): + patched.return_value = None + client = client_class() + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + api_mtls_endpoint=client.DEFAULT_ENDPOINT, + client_cert_source=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "Unsupported"}): + with pytest.raises(MutualTLSChannelError): + client = client_class() + + # Check the case quota_project_id is provided + options = client_options.ClientOptions(quota_project_id="octopus") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + api_mtls_endpoint=client.DEFAULT_ENDPOINT, + client_cert_source=None, + quota_project_id="octopus", + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + (ErrorGroupServiceClient, transports.ErrorGroupServiceGrpcTransport, "grpc"), + ( + ErrorGroupServiceAsyncClient, + transports.ErrorGroupServiceGrpcAsyncIOTransport, + "grpc_asyncio", + ), + ], +) +def test_error_group_service_client_client_options_scopes( + client_class, transport_class, transport_name +): + # Check the case scopes are provided. + options = client_options.ClientOptions(scopes=["1", "2"],) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=["1", "2"], + api_mtls_endpoint=client.DEFAULT_ENDPOINT, + client_cert_source=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + (ErrorGroupServiceClient, transports.ErrorGroupServiceGrpcTransport, "grpc"), + ( + ErrorGroupServiceAsyncClient, + transports.ErrorGroupServiceGrpcAsyncIOTransport, + "grpc_asyncio", + ), + ], +) +def test_error_group_service_client_client_options_credentials_file( + client_class, transport_class, transport_name +): + # Check the case credentials file is provided. + options = client_options.ClientOptions(credentials_file="credentials.json") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file="credentials.json", + host=client.DEFAULT_ENDPOINT, + scopes=None, + api_mtls_endpoint=client.DEFAULT_ENDPOINT, + client_cert_source=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + + +def test_error_group_service_client_client_options_from_dict(): + with mock.patch( + "google.cloud.errorreporting_v1beta1.services.error_group_service.transports.ErrorGroupServiceGrpcTransport.__init__" + ) as grpc_transport: + grpc_transport.return_value = None + client = ErrorGroupServiceClient( + client_options={"api_endpoint": "squid.clam.whelk"} + ) + grpc_transport.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + api_mtls_endpoint="squid.clam.whelk", + client_cert_source=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + + +def test_get_group( + transport: str = "grpc", request_type=error_group_service.GetGroupRequest +): + client = ErrorGroupServiceClient( + credentials=credentials.AnonymousCredentials(), transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client._transport.get_group), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = common.ErrorGroup( + name="name_value", group_id="group_id_value", + ) + + response = client.get_group(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + + assert args[0] == error_group_service.GetGroupRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, common.ErrorGroup) + + assert response.name == "name_value" + + assert response.group_id == "group_id_value" + + +def test_get_group_from_dict(): + test_get_group(request_type=dict) + + +@pytest.mark.asyncio +async def test_get_group_async(transport: str = "grpc_asyncio"): + client = ErrorGroupServiceAsyncClient( + credentials=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 = error_group_service.GetGroupRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client._client._transport.get_group), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + common.ErrorGroup(name="name_value", group_id="group_id_value",) + ) + + response = await client.get_group(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 response is the type that we expect. + assert isinstance(response, common.ErrorGroup) + + assert response.name == "name_value" + + assert response.group_id == "group_id_value" + + +def test_get_group_field_headers(): + client = ErrorGroupServiceClient(credentials=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 = error_group_service.GetGroupRequest() + request.group_name = "group_name/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client._transport.get_group), "__call__") as call: + call.return_value = common.ErrorGroup() + + client.get_group(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", "group_name=group_name/value",) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_get_group_field_headers_async(): + client = ErrorGroupServiceAsyncClient( + credentials=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 = error_group_service.GetGroupRequest() + request.group_name = "group_name/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client._client._transport.get_group), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(common.ErrorGroup()) + + await client.get_group(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", "group_name=group_name/value",) in kw["metadata"] + + +def test_get_group_flattened(): + client = ErrorGroupServiceClient(credentials=credentials.AnonymousCredentials(),) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client._transport.get_group), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = common.ErrorGroup() + + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.get_group(group_name="group_name_value",) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + + assert args[0].group_name == "group_name_value" + + +def test_get_group_flattened_error(): + client = ErrorGroupServiceClient(credentials=credentials.AnonymousCredentials(),) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_group( + error_group_service.GetGroupRequest(), group_name="group_name_value", + ) + + +@pytest.mark.asyncio +async def test_get_group_flattened_async(): + client = ErrorGroupServiceAsyncClient( + credentials=credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client._client._transport.get_group), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = common.ErrorGroup() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(common.ErrorGroup()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.get_group(group_name="group_name_value",) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + + assert args[0].group_name == "group_name_value" + + +@pytest.mark.asyncio +async def test_get_group_flattened_error_async(): + client = ErrorGroupServiceAsyncClient( + credentials=credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.get_group( + error_group_service.GetGroupRequest(), group_name="group_name_value", + ) + + +def test_update_group( + transport: str = "grpc", request_type=error_group_service.UpdateGroupRequest +): + client = ErrorGroupServiceClient( + credentials=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.update_group), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = common.ErrorGroup( + name="name_value", group_id="group_id_value", + ) + + response = client.update_group(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + + assert args[0] == error_group_service.UpdateGroupRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, common.ErrorGroup) + + assert response.name == "name_value" + + assert response.group_id == "group_id_value" + + +def test_update_group_from_dict(): + test_update_group(request_type=dict) + + +@pytest.mark.asyncio +async def test_update_group_async(transport: str = "grpc_asyncio"): + client = ErrorGroupServiceAsyncClient( + credentials=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 = error_group_service.UpdateGroupRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client._client._transport.update_group), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + common.ErrorGroup(name="name_value", group_id="group_id_value",) + ) + + response = await client.update_group(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 response is the type that we expect. + assert isinstance(response, common.ErrorGroup) + + assert response.name == "name_value" + + assert response.group_id == "group_id_value" + + +def test_update_group_field_headers(): + client = ErrorGroupServiceClient(credentials=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 = error_group_service.UpdateGroupRequest() + request.group.name = "group.name/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client._transport.update_group), "__call__") as call: + call.return_value = common.ErrorGroup() + + client.update_group(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", "group.name=group.name/value",) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_update_group_field_headers_async(): + client = ErrorGroupServiceAsyncClient( + credentials=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 = error_group_service.UpdateGroupRequest() + request.group.name = "group.name/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client._client._transport.update_group), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(common.ErrorGroup()) + + await client.update_group(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", "group.name=group.name/value",) in kw["metadata"] + + +def test_update_group_flattened(): + client = ErrorGroupServiceClient(credentials=credentials.AnonymousCredentials(),) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client._transport.update_group), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = common.ErrorGroup() + + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.update_group(group=common.ErrorGroup(name="name_value"),) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + + assert args[0].group == common.ErrorGroup(name="name_value") + + +def test_update_group_flattened_error(): + client = ErrorGroupServiceClient(credentials=credentials.AnonymousCredentials(),) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.update_group( + error_group_service.UpdateGroupRequest(), + group=common.ErrorGroup(name="name_value"), + ) + + +@pytest.mark.asyncio +async def test_update_group_flattened_async(): + client = ErrorGroupServiceAsyncClient( + credentials=credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client._client._transport.update_group), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = common.ErrorGroup() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(common.ErrorGroup()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.update_group( + group=common.ErrorGroup(name="name_value"), + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + + assert args[0].group == common.ErrorGroup(name="name_value") + + +@pytest.mark.asyncio +async def test_update_group_flattened_error_async(): + client = ErrorGroupServiceAsyncClient( + credentials=credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.update_group( + error_group_service.UpdateGroupRequest(), + group=common.ErrorGroup(name="name_value"), + ) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.ErrorGroupServiceGrpcTransport( + credentials=credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ErrorGroupServiceClient( + credentials=credentials.AnonymousCredentials(), transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.ErrorGroupServiceGrpcTransport( + credentials=credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ErrorGroupServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.ErrorGroupServiceGrpcTransport( + credentials=credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ErrorGroupServiceClient( + client_options={"scopes": ["1", "2"]}, transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.ErrorGroupServiceGrpcTransport( + credentials=credentials.AnonymousCredentials(), + ) + client = ErrorGroupServiceClient(transport=transport) + assert client._transport is transport + + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.ErrorGroupServiceGrpcTransport( + credentials=credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.ErrorGroupServiceGrpcAsyncIOTransport( + credentials=credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + +def test_transport_grpc_default(): + # A client should use the gRPC transport by default. + client = ErrorGroupServiceClient(credentials=credentials.AnonymousCredentials(),) + assert isinstance(client._transport, transports.ErrorGroupServiceGrpcTransport,) + + +def test_error_group_service_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(exceptions.DuplicateCredentialArgs): + transport = transports.ErrorGroupServiceTransport( + credentials=credentials.AnonymousCredentials(), + credentials_file="credentials.json", + ) + + +def test_error_group_service_base_transport(): + # Instantiate the base transport. + with mock.patch( + "google.cloud.errorreporting_v1beta1.services.error_group_service.transports.ErrorGroupServiceTransport.__init__" + ) as Transport: + Transport.return_value = None + transport = transports.ErrorGroupServiceTransport( + credentials=credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + "get_group", + "update_group", + ) + for method in methods: + with pytest.raises(NotImplementedError): + getattr(transport, method)(request=object()) + + +def test_error_group_service_base_transport_with_credentials_file(): + # Instantiate the base transport with a credentials file + with mock.patch.object( + auth, "load_credentials_from_file" + ) as load_creds, mock.patch( + "google.cloud.errorreporting_v1beta1.services.error_group_service.transports.ErrorGroupServiceTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + load_creds.return_value = (credentials.AnonymousCredentials(), None) + transport = transports.ErrorGroupServiceTransport( + credentials_file="credentials.json", quota_project_id="octopus", + ) + load_creds.assert_called_once_with( + "credentials.json", + scopes=("https://www.googleapis.com/auth/cloud-platform",), + quota_project_id="octopus", + ) + + +def test_error_group_service_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) + ErrorGroupServiceClient() + adc.assert_called_once_with( + scopes=("https://www.googleapis.com/auth/cloud-platform",), + quota_project_id=None, + ) + + +def test_error_group_service_transport_auth_adc(): + # 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.ErrorGroupServiceGrpcTransport( + host="squid.clam.whelk", quota_project_id="octopus" + ) + adc.assert_called_once_with( + scopes=("https://www.googleapis.com/auth/cloud-platform",), + quota_project_id="octopus", + ) + + +def test_error_group_service_host_no_port(): + client = ErrorGroupServiceClient( + credentials=credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions( + api_endpoint="clouderrorreporting.googleapis.com" + ), + ) + assert client._transport._host == "clouderrorreporting.googleapis.com:443" + + +def test_error_group_service_host_with_port(): + client = ErrorGroupServiceClient( + credentials=credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions( + api_endpoint="clouderrorreporting.googleapis.com:8000" + ), + ) + assert client._transport._host == "clouderrorreporting.googleapis.com:8000" + + +def test_error_group_service_grpc_transport_channel(): + channel = grpc.insecure_channel("http://localhost/") + + # Check that if channel is provided, mtls endpoint and client_cert_source + # won't be used. + callback = mock.MagicMock() + transport = transports.ErrorGroupServiceGrpcTransport( + host="squid.clam.whelk", + channel=channel, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=callback, + ) + assert transport.grpc_channel == channel + assert transport._host == "squid.clam.whelk:443" + assert not callback.called + + +def test_error_group_service_grpc_asyncio_transport_channel(): + channel = aio.insecure_channel("http://localhost/") + + # Check that if channel is provided, mtls endpoint and client_cert_source + # won't be used. + callback = mock.MagicMock() + transport = transports.ErrorGroupServiceGrpcAsyncIOTransport( + host="squid.clam.whelk", + channel=channel, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=callback, + ) + assert transport.grpc_channel == channel + assert transport._host == "squid.clam.whelk:443" + assert not callback.called + + +@mock.patch("grpc.ssl_channel_credentials", autospec=True) +@mock.patch("google.api_core.grpc_helpers.create_channel", autospec=True) +def test_error_group_service_grpc_transport_channel_mtls_with_client_cert_source( + grpc_create_channel, grpc_ssl_channel_cred +): + # Check that if channel is None, but api_mtls_endpoint and client_cert_source + # are provided, then a mTLS channel will be created. + mock_cred = mock.Mock() + + mock_ssl_cred = mock.Mock() + grpc_ssl_channel_cred.return_value = mock_ssl_cred + + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + transport = transports.ErrorGroupServiceGrpcTransport( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=client_cert_source_callback, + ) + grpc_ssl_channel_cred.assert_called_once_with( + certificate_chain=b"cert bytes", private_key=b"key bytes" + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + credentials_file=None, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + ) + assert transport.grpc_channel == mock_grpc_channel + + +@mock.patch("grpc.ssl_channel_credentials", autospec=True) +@mock.patch("google.api_core.grpc_helpers_async.create_channel", autospec=True) +def test_error_group_service_grpc_asyncio_transport_channel_mtls_with_client_cert_source( + grpc_create_channel, grpc_ssl_channel_cred +): + # Check that if channel is None, but api_mtls_endpoint and client_cert_source + # are provided, then a mTLS channel will be created. + mock_cred = mock.Mock() + + mock_ssl_cred = mock.Mock() + grpc_ssl_channel_cred.return_value = mock_ssl_cred + + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + transport = transports.ErrorGroupServiceGrpcAsyncIOTransport( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=client_cert_source_callback, + ) + grpc_ssl_channel_cred.assert_called_once_with( + certificate_chain=b"cert bytes", private_key=b"key bytes" + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + credentials_file=None, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + ) + assert transport.grpc_channel == mock_grpc_channel + + +@pytest.mark.parametrize( + "api_mtls_endpoint", ["mtls.squid.clam.whelk", "mtls.squid.clam.whelk:443"] +) +@mock.patch("google.api_core.grpc_helpers.create_channel", autospec=True) +def test_error_group_service_grpc_transport_channel_mtls_with_adc( + grpc_create_channel, api_mtls_endpoint +): + # Check that if channel and client_cert_source are None, but api_mtls_endpoint + # is provided, then a mTLS channel will be created with SSL ADC. + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + # Mock google.auth.transport.grpc.SslCredentials class. + mock_ssl_cred = mock.Mock() + with mock.patch.multiple( + "google.auth.transport.grpc.SslCredentials", + __init__=mock.Mock(return_value=None), + ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), + ): + mock_cred = mock.Mock() + transport = transports.ErrorGroupServiceGrpcTransport( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint=api_mtls_endpoint, + client_cert_source=None, + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + credentials_file=None, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + ) + assert transport.grpc_channel == mock_grpc_channel + + +@pytest.mark.parametrize( + "api_mtls_endpoint", ["mtls.squid.clam.whelk", "mtls.squid.clam.whelk:443"] +) +@mock.patch("google.api_core.grpc_helpers_async.create_channel", autospec=True) +def test_error_group_service_grpc_asyncio_transport_channel_mtls_with_adc( + grpc_create_channel, api_mtls_endpoint +): + # Check that if channel and client_cert_source are None, but api_mtls_endpoint + # is provided, then a mTLS channel will be created with SSL ADC. + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + # Mock google.auth.transport.grpc.SslCredentials class. + mock_ssl_cred = mock.Mock() + with mock.patch.multiple( + "google.auth.transport.grpc.SslCredentials", + __init__=mock.Mock(return_value=None), + ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), + ): + mock_cred = mock.Mock() + transport = transports.ErrorGroupServiceGrpcAsyncIOTransport( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint=api_mtls_endpoint, + client_cert_source=None, + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + credentials_file=None, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + ) + assert transport.grpc_channel == mock_grpc_channel + + +def test_error_group_path(): + project = "squid" + group = "clam" + + expected = "projects/{project}/groups/{group}".format(project=project, group=group,) + actual = ErrorGroupServiceClient.error_group_path(project, group) + assert expected == actual + + +def test_parse_error_group_path(): + expected = { + "project": "whelk", + "group": "octopus", + } + path = ErrorGroupServiceClient.error_group_path(**expected) + + # Check that the path construction is reversible. + actual = ErrorGroupServiceClient.parse_error_group_path(path) + assert expected == actual + + +def test_client_withDEFAULT_CLIENT_INFO(): + client_info = gapic_v1.client_info.ClientInfo() + + with mock.patch.object( + transports.ErrorGroupServiceTransport, "_prep_wrapped_messages" + ) as prep: + client = ErrorGroupServiceClient( + credentials=credentials.AnonymousCredentials(), client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object( + transports.ErrorGroupServiceTransport, "_prep_wrapped_messages" + ) as prep: + transport_class = ErrorGroupServiceClient.get_transport_class() + transport = transport_class( + credentials=credentials.AnonymousCredentials(), client_info=client_info, + ) + prep.assert_called_once_with(client_info) diff --git a/tests/unit/gapic/errorreporting_v1beta1/test_error_stats_service.py b/tests/unit/gapic/errorreporting_v1beta1/test_error_stats_service.py new file mode 100644 index 00000000..d0f5fcf1 --- /dev/null +++ b/tests/unit/gapic/errorreporting_v1beta1/test_error_stats_service.py @@ -0,0 +1,1693 @@ +# -*- 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. +# + +import os +import mock + +import grpc +from grpc.experimental import aio +import math +import pytest +from proto.marshal.rules.dates import DurationRule, TimestampRule + +from google import auth +from google.api_core import client_options +from google.api_core import 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.exceptions import MutualTLSChannelError +from google.cloud.errorreporting_v1beta1.services.error_stats_service import ( + ErrorStatsServiceAsyncClient, +) +from google.cloud.errorreporting_v1beta1.services.error_stats_service import ( + ErrorStatsServiceClient, +) +from google.cloud.errorreporting_v1beta1.services.error_stats_service import pagers +from google.cloud.errorreporting_v1beta1.services.error_stats_service import transports +from google.cloud.errorreporting_v1beta1.types import common +from google.cloud.errorreporting_v1beta1.types import error_stats_service +from google.oauth2 import service_account +from google.protobuf import duration_pb2 as duration # type: ignore +from google.protobuf import timestamp_pb2 as timestamp # type: ignore + + +def client_cert_source_callback(): + return b"cert bytes", b"key bytes" + + +# If default endpoint is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint(client): + return ( + "foo.googleapis.com" + if ("localhost" in client.DEFAULT_ENDPOINT) + else client.DEFAULT_ENDPOINT + ) + + +def test__get_default_mtls_endpoint(): + api_endpoint = "example.googleapis.com" + api_mtls_endpoint = "example.mtls.googleapis.com" + sandbox_endpoint = "example.sandbox.googleapis.com" + sandbox_mtls_endpoint = "example.mtls.sandbox.googleapis.com" + non_googleapi = "api.example.com" + + assert ErrorStatsServiceClient._get_default_mtls_endpoint(None) is None + assert ( + ErrorStatsServiceClient._get_default_mtls_endpoint(api_endpoint) + == api_mtls_endpoint + ) + assert ( + ErrorStatsServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) + == api_mtls_endpoint + ) + assert ( + ErrorStatsServiceClient._get_default_mtls_endpoint(sandbox_endpoint) + == sandbox_mtls_endpoint + ) + assert ( + ErrorStatsServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) + == sandbox_mtls_endpoint + ) + assert ( + ErrorStatsServiceClient._get_default_mtls_endpoint(non_googleapi) + == non_googleapi + ) + + +@pytest.mark.parametrize( + "client_class", [ErrorStatsServiceClient, ErrorStatsServiceAsyncClient] +) +def test_error_stats_service_client_from_service_account_file(client_class): + creds = credentials.AnonymousCredentials() + with mock.patch.object( + service_account.Credentials, "from_service_account_file" + ) as factory: + factory.return_value = creds + client = client_class.from_service_account_file("dummy/file/path.json") + assert client._transport._credentials == creds + + client = client_class.from_service_account_json("dummy/file/path.json") + assert client._transport._credentials == creds + + assert client._transport._host == "clouderrorreporting.googleapis.com:443" + + +def test_error_stats_service_client_get_transport_class(): + transport = ErrorStatsServiceClient.get_transport_class() + assert transport == transports.ErrorStatsServiceGrpcTransport + + transport = ErrorStatsServiceClient.get_transport_class("grpc") + assert transport == transports.ErrorStatsServiceGrpcTransport + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + (ErrorStatsServiceClient, transports.ErrorStatsServiceGrpcTransport, "grpc"), + ( + ErrorStatsServiceAsyncClient, + transports.ErrorStatsServiceGrpcAsyncIOTransport, + "grpc_asyncio", + ), + ], +) +@mock.patch.object( + ErrorStatsServiceClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(ErrorStatsServiceClient), +) +@mock.patch.object( + ErrorStatsServiceAsyncClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(ErrorStatsServiceAsyncClient), +) +def test_error_stats_service_client_client_options( + client_class, transport_class, transport_name +): + # Check that if channel is provided we won't create a new one. + with mock.patch.object(ErrorStatsServiceClient, "get_transport_class") as gtc: + transport = transport_class(credentials=credentials.AnonymousCredentials()) + client = client_class(transport=transport) + gtc.assert_not_called() + + # Check that if channel is provided via str we will create a new one. + with mock.patch.object(ErrorStatsServiceClient, "get_transport_class") as gtc: + client = client_class(transport=transport_name) + gtc.assert_called() + + # Check the case api_endpoint is provided. + options = client_options.ClientOptions(api_endpoint="squid.clam.whelk") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + api_mtls_endpoint="squid.clam.whelk", + client_cert_source=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS is + # "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "never"}): + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class() + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + api_mtls_endpoint=client.DEFAULT_ENDPOINT, + client_cert_source=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS is + # "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "always"}): + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class() + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_MTLS_ENDPOINT, + scopes=None, + api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT, + client_cert_source=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + + # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is + # "auto", and client_cert_source is provided. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}): + options = client_options.ClientOptions( + client_cert_source=client_cert_source_callback + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_MTLS_ENDPOINT, + scopes=None, + api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT, + client_cert_source=client_cert_source_callback, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + + # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is + # "auto", and default_client_cert_source is provided. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, + ): + patched.return_value = None + client = client_class() + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_MTLS_ENDPOINT, + scopes=None, + api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT, + client_cert_source=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + + # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is + # "auto", but client_cert_source and default_client_cert_source are None. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, + ): + patched.return_value = None + client = client_class() + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + api_mtls_endpoint=client.DEFAULT_ENDPOINT, + client_cert_source=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "Unsupported"}): + with pytest.raises(MutualTLSChannelError): + client = client_class() + + # Check the case quota_project_id is provided + options = client_options.ClientOptions(quota_project_id="octopus") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + api_mtls_endpoint=client.DEFAULT_ENDPOINT, + client_cert_source=None, + quota_project_id="octopus", + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + (ErrorStatsServiceClient, transports.ErrorStatsServiceGrpcTransport, "grpc"), + ( + ErrorStatsServiceAsyncClient, + transports.ErrorStatsServiceGrpcAsyncIOTransport, + "grpc_asyncio", + ), + ], +) +def test_error_stats_service_client_client_options_scopes( + client_class, transport_class, transport_name +): + # Check the case scopes are provided. + options = client_options.ClientOptions(scopes=["1", "2"],) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=["1", "2"], + api_mtls_endpoint=client.DEFAULT_ENDPOINT, + client_cert_source=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + (ErrorStatsServiceClient, transports.ErrorStatsServiceGrpcTransport, "grpc"), + ( + ErrorStatsServiceAsyncClient, + transports.ErrorStatsServiceGrpcAsyncIOTransport, + "grpc_asyncio", + ), + ], +) +def test_error_stats_service_client_client_options_credentials_file( + client_class, transport_class, transport_name +): + # Check the case credentials file is provided. + options = client_options.ClientOptions(credentials_file="credentials.json") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file="credentials.json", + host=client.DEFAULT_ENDPOINT, + scopes=None, + api_mtls_endpoint=client.DEFAULT_ENDPOINT, + client_cert_source=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + + +def test_error_stats_service_client_client_options_from_dict(): + with mock.patch( + "google.cloud.errorreporting_v1beta1.services.error_stats_service.transports.ErrorStatsServiceGrpcTransport.__init__" + ) as grpc_transport: + grpc_transport.return_value = None + client = ErrorStatsServiceClient( + client_options={"api_endpoint": "squid.clam.whelk"} + ) + grpc_transport.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + api_mtls_endpoint="squid.clam.whelk", + client_cert_source=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + + +def test_list_group_stats( + transport: str = "grpc", request_type=error_stats_service.ListGroupStatsRequest +): + client = ErrorStatsServiceClient( + credentials=credentials.AnonymousCredentials(), transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client._transport.list_group_stats), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = error_stats_service.ListGroupStatsResponse( + next_page_token="next_page_token_value", + ) + + response = client.list_group_stats(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + + assert args[0] == error_stats_service.ListGroupStatsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListGroupStatsPager) + + assert response.next_page_token == "next_page_token_value" + + +def test_list_group_stats_from_dict(): + test_list_group_stats(request_type=dict) + + +@pytest.mark.asyncio +async def test_list_group_stats_async(transport: str = "grpc_asyncio"): + client = ErrorStatsServiceAsyncClient( + credentials=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 = error_stats_service.ListGroupStatsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client._client._transport.list_group_stats), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + error_stats_service.ListGroupStatsResponse( + next_page_token="next_page_token_value", + ) + ) + + response = await client.list_group_stats(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 response is the type that we expect. + assert isinstance(response, pagers.ListGroupStatsAsyncPager) + + assert response.next_page_token == "next_page_token_value" + + +def test_list_group_stats_field_headers(): + client = ErrorStatsServiceClient(credentials=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 = error_stats_service.ListGroupStatsRequest() + request.project_name = "project_name/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client._transport.list_group_stats), "__call__" + ) as call: + call.return_value = error_stats_service.ListGroupStatsResponse() + + client.list_group_stats(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", "project_name=project_name/value",) in kw[ + "metadata" + ] + + +@pytest.mark.asyncio +async def test_list_group_stats_field_headers_async(): + client = ErrorStatsServiceAsyncClient( + credentials=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 = error_stats_service.ListGroupStatsRequest() + request.project_name = "project_name/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client._client._transport.list_group_stats), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + error_stats_service.ListGroupStatsResponse() + ) + + await client.list_group_stats(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", "project_name=project_name/value",) in kw[ + "metadata" + ] + + +def test_list_group_stats_flattened(): + client = ErrorStatsServiceClient(credentials=credentials.AnonymousCredentials(),) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client._transport.list_group_stats), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = error_stats_service.ListGroupStatsResponse() + + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.list_group_stats( + project_name="project_name_value", + time_range=error_stats_service.QueryTimeRange( + period=error_stats_service.QueryTimeRange.Period.PERIOD_1_HOUR + ), + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + + assert args[0].project_name == "project_name_value" + + assert args[0].time_range == error_stats_service.QueryTimeRange( + period=error_stats_service.QueryTimeRange.Period.PERIOD_1_HOUR + ) + + +def test_list_group_stats_flattened_error(): + client = ErrorStatsServiceClient(credentials=credentials.AnonymousCredentials(),) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_group_stats( + error_stats_service.ListGroupStatsRequest(), + project_name="project_name_value", + time_range=error_stats_service.QueryTimeRange( + period=error_stats_service.QueryTimeRange.Period.PERIOD_1_HOUR + ), + ) + + +@pytest.mark.asyncio +async def test_list_group_stats_flattened_async(): + client = ErrorStatsServiceAsyncClient( + credentials=credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client._client._transport.list_group_stats), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = error_stats_service.ListGroupStatsResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + error_stats_service.ListGroupStatsResponse() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.list_group_stats( + project_name="project_name_value", + time_range=error_stats_service.QueryTimeRange( + period=error_stats_service.QueryTimeRange.Period.PERIOD_1_HOUR + ), + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + + assert args[0].project_name == "project_name_value" + + assert args[0].time_range == error_stats_service.QueryTimeRange( + period=error_stats_service.QueryTimeRange.Period.PERIOD_1_HOUR + ) + + +@pytest.mark.asyncio +async def test_list_group_stats_flattened_error_async(): + client = ErrorStatsServiceAsyncClient( + credentials=credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.list_group_stats( + error_stats_service.ListGroupStatsRequest(), + project_name="project_name_value", + time_range=error_stats_service.QueryTimeRange( + period=error_stats_service.QueryTimeRange.Period.PERIOD_1_HOUR + ), + ) + + +def test_list_group_stats_pager(): + client = ErrorStatsServiceClient(credentials=credentials.AnonymousCredentials,) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client._transport.list_group_stats), "__call__" + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + error_stats_service.ListGroupStatsResponse( + error_group_stats=[ + error_stats_service.ErrorGroupStats(), + error_stats_service.ErrorGroupStats(), + error_stats_service.ErrorGroupStats(), + ], + next_page_token="abc", + ), + error_stats_service.ListGroupStatsResponse( + error_group_stats=[], next_page_token="def", + ), + error_stats_service.ListGroupStatsResponse( + error_group_stats=[error_stats_service.ErrorGroupStats(),], + next_page_token="ghi", + ), + error_stats_service.ListGroupStatsResponse( + error_group_stats=[ + error_stats_service.ErrorGroupStats(), + error_stats_service.ErrorGroupStats(), + ], + ), + RuntimeError, + ) + + metadata = () + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("project_name", ""),)), + ) + pager = client.list_group_stats(request={}) + + assert pager._metadata == metadata + + results = [i for i in pager] + assert len(results) == 6 + assert all(isinstance(i, error_stats_service.ErrorGroupStats) for i in results) + + +def test_list_group_stats_pages(): + client = ErrorStatsServiceClient(credentials=credentials.AnonymousCredentials,) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client._transport.list_group_stats), "__call__" + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + error_stats_service.ListGroupStatsResponse( + error_group_stats=[ + error_stats_service.ErrorGroupStats(), + error_stats_service.ErrorGroupStats(), + error_stats_service.ErrorGroupStats(), + ], + next_page_token="abc", + ), + error_stats_service.ListGroupStatsResponse( + error_group_stats=[], next_page_token="def", + ), + error_stats_service.ListGroupStatsResponse( + error_group_stats=[error_stats_service.ErrorGroupStats(),], + next_page_token="ghi", + ), + error_stats_service.ListGroupStatsResponse( + error_group_stats=[ + error_stats_service.ErrorGroupStats(), + error_stats_service.ErrorGroupStats(), + ], + ), + RuntimeError, + ) + pages = list(client.list_group_stats(request={}).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +@pytest.mark.asyncio +async def test_list_group_stats_async_pager(): + client = ErrorStatsServiceAsyncClient(credentials=credentials.AnonymousCredentials,) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client._client._transport.list_group_stats), + "__call__", + new_callable=mock.AsyncMock, + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + error_stats_service.ListGroupStatsResponse( + error_group_stats=[ + error_stats_service.ErrorGroupStats(), + error_stats_service.ErrorGroupStats(), + error_stats_service.ErrorGroupStats(), + ], + next_page_token="abc", + ), + error_stats_service.ListGroupStatsResponse( + error_group_stats=[], next_page_token="def", + ), + error_stats_service.ListGroupStatsResponse( + error_group_stats=[error_stats_service.ErrorGroupStats(),], + next_page_token="ghi", + ), + error_stats_service.ListGroupStatsResponse( + error_group_stats=[ + error_stats_service.ErrorGroupStats(), + error_stats_service.ErrorGroupStats(), + ], + ), + RuntimeError, + ) + async_pager = await client.list_group_stats(request={},) + assert async_pager.next_page_token == "abc" + responses = [] + async for response in async_pager: + responses.append(response) + + assert len(responses) == 6 + assert all( + isinstance(i, error_stats_service.ErrorGroupStats) for i in responses + ) + + +@pytest.mark.asyncio +async def test_list_group_stats_async_pages(): + client = ErrorStatsServiceAsyncClient(credentials=credentials.AnonymousCredentials,) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client._client._transport.list_group_stats), + "__call__", + new_callable=mock.AsyncMock, + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + error_stats_service.ListGroupStatsResponse( + error_group_stats=[ + error_stats_service.ErrorGroupStats(), + error_stats_service.ErrorGroupStats(), + error_stats_service.ErrorGroupStats(), + ], + next_page_token="abc", + ), + error_stats_service.ListGroupStatsResponse( + error_group_stats=[], next_page_token="def", + ), + error_stats_service.ListGroupStatsResponse( + error_group_stats=[error_stats_service.ErrorGroupStats(),], + next_page_token="ghi", + ), + error_stats_service.ListGroupStatsResponse( + error_group_stats=[ + error_stats_service.ErrorGroupStats(), + error_stats_service.ErrorGroupStats(), + ], + ), + RuntimeError, + ) + pages = [] + async for page_ in (await client.list_group_stats(request={})).pages: + pages.append(page_) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +def test_list_events( + transport: str = "grpc", request_type=error_stats_service.ListEventsRequest +): + client = ErrorStatsServiceClient( + credentials=credentials.AnonymousCredentials(), transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client._transport.list_events), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = error_stats_service.ListEventsResponse( + next_page_token="next_page_token_value", + ) + + response = client.list_events(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + + assert args[0] == error_stats_service.ListEventsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListEventsPager) + + assert response.next_page_token == "next_page_token_value" + + +def test_list_events_from_dict(): + test_list_events(request_type=dict) + + +@pytest.mark.asyncio +async def test_list_events_async(transport: str = "grpc_asyncio"): + client = ErrorStatsServiceAsyncClient( + credentials=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 = error_stats_service.ListEventsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client._client._transport.list_events), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + error_stats_service.ListEventsResponse( + next_page_token="next_page_token_value", + ) + ) + + response = await client.list_events(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 response is the type that we expect. + assert isinstance(response, pagers.ListEventsAsyncPager) + + assert response.next_page_token == "next_page_token_value" + + +def test_list_events_field_headers(): + client = ErrorStatsServiceClient(credentials=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 = error_stats_service.ListEventsRequest() + request.project_name = "project_name/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client._transport.list_events), "__call__") as call: + call.return_value = error_stats_service.ListEventsResponse() + + client.list_events(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", "project_name=project_name/value",) in kw[ + "metadata" + ] + + +@pytest.mark.asyncio +async def test_list_events_field_headers_async(): + client = ErrorStatsServiceAsyncClient( + credentials=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 = error_stats_service.ListEventsRequest() + request.project_name = "project_name/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client._client._transport.list_events), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + error_stats_service.ListEventsResponse() + ) + + await client.list_events(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", "project_name=project_name/value",) in kw[ + "metadata" + ] + + +def test_list_events_flattened(): + client = ErrorStatsServiceClient(credentials=credentials.AnonymousCredentials(),) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client._transport.list_events), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = error_stats_service.ListEventsResponse() + + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.list_events( + project_name="project_name_value", group_id="group_id_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + + assert args[0].project_name == "project_name_value" + + assert args[0].group_id == "group_id_value" + + +def test_list_events_flattened_error(): + client = ErrorStatsServiceClient(credentials=credentials.AnonymousCredentials(),) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_events( + error_stats_service.ListEventsRequest(), + project_name="project_name_value", + group_id="group_id_value", + ) + + +@pytest.mark.asyncio +async def test_list_events_flattened_async(): + client = ErrorStatsServiceAsyncClient( + credentials=credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client._client._transport.list_events), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = error_stats_service.ListEventsResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + error_stats_service.ListEventsResponse() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.list_events( + project_name="project_name_value", group_id="group_id_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + + assert args[0].project_name == "project_name_value" + + assert args[0].group_id == "group_id_value" + + +@pytest.mark.asyncio +async def test_list_events_flattened_error_async(): + client = ErrorStatsServiceAsyncClient( + credentials=credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.list_events( + error_stats_service.ListEventsRequest(), + project_name="project_name_value", + group_id="group_id_value", + ) + + +def test_list_events_pager(): + client = ErrorStatsServiceClient(credentials=credentials.AnonymousCredentials,) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client._transport.list_events), "__call__") as call: + # Set the response to a series of pages. + call.side_effect = ( + error_stats_service.ListEventsResponse( + error_events=[ + common.ErrorEvent(), + common.ErrorEvent(), + common.ErrorEvent(), + ], + next_page_token="abc", + ), + error_stats_service.ListEventsResponse( + error_events=[], next_page_token="def", + ), + error_stats_service.ListEventsResponse( + error_events=[common.ErrorEvent(),], next_page_token="ghi", + ), + error_stats_service.ListEventsResponse( + error_events=[common.ErrorEvent(), common.ErrorEvent(),], + ), + RuntimeError, + ) + + metadata = () + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("project_name", ""),)), + ) + pager = client.list_events(request={}) + + assert pager._metadata == metadata + + results = [i for i in pager] + assert len(results) == 6 + assert all(isinstance(i, common.ErrorEvent) for i in results) + + +def test_list_events_pages(): + client = ErrorStatsServiceClient(credentials=credentials.AnonymousCredentials,) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client._transport.list_events), "__call__") as call: + # Set the response to a series of pages. + call.side_effect = ( + error_stats_service.ListEventsResponse( + error_events=[ + common.ErrorEvent(), + common.ErrorEvent(), + common.ErrorEvent(), + ], + next_page_token="abc", + ), + error_stats_service.ListEventsResponse( + error_events=[], next_page_token="def", + ), + error_stats_service.ListEventsResponse( + error_events=[common.ErrorEvent(),], next_page_token="ghi", + ), + error_stats_service.ListEventsResponse( + error_events=[common.ErrorEvent(), common.ErrorEvent(),], + ), + RuntimeError, + ) + pages = list(client.list_events(request={}).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +@pytest.mark.asyncio +async def test_list_events_async_pager(): + client = ErrorStatsServiceAsyncClient(credentials=credentials.AnonymousCredentials,) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client._client._transport.list_events), + "__call__", + new_callable=mock.AsyncMock, + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + error_stats_service.ListEventsResponse( + error_events=[ + common.ErrorEvent(), + common.ErrorEvent(), + common.ErrorEvent(), + ], + next_page_token="abc", + ), + error_stats_service.ListEventsResponse( + error_events=[], next_page_token="def", + ), + error_stats_service.ListEventsResponse( + error_events=[common.ErrorEvent(),], next_page_token="ghi", + ), + error_stats_service.ListEventsResponse( + error_events=[common.ErrorEvent(), common.ErrorEvent(),], + ), + RuntimeError, + ) + async_pager = await client.list_events(request={},) + assert async_pager.next_page_token == "abc" + responses = [] + async for response in async_pager: + responses.append(response) + + assert len(responses) == 6 + assert all(isinstance(i, common.ErrorEvent) for i in responses) + + +@pytest.mark.asyncio +async def test_list_events_async_pages(): + client = ErrorStatsServiceAsyncClient(credentials=credentials.AnonymousCredentials,) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client._client._transport.list_events), + "__call__", + new_callable=mock.AsyncMock, + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + error_stats_service.ListEventsResponse( + error_events=[ + common.ErrorEvent(), + common.ErrorEvent(), + common.ErrorEvent(), + ], + next_page_token="abc", + ), + error_stats_service.ListEventsResponse( + error_events=[], next_page_token="def", + ), + error_stats_service.ListEventsResponse( + error_events=[common.ErrorEvent(),], next_page_token="ghi", + ), + error_stats_service.ListEventsResponse( + error_events=[common.ErrorEvent(), common.ErrorEvent(),], + ), + RuntimeError, + ) + pages = [] + async for page_ in (await client.list_events(request={})).pages: + pages.append(page_) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +def test_delete_events( + transport: str = "grpc", request_type=error_stats_service.DeleteEventsRequest +): + client = ErrorStatsServiceClient( + credentials=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.delete_events), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = error_stats_service.DeleteEventsResponse() + + response = client.delete_events(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + + assert args[0] == error_stats_service.DeleteEventsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, error_stats_service.DeleteEventsResponse) + + +def test_delete_events_from_dict(): + test_delete_events(request_type=dict) + + +@pytest.mark.asyncio +async def test_delete_events_async(transport: str = "grpc_asyncio"): + client = ErrorStatsServiceAsyncClient( + credentials=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 = error_stats_service.DeleteEventsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client._client._transport.delete_events), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + error_stats_service.DeleteEventsResponse() + ) + + response = await client.delete_events(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 response is the type that we expect. + assert isinstance(response, error_stats_service.DeleteEventsResponse) + + +def test_delete_events_field_headers(): + client = ErrorStatsServiceClient(credentials=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 = error_stats_service.DeleteEventsRequest() + request.project_name = "project_name/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client._transport.delete_events), "__call__") as call: + call.return_value = error_stats_service.DeleteEventsResponse() + + client.delete_events(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", "project_name=project_name/value",) in kw[ + "metadata" + ] + + +@pytest.mark.asyncio +async def test_delete_events_field_headers_async(): + client = ErrorStatsServiceAsyncClient( + credentials=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 = error_stats_service.DeleteEventsRequest() + request.project_name = "project_name/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client._client._transport.delete_events), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + error_stats_service.DeleteEventsResponse() + ) + + await client.delete_events(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", "project_name=project_name/value",) in kw[ + "metadata" + ] + + +def test_delete_events_flattened(): + client = ErrorStatsServiceClient(credentials=credentials.AnonymousCredentials(),) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client._transport.delete_events), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = error_stats_service.DeleteEventsResponse() + + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.delete_events(project_name="project_name_value",) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + + assert args[0].project_name == "project_name_value" + + +def test_delete_events_flattened_error(): + client = ErrorStatsServiceClient(credentials=credentials.AnonymousCredentials(),) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.delete_events( + error_stats_service.DeleteEventsRequest(), + project_name="project_name_value", + ) + + +@pytest.mark.asyncio +async def test_delete_events_flattened_async(): + client = ErrorStatsServiceAsyncClient( + credentials=credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client._client._transport.delete_events), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = error_stats_service.DeleteEventsResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + error_stats_service.DeleteEventsResponse() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.delete_events(project_name="project_name_value",) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + + assert args[0].project_name == "project_name_value" + + +@pytest.mark.asyncio +async def test_delete_events_flattened_error_async(): + client = ErrorStatsServiceAsyncClient( + credentials=credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.delete_events( + error_stats_service.DeleteEventsRequest(), + project_name="project_name_value", + ) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.ErrorStatsServiceGrpcTransport( + credentials=credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ErrorStatsServiceClient( + credentials=credentials.AnonymousCredentials(), transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.ErrorStatsServiceGrpcTransport( + credentials=credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ErrorStatsServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.ErrorStatsServiceGrpcTransport( + credentials=credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ErrorStatsServiceClient( + client_options={"scopes": ["1", "2"]}, transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.ErrorStatsServiceGrpcTransport( + credentials=credentials.AnonymousCredentials(), + ) + client = ErrorStatsServiceClient(transport=transport) + assert client._transport is transport + + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.ErrorStatsServiceGrpcTransport( + credentials=credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.ErrorStatsServiceGrpcAsyncIOTransport( + credentials=credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + +def test_transport_grpc_default(): + # A client should use the gRPC transport by default. + client = ErrorStatsServiceClient(credentials=credentials.AnonymousCredentials(),) + assert isinstance(client._transport, transports.ErrorStatsServiceGrpcTransport,) + + +def test_error_stats_service_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(exceptions.DuplicateCredentialArgs): + transport = transports.ErrorStatsServiceTransport( + credentials=credentials.AnonymousCredentials(), + credentials_file="credentials.json", + ) + + +def test_error_stats_service_base_transport(): + # Instantiate the base transport. + with mock.patch( + "google.cloud.errorreporting_v1beta1.services.error_stats_service.transports.ErrorStatsServiceTransport.__init__" + ) as Transport: + Transport.return_value = None + transport = transports.ErrorStatsServiceTransport( + credentials=credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + "list_group_stats", + "list_events", + "delete_events", + ) + for method in methods: + with pytest.raises(NotImplementedError): + getattr(transport, method)(request=object()) + + +def test_error_stats_service_base_transport_with_credentials_file(): + # Instantiate the base transport with a credentials file + with mock.patch.object( + auth, "load_credentials_from_file" + ) as load_creds, mock.patch( + "google.cloud.errorreporting_v1beta1.services.error_stats_service.transports.ErrorStatsServiceTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + load_creds.return_value = (credentials.AnonymousCredentials(), None) + transport = transports.ErrorStatsServiceTransport( + credentials_file="credentials.json", quota_project_id="octopus", + ) + load_creds.assert_called_once_with( + "credentials.json", + scopes=("https://www.googleapis.com/auth/cloud-platform",), + quota_project_id="octopus", + ) + + +def test_error_stats_service_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) + ErrorStatsServiceClient() + adc.assert_called_once_with( + scopes=("https://www.googleapis.com/auth/cloud-platform",), + quota_project_id=None, + ) + + +def test_error_stats_service_transport_auth_adc(): + # 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.ErrorStatsServiceGrpcTransport( + host="squid.clam.whelk", quota_project_id="octopus" + ) + adc.assert_called_once_with( + scopes=("https://www.googleapis.com/auth/cloud-platform",), + quota_project_id="octopus", + ) + + +def test_error_stats_service_host_no_port(): + client = ErrorStatsServiceClient( + credentials=credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions( + api_endpoint="clouderrorreporting.googleapis.com" + ), + ) + assert client._transport._host == "clouderrorreporting.googleapis.com:443" + + +def test_error_stats_service_host_with_port(): + client = ErrorStatsServiceClient( + credentials=credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions( + api_endpoint="clouderrorreporting.googleapis.com:8000" + ), + ) + assert client._transport._host == "clouderrorreporting.googleapis.com:8000" + + +def test_error_stats_service_grpc_transport_channel(): + channel = grpc.insecure_channel("http://localhost/") + + # Check that if channel is provided, mtls endpoint and client_cert_source + # won't be used. + callback = mock.MagicMock() + transport = transports.ErrorStatsServiceGrpcTransport( + host="squid.clam.whelk", + channel=channel, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=callback, + ) + assert transport.grpc_channel == channel + assert transport._host == "squid.clam.whelk:443" + assert not callback.called + + +def test_error_stats_service_grpc_asyncio_transport_channel(): + channel = aio.insecure_channel("http://localhost/") + + # Check that if channel is provided, mtls endpoint and client_cert_source + # won't be used. + callback = mock.MagicMock() + transport = transports.ErrorStatsServiceGrpcAsyncIOTransport( + host="squid.clam.whelk", + channel=channel, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=callback, + ) + assert transport.grpc_channel == channel + assert transport._host == "squid.clam.whelk:443" + assert not callback.called + + +@mock.patch("grpc.ssl_channel_credentials", autospec=True) +@mock.patch("google.api_core.grpc_helpers.create_channel", autospec=True) +def test_error_stats_service_grpc_transport_channel_mtls_with_client_cert_source( + grpc_create_channel, grpc_ssl_channel_cred +): + # Check that if channel is None, but api_mtls_endpoint and client_cert_source + # are provided, then a mTLS channel will be created. + mock_cred = mock.Mock() + + mock_ssl_cred = mock.Mock() + grpc_ssl_channel_cred.return_value = mock_ssl_cred + + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + transport = transports.ErrorStatsServiceGrpcTransport( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=client_cert_source_callback, + ) + grpc_ssl_channel_cred.assert_called_once_with( + certificate_chain=b"cert bytes", private_key=b"key bytes" + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + credentials_file=None, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + ) + assert transport.grpc_channel == mock_grpc_channel + + +@mock.patch("grpc.ssl_channel_credentials", autospec=True) +@mock.patch("google.api_core.grpc_helpers_async.create_channel", autospec=True) +def test_error_stats_service_grpc_asyncio_transport_channel_mtls_with_client_cert_source( + grpc_create_channel, grpc_ssl_channel_cred +): + # Check that if channel is None, but api_mtls_endpoint and client_cert_source + # are provided, then a mTLS channel will be created. + mock_cred = mock.Mock() + + mock_ssl_cred = mock.Mock() + grpc_ssl_channel_cred.return_value = mock_ssl_cred + + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + transport = transports.ErrorStatsServiceGrpcAsyncIOTransport( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=client_cert_source_callback, + ) + grpc_ssl_channel_cred.assert_called_once_with( + certificate_chain=b"cert bytes", private_key=b"key bytes" + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + credentials_file=None, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + ) + assert transport.grpc_channel == mock_grpc_channel + + +@pytest.mark.parametrize( + "api_mtls_endpoint", ["mtls.squid.clam.whelk", "mtls.squid.clam.whelk:443"] +) +@mock.patch("google.api_core.grpc_helpers.create_channel", autospec=True) +def test_error_stats_service_grpc_transport_channel_mtls_with_adc( + grpc_create_channel, api_mtls_endpoint +): + # Check that if channel and client_cert_source are None, but api_mtls_endpoint + # is provided, then a mTLS channel will be created with SSL ADC. + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + # Mock google.auth.transport.grpc.SslCredentials class. + mock_ssl_cred = mock.Mock() + with mock.patch.multiple( + "google.auth.transport.grpc.SslCredentials", + __init__=mock.Mock(return_value=None), + ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), + ): + mock_cred = mock.Mock() + transport = transports.ErrorStatsServiceGrpcTransport( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint=api_mtls_endpoint, + client_cert_source=None, + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + credentials_file=None, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + ) + assert transport.grpc_channel == mock_grpc_channel + + +@pytest.mark.parametrize( + "api_mtls_endpoint", ["mtls.squid.clam.whelk", "mtls.squid.clam.whelk:443"] +) +@mock.patch("google.api_core.grpc_helpers_async.create_channel", autospec=True) +def test_error_stats_service_grpc_asyncio_transport_channel_mtls_with_adc( + grpc_create_channel, api_mtls_endpoint +): + # Check that if channel and client_cert_source are None, but api_mtls_endpoint + # is provided, then a mTLS channel will be created with SSL ADC. + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + # Mock google.auth.transport.grpc.SslCredentials class. + mock_ssl_cred = mock.Mock() + with mock.patch.multiple( + "google.auth.transport.grpc.SslCredentials", + __init__=mock.Mock(return_value=None), + ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), + ): + mock_cred = mock.Mock() + transport = transports.ErrorStatsServiceGrpcAsyncIOTransport( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint=api_mtls_endpoint, + client_cert_source=None, + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + credentials_file=None, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + ) + assert transport.grpc_channel == mock_grpc_channel + + +def test_client_withDEFAULT_CLIENT_INFO(): + client_info = gapic_v1.client_info.ClientInfo() + + with mock.patch.object( + transports.ErrorStatsServiceTransport, "_prep_wrapped_messages" + ) as prep: + client = ErrorStatsServiceClient( + credentials=credentials.AnonymousCredentials(), client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object( + transports.ErrorStatsServiceTransport, "_prep_wrapped_messages" + ) as prep: + transport_class = ErrorStatsServiceClient.get_transport_class() + transport = transport_class( + credentials=credentials.AnonymousCredentials(), client_info=client_info, + ) + prep.assert_called_once_with(client_info) diff --git a/tests/unit/gapic/errorreporting_v1beta1/test_report_errors_service.py b/tests/unit/gapic/errorreporting_v1beta1/test_report_errors_service.py new file mode 100644 index 00000000..c3778272 --- /dev/null +++ b/tests/unit/gapic/errorreporting_v1beta1/test_report_errors_service.py @@ -0,0 +1,959 @@ +# -*- 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. +# + +import os +import mock + +import grpc +from grpc.experimental import aio +import math +import pytest +from proto.marshal.rules.dates import DurationRule, TimestampRule + +from google import auth +from google.api_core import client_options +from google.api_core import 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.exceptions import MutualTLSChannelError +from google.cloud.errorreporting_v1beta1.services.report_errors_service import ( + ReportErrorsServiceAsyncClient, +) +from google.cloud.errorreporting_v1beta1.services.report_errors_service import ( + ReportErrorsServiceClient, +) +from google.cloud.errorreporting_v1beta1.services.report_errors_service import ( + transports, +) +from google.cloud.errorreporting_v1beta1.types import common +from google.cloud.errorreporting_v1beta1.types import report_errors_service +from google.oauth2 import service_account +from google.protobuf import timestamp_pb2 as timestamp # type: ignore + + +def client_cert_source_callback(): + return b"cert bytes", b"key bytes" + + +# If default endpoint is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint(client): + return ( + "foo.googleapis.com" + if ("localhost" in client.DEFAULT_ENDPOINT) + else client.DEFAULT_ENDPOINT + ) + + +def test__get_default_mtls_endpoint(): + api_endpoint = "example.googleapis.com" + api_mtls_endpoint = "example.mtls.googleapis.com" + sandbox_endpoint = "example.sandbox.googleapis.com" + sandbox_mtls_endpoint = "example.mtls.sandbox.googleapis.com" + non_googleapi = "api.example.com" + + assert ReportErrorsServiceClient._get_default_mtls_endpoint(None) is None + assert ( + ReportErrorsServiceClient._get_default_mtls_endpoint(api_endpoint) + == api_mtls_endpoint + ) + assert ( + ReportErrorsServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) + == api_mtls_endpoint + ) + assert ( + ReportErrorsServiceClient._get_default_mtls_endpoint(sandbox_endpoint) + == sandbox_mtls_endpoint + ) + assert ( + ReportErrorsServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) + == sandbox_mtls_endpoint + ) + assert ( + ReportErrorsServiceClient._get_default_mtls_endpoint(non_googleapi) + == non_googleapi + ) + + +@pytest.mark.parametrize( + "client_class", [ReportErrorsServiceClient, ReportErrorsServiceAsyncClient] +) +def test_report_errors_service_client_from_service_account_file(client_class): + creds = credentials.AnonymousCredentials() + with mock.patch.object( + service_account.Credentials, "from_service_account_file" + ) as factory: + factory.return_value = creds + client = client_class.from_service_account_file("dummy/file/path.json") + assert client._transport._credentials == creds + + client = client_class.from_service_account_json("dummy/file/path.json") + assert client._transport._credentials == creds + + assert client._transport._host == "clouderrorreporting.googleapis.com:443" + + +def test_report_errors_service_client_get_transport_class(): + transport = ReportErrorsServiceClient.get_transport_class() + assert transport == transports.ReportErrorsServiceGrpcTransport + + transport = ReportErrorsServiceClient.get_transport_class("grpc") + assert transport == transports.ReportErrorsServiceGrpcTransport + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + ( + ReportErrorsServiceClient, + transports.ReportErrorsServiceGrpcTransport, + "grpc", + ), + ( + ReportErrorsServiceAsyncClient, + transports.ReportErrorsServiceGrpcAsyncIOTransport, + "grpc_asyncio", + ), + ], +) +@mock.patch.object( + ReportErrorsServiceClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(ReportErrorsServiceClient), +) +@mock.patch.object( + ReportErrorsServiceAsyncClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(ReportErrorsServiceAsyncClient), +) +def test_report_errors_service_client_client_options( + client_class, transport_class, transport_name +): + # Check that if channel is provided we won't create a new one. + with mock.patch.object(ReportErrorsServiceClient, "get_transport_class") as gtc: + transport = transport_class(credentials=credentials.AnonymousCredentials()) + client = client_class(transport=transport) + gtc.assert_not_called() + + # Check that if channel is provided via str we will create a new one. + with mock.patch.object(ReportErrorsServiceClient, "get_transport_class") as gtc: + client = client_class(transport=transport_name) + gtc.assert_called() + + # Check the case api_endpoint is provided. + options = client_options.ClientOptions(api_endpoint="squid.clam.whelk") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + api_mtls_endpoint="squid.clam.whelk", + client_cert_source=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS is + # "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "never"}): + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class() + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + api_mtls_endpoint=client.DEFAULT_ENDPOINT, + client_cert_source=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS is + # "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "always"}): + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class() + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_MTLS_ENDPOINT, + scopes=None, + api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT, + client_cert_source=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + + # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is + # "auto", and client_cert_source is provided. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}): + options = client_options.ClientOptions( + client_cert_source=client_cert_source_callback + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_MTLS_ENDPOINT, + scopes=None, + api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT, + client_cert_source=client_cert_source_callback, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + + # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is + # "auto", and default_client_cert_source is provided. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, + ): + patched.return_value = None + client = client_class() + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_MTLS_ENDPOINT, + scopes=None, + api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT, + client_cert_source=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + + # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is + # "auto", but client_cert_source and default_client_cert_source are None. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, + ): + patched.return_value = None + client = client_class() + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + api_mtls_endpoint=client.DEFAULT_ENDPOINT, + client_cert_source=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "Unsupported"}): + with pytest.raises(MutualTLSChannelError): + client = client_class() + + # Check the case quota_project_id is provided + options = client_options.ClientOptions(quota_project_id="octopus") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + api_mtls_endpoint=client.DEFAULT_ENDPOINT, + client_cert_source=None, + quota_project_id="octopus", + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + ( + ReportErrorsServiceClient, + transports.ReportErrorsServiceGrpcTransport, + "grpc", + ), + ( + ReportErrorsServiceAsyncClient, + transports.ReportErrorsServiceGrpcAsyncIOTransport, + "grpc_asyncio", + ), + ], +) +def test_report_errors_service_client_client_options_scopes( + client_class, transport_class, transport_name +): + # Check the case scopes are provided. + options = client_options.ClientOptions(scopes=["1", "2"],) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=["1", "2"], + api_mtls_endpoint=client.DEFAULT_ENDPOINT, + client_cert_source=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + ( + ReportErrorsServiceClient, + transports.ReportErrorsServiceGrpcTransport, + "grpc", + ), + ( + ReportErrorsServiceAsyncClient, + transports.ReportErrorsServiceGrpcAsyncIOTransport, + "grpc_asyncio", + ), + ], +) +def test_report_errors_service_client_client_options_credentials_file( + client_class, transport_class, transport_name +): + # Check the case credentials file is provided. + options = client_options.ClientOptions(credentials_file="credentials.json") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file="credentials.json", + host=client.DEFAULT_ENDPOINT, + scopes=None, + api_mtls_endpoint=client.DEFAULT_ENDPOINT, + client_cert_source=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + + +def test_report_errors_service_client_client_options_from_dict(): + with mock.patch( + "google.cloud.errorreporting_v1beta1.services.report_errors_service.transports.ReportErrorsServiceGrpcTransport.__init__" + ) as grpc_transport: + grpc_transport.return_value = None + client = ReportErrorsServiceClient( + client_options={"api_endpoint": "squid.clam.whelk"} + ) + grpc_transport.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + api_mtls_endpoint="squid.clam.whelk", + client_cert_source=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + + +def test_report_error_event( + transport: str = "grpc", request_type=report_errors_service.ReportErrorEventRequest +): + client = ReportErrorsServiceClient( + credentials=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.report_error_event), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = report_errors_service.ReportErrorEventResponse() + + response = client.report_error_event(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + + assert args[0] == report_errors_service.ReportErrorEventRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, report_errors_service.ReportErrorEventResponse) + + +def test_report_error_event_from_dict(): + test_report_error_event(request_type=dict) + + +@pytest.mark.asyncio +async def test_report_error_event_async(transport: str = "grpc_asyncio"): + client = ReportErrorsServiceAsyncClient( + credentials=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 = report_errors_service.ReportErrorEventRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client._client._transport.report_error_event), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + report_errors_service.ReportErrorEventResponse() + ) + + response = await client.report_error_event(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 response is the type that we expect. + assert isinstance(response, report_errors_service.ReportErrorEventResponse) + + +def test_report_error_event_field_headers(): + client = ReportErrorsServiceClient(credentials=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 = report_errors_service.ReportErrorEventRequest() + request.project_name = "project_name/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client._transport.report_error_event), "__call__" + ) as call: + call.return_value = report_errors_service.ReportErrorEventResponse() + + client.report_error_event(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", "project_name=project_name/value",) in kw[ + "metadata" + ] + + +@pytest.mark.asyncio +async def test_report_error_event_field_headers_async(): + client = ReportErrorsServiceAsyncClient( + credentials=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 = report_errors_service.ReportErrorEventRequest() + request.project_name = "project_name/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client._client._transport.report_error_event), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + report_errors_service.ReportErrorEventResponse() + ) + + await client.report_error_event(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", "project_name=project_name/value",) in kw[ + "metadata" + ] + + +def test_report_error_event_flattened(): + client = ReportErrorsServiceClient(credentials=credentials.AnonymousCredentials(),) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client._transport.report_error_event), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = report_errors_service.ReportErrorEventResponse() + + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.report_error_event( + project_name="project_name_value", + event=report_errors_service.ReportedErrorEvent( + event_time=timestamp.Timestamp(seconds=751) + ), + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + + assert args[0].project_name == "project_name_value" + + assert args[0].event == report_errors_service.ReportedErrorEvent( + event_time=timestamp.Timestamp(seconds=751) + ) + + +def test_report_error_event_flattened_error(): + client = ReportErrorsServiceClient(credentials=credentials.AnonymousCredentials(),) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.report_error_event( + report_errors_service.ReportErrorEventRequest(), + project_name="project_name_value", + event=report_errors_service.ReportedErrorEvent( + event_time=timestamp.Timestamp(seconds=751) + ), + ) + + +@pytest.mark.asyncio +async def test_report_error_event_flattened_async(): + client = ReportErrorsServiceAsyncClient( + credentials=credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client._client._transport.report_error_event), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = report_errors_service.ReportErrorEventResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + report_errors_service.ReportErrorEventResponse() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.report_error_event( + project_name="project_name_value", + event=report_errors_service.ReportedErrorEvent( + event_time=timestamp.Timestamp(seconds=751) + ), + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + + assert args[0].project_name == "project_name_value" + + assert args[0].event == report_errors_service.ReportedErrorEvent( + event_time=timestamp.Timestamp(seconds=751) + ) + + +@pytest.mark.asyncio +async def test_report_error_event_flattened_error_async(): + client = ReportErrorsServiceAsyncClient( + credentials=credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.report_error_event( + report_errors_service.ReportErrorEventRequest(), + project_name="project_name_value", + event=report_errors_service.ReportedErrorEvent( + event_time=timestamp.Timestamp(seconds=751) + ), + ) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.ReportErrorsServiceGrpcTransport( + credentials=credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ReportErrorsServiceClient( + credentials=credentials.AnonymousCredentials(), transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.ReportErrorsServiceGrpcTransport( + credentials=credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ReportErrorsServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.ReportErrorsServiceGrpcTransport( + credentials=credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ReportErrorsServiceClient( + client_options={"scopes": ["1", "2"]}, transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.ReportErrorsServiceGrpcTransport( + credentials=credentials.AnonymousCredentials(), + ) + client = ReportErrorsServiceClient(transport=transport) + assert client._transport is transport + + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.ReportErrorsServiceGrpcTransport( + credentials=credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.ReportErrorsServiceGrpcAsyncIOTransport( + credentials=credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + +def test_transport_grpc_default(): + # A client should use the gRPC transport by default. + client = ReportErrorsServiceClient(credentials=credentials.AnonymousCredentials(),) + assert isinstance(client._transport, transports.ReportErrorsServiceGrpcTransport,) + + +def test_report_errors_service_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(exceptions.DuplicateCredentialArgs): + transport = transports.ReportErrorsServiceTransport( + credentials=credentials.AnonymousCredentials(), + credentials_file="credentials.json", + ) + + +def test_report_errors_service_base_transport(): + # Instantiate the base transport. + with mock.patch( + "google.cloud.errorreporting_v1beta1.services.report_errors_service.transports.ReportErrorsServiceTransport.__init__" + ) as Transport: + Transport.return_value = None + transport = transports.ReportErrorsServiceTransport( + credentials=credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ("report_error_event",) + for method in methods: + with pytest.raises(NotImplementedError): + getattr(transport, method)(request=object()) + + +def test_report_errors_service_base_transport_with_credentials_file(): + # Instantiate the base transport with a credentials file + with mock.patch.object( + auth, "load_credentials_from_file" + ) as load_creds, mock.patch( + "google.cloud.errorreporting_v1beta1.services.report_errors_service.transports.ReportErrorsServiceTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + load_creds.return_value = (credentials.AnonymousCredentials(), None) + transport = transports.ReportErrorsServiceTransport( + credentials_file="credentials.json", quota_project_id="octopus", + ) + load_creds.assert_called_once_with( + "credentials.json", + scopes=("https://www.googleapis.com/auth/cloud-platform",), + quota_project_id="octopus", + ) + + +def test_report_errors_service_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) + ReportErrorsServiceClient() + adc.assert_called_once_with( + scopes=("https://www.googleapis.com/auth/cloud-platform",), + quota_project_id=None, + ) + + +def test_report_errors_service_transport_auth_adc(): + # 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.ReportErrorsServiceGrpcTransport( + host="squid.clam.whelk", quota_project_id="octopus" + ) + adc.assert_called_once_with( + scopes=("https://www.googleapis.com/auth/cloud-platform",), + quota_project_id="octopus", + ) + + +def test_report_errors_service_host_no_port(): + client = ReportErrorsServiceClient( + credentials=credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions( + api_endpoint="clouderrorreporting.googleapis.com" + ), + ) + assert client._transport._host == "clouderrorreporting.googleapis.com:443" + + +def test_report_errors_service_host_with_port(): + client = ReportErrorsServiceClient( + credentials=credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions( + api_endpoint="clouderrorreporting.googleapis.com:8000" + ), + ) + assert client._transport._host == "clouderrorreporting.googleapis.com:8000" + + +def test_report_errors_service_grpc_transport_channel(): + channel = grpc.insecure_channel("http://localhost/") + + # Check that if channel is provided, mtls endpoint and client_cert_source + # won't be used. + callback = mock.MagicMock() + transport = transports.ReportErrorsServiceGrpcTransport( + host="squid.clam.whelk", + channel=channel, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=callback, + ) + assert transport.grpc_channel == channel + assert transport._host == "squid.clam.whelk:443" + assert not callback.called + + +def test_report_errors_service_grpc_asyncio_transport_channel(): + channel = aio.insecure_channel("http://localhost/") + + # Check that if channel is provided, mtls endpoint and client_cert_source + # won't be used. + callback = mock.MagicMock() + transport = transports.ReportErrorsServiceGrpcAsyncIOTransport( + host="squid.clam.whelk", + channel=channel, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=callback, + ) + assert transport.grpc_channel == channel + assert transport._host == "squid.clam.whelk:443" + assert not callback.called + + +@mock.patch("grpc.ssl_channel_credentials", autospec=True) +@mock.patch("google.api_core.grpc_helpers.create_channel", autospec=True) +def test_report_errors_service_grpc_transport_channel_mtls_with_client_cert_source( + grpc_create_channel, grpc_ssl_channel_cred +): + # Check that if channel is None, but api_mtls_endpoint and client_cert_source + # are provided, then a mTLS channel will be created. + mock_cred = mock.Mock() + + mock_ssl_cred = mock.Mock() + grpc_ssl_channel_cred.return_value = mock_ssl_cred + + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + transport = transports.ReportErrorsServiceGrpcTransport( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=client_cert_source_callback, + ) + grpc_ssl_channel_cred.assert_called_once_with( + certificate_chain=b"cert bytes", private_key=b"key bytes" + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + credentials_file=None, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + ) + assert transport.grpc_channel == mock_grpc_channel + + +@mock.patch("grpc.ssl_channel_credentials", autospec=True) +@mock.patch("google.api_core.grpc_helpers_async.create_channel", autospec=True) +def test_report_errors_service_grpc_asyncio_transport_channel_mtls_with_client_cert_source( + grpc_create_channel, grpc_ssl_channel_cred +): + # Check that if channel is None, but api_mtls_endpoint and client_cert_source + # are provided, then a mTLS channel will be created. + mock_cred = mock.Mock() + + mock_ssl_cred = mock.Mock() + grpc_ssl_channel_cred.return_value = mock_ssl_cred + + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + transport = transports.ReportErrorsServiceGrpcAsyncIOTransport( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=client_cert_source_callback, + ) + grpc_ssl_channel_cred.assert_called_once_with( + certificate_chain=b"cert bytes", private_key=b"key bytes" + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + credentials_file=None, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + ) + assert transport.grpc_channel == mock_grpc_channel + + +@pytest.mark.parametrize( + "api_mtls_endpoint", ["mtls.squid.clam.whelk", "mtls.squid.clam.whelk:443"] +) +@mock.patch("google.api_core.grpc_helpers.create_channel", autospec=True) +def test_report_errors_service_grpc_transport_channel_mtls_with_adc( + grpc_create_channel, api_mtls_endpoint +): + # Check that if channel and client_cert_source are None, but api_mtls_endpoint + # is provided, then a mTLS channel will be created with SSL ADC. + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + # Mock google.auth.transport.grpc.SslCredentials class. + mock_ssl_cred = mock.Mock() + with mock.patch.multiple( + "google.auth.transport.grpc.SslCredentials", + __init__=mock.Mock(return_value=None), + ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), + ): + mock_cred = mock.Mock() + transport = transports.ReportErrorsServiceGrpcTransport( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint=api_mtls_endpoint, + client_cert_source=None, + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + credentials_file=None, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + ) + assert transport.grpc_channel == mock_grpc_channel + + +@pytest.mark.parametrize( + "api_mtls_endpoint", ["mtls.squid.clam.whelk", "mtls.squid.clam.whelk:443"] +) +@mock.patch("google.api_core.grpc_helpers_async.create_channel", autospec=True) +def test_report_errors_service_grpc_asyncio_transport_channel_mtls_with_adc( + grpc_create_channel, api_mtls_endpoint +): + # Check that if channel and client_cert_source are None, but api_mtls_endpoint + # is provided, then a mTLS channel will be created with SSL ADC. + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + # Mock google.auth.transport.grpc.SslCredentials class. + mock_ssl_cred = mock.Mock() + with mock.patch.multiple( + "google.auth.transport.grpc.SslCredentials", + __init__=mock.Mock(return_value=None), + ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), + ): + mock_cred = mock.Mock() + transport = transports.ReportErrorsServiceGrpcAsyncIOTransport( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint=api_mtls_endpoint, + client_cert_source=None, + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + credentials_file=None, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + ) + assert transport.grpc_channel == mock_grpc_channel + + +def test_client_withDEFAULT_CLIENT_INFO(): + client_info = gapic_v1.client_info.ClientInfo() + + with mock.patch.object( + transports.ReportErrorsServiceTransport, "_prep_wrapped_messages" + ) as prep: + client = ReportErrorsServiceClient( + credentials=credentials.AnonymousCredentials(), client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object( + transports.ReportErrorsServiceTransport, "_prep_wrapped_messages" + ) as prep: + transport_class = ReportErrorsServiceClient.get_transport_class() + transport = transport_class( + credentials=credentials.AnonymousCredentials(), client_info=client_info, + ) + prep.assert_called_once_with(client_info) diff --git a/tests/unit/gapic/v1beta1/test_error_group_service_client_v1beta1.py b/tests/unit/gapic/v1beta1/test_error_group_service_client_v1beta1.py deleted file mode 100644 index d65f3f1f..00000000 --- a/tests/unit/gapic/v1beta1/test_error_group_service_client_v1beta1.py +++ /dev/null @@ -1,142 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright 2019 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 -# -# https://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. - -"""Unit tests.""" - -import mock -import pytest - -from google.cloud import errorreporting_v1beta1 -from google.cloud.errorreporting_v1beta1.proto import common_pb2 -from google.cloud.errorreporting_v1beta1.proto import error_group_service_pb2 - - -class MultiCallableStub(object): - """Stub for the grpc.UnaryUnaryMultiCallable interface.""" - - def __init__(self, method, channel_stub): - self.method = method - self.channel_stub = channel_stub - - def __call__(self, request, timeout=None, metadata=None, credentials=None): - self.channel_stub.requests.append((self.method, request)) - - response = None - if self.channel_stub.responses: - response = self.channel_stub.responses.pop() - - if isinstance(response, Exception): - raise response - - if response: - return response - - -class ChannelStub(object): - """Stub for the grpc.Channel interface.""" - - def __init__(self, responses=[]): - self.responses = responses - self.requests = [] - - def unary_unary(self, method, request_serializer=None, response_deserializer=None): - return MultiCallableStub(method, self) - - -class CustomException(Exception): - pass - - -class TestErrorGroupServiceClient(object): - def test_get_group(self): - # Setup Expected Response - name = "name3373707" - group_id = "groupId506361563" - expected_response = {"name": name, "group_id": group_id} - expected_response = common_pb2.ErrorGroup(**expected_response) - - # Mock the API response - channel = ChannelStub(responses=[expected_response]) - patch = mock.patch("google.api_core.grpc_helpers.create_channel") - with patch as create_channel: - create_channel.return_value = channel - client = errorreporting_v1beta1.ErrorGroupServiceClient() - - # Setup Request - group_name = client.group_path("[PROJECT]", "[GROUP]") - - response = client.get_group(group_name) - assert expected_response == response - - assert len(channel.requests) == 1 - expected_request = error_group_service_pb2.GetGroupRequest( - group_name=group_name - ) - actual_request = channel.requests[0][1] - assert expected_request == actual_request - - def test_get_group_exception(self): - # Mock the API response - channel = ChannelStub(responses=[CustomException()]) - patch = mock.patch("google.api_core.grpc_helpers.create_channel") - with patch as create_channel: - create_channel.return_value = channel - client = errorreporting_v1beta1.ErrorGroupServiceClient() - - # Setup request - group_name = client.group_path("[PROJECT]", "[GROUP]") - - with pytest.raises(CustomException): - client.get_group(group_name) - - def test_update_group(self): - # Setup Expected Response - name = "name3373707" - group_id = "groupId506361563" - expected_response = {"name": name, "group_id": group_id} - expected_response = common_pb2.ErrorGroup(**expected_response) - - # Mock the API response - channel = ChannelStub(responses=[expected_response]) - patch = mock.patch("google.api_core.grpc_helpers.create_channel") - with patch as create_channel: - create_channel.return_value = channel - client = errorreporting_v1beta1.ErrorGroupServiceClient() - - # Setup Request - group = {} - - response = client.update_group(group) - assert expected_response == response - - assert len(channel.requests) == 1 - expected_request = error_group_service_pb2.UpdateGroupRequest(group=group) - actual_request = channel.requests[0][1] - assert expected_request == actual_request - - def test_update_group_exception(self): - # Mock the API response - channel = ChannelStub(responses=[CustomException()]) - patch = mock.patch("google.api_core.grpc_helpers.create_channel") - with patch as create_channel: - create_channel.return_value = channel - client = errorreporting_v1beta1.ErrorGroupServiceClient() - - # Setup request - group = {} - - with pytest.raises(CustomException): - client.update_group(group) diff --git a/tests/unit/gapic/v1beta1/test_error_stats_service_client_v1beta1.py b/tests/unit/gapic/v1beta1/test_error_stats_service_client_v1beta1.py deleted file mode 100644 index dc09b13f..00000000 --- a/tests/unit/gapic/v1beta1/test_error_stats_service_client_v1beta1.py +++ /dev/null @@ -1,207 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright 2019 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 -# -# https://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. - -"""Unit tests.""" - -import mock -import pytest - -from google.cloud import errorreporting_v1beta1 -from google.cloud.errorreporting_v1beta1.proto import common_pb2 -from google.cloud.errorreporting_v1beta1.proto import error_stats_service_pb2 - - -class MultiCallableStub(object): - """Stub for the grpc.UnaryUnaryMultiCallable interface.""" - - def __init__(self, method, channel_stub): - self.method = method - self.channel_stub = channel_stub - - def __call__(self, request, timeout=None, metadata=None, credentials=None): - self.channel_stub.requests.append((self.method, request)) - - response = None - if self.channel_stub.responses: - response = self.channel_stub.responses.pop() - - if isinstance(response, Exception): - raise response - - if response: - return response - - -class ChannelStub(object): - """Stub for the grpc.Channel interface.""" - - def __init__(self, responses=[]): - self.responses = responses - self.requests = [] - - def unary_unary(self, method, request_serializer=None, response_deserializer=None): - return MultiCallableStub(method, self) - - -class CustomException(Exception): - pass - - -class TestErrorStatsServiceClient(object): - def test_list_group_stats(self): - # Setup Expected Response - next_page_token = "" - error_group_stats_element = {} - error_group_stats = [error_group_stats_element] - expected_response = { - "next_page_token": next_page_token, - "error_group_stats": error_group_stats, - } - expected_response = error_stats_service_pb2.ListGroupStatsResponse( - **expected_response - ) - - # Mock the API response - channel = ChannelStub(responses=[expected_response]) - patch = mock.patch("google.api_core.grpc_helpers.create_channel") - with patch as create_channel: - create_channel.return_value = channel - client = errorreporting_v1beta1.ErrorStatsServiceClient() - - # Setup Request - project_name = client.project_path("[PROJECT]") - time_range = {} - - paged_list_response = client.list_group_stats(project_name, time_range) - resources = list(paged_list_response) - assert len(resources) == 1 - - assert expected_response.error_group_stats[0] == resources[0] - - assert len(channel.requests) == 1 - expected_request = error_stats_service_pb2.ListGroupStatsRequest( - project_name=project_name, time_range=time_range - ) - actual_request = channel.requests[0][1] - assert expected_request == actual_request - - def test_list_group_stats_exception(self): - channel = ChannelStub(responses=[CustomException()]) - patch = mock.patch("google.api_core.grpc_helpers.create_channel") - with patch as create_channel: - create_channel.return_value = channel - client = errorreporting_v1beta1.ErrorStatsServiceClient() - - # Setup request - project_name = client.project_path("[PROJECT]") - time_range = {} - - paged_list_response = client.list_group_stats(project_name, time_range) - with pytest.raises(CustomException): - list(paged_list_response) - - def test_list_events(self): - # Setup Expected Response - next_page_token = "" - error_events_element = {} - error_events = [error_events_element] - expected_response = { - "next_page_token": next_page_token, - "error_events": error_events, - } - expected_response = error_stats_service_pb2.ListEventsResponse( - **expected_response - ) - - # Mock the API response - channel = ChannelStub(responses=[expected_response]) - patch = mock.patch("google.api_core.grpc_helpers.create_channel") - with patch as create_channel: - create_channel.return_value = channel - client = errorreporting_v1beta1.ErrorStatsServiceClient() - - # Setup Request - project_name = client.project_path("[PROJECT]") - group_id = "groupId506361563" - - paged_list_response = client.list_events(project_name, group_id) - resources = list(paged_list_response) - assert len(resources) == 1 - - assert expected_response.error_events[0] == resources[0] - - assert len(channel.requests) == 1 - expected_request = error_stats_service_pb2.ListEventsRequest( - project_name=project_name, group_id=group_id - ) - actual_request = channel.requests[0][1] - assert expected_request == actual_request - - def test_list_events_exception(self): - channel = ChannelStub(responses=[CustomException()]) - patch = mock.patch("google.api_core.grpc_helpers.create_channel") - with patch as create_channel: - create_channel.return_value = channel - client = errorreporting_v1beta1.ErrorStatsServiceClient() - - # Setup request - project_name = client.project_path("[PROJECT]") - group_id = "groupId506361563" - - paged_list_response = client.list_events(project_name, group_id) - with pytest.raises(CustomException): - list(paged_list_response) - - def test_delete_events(self): - # Setup Expected Response - expected_response = {} - expected_response = error_stats_service_pb2.DeleteEventsResponse( - **expected_response - ) - - # Mock the API response - channel = ChannelStub(responses=[expected_response]) - patch = mock.patch("google.api_core.grpc_helpers.create_channel") - with patch as create_channel: - create_channel.return_value = channel - client = errorreporting_v1beta1.ErrorStatsServiceClient() - - # Setup Request - project_name = client.project_path("[PROJECT]") - - response = client.delete_events(project_name) - assert expected_response == response - - assert len(channel.requests) == 1 - expected_request = error_stats_service_pb2.DeleteEventsRequest( - project_name=project_name - ) - actual_request = channel.requests[0][1] - assert expected_request == actual_request - - def test_delete_events_exception(self): - # Mock the API response - channel = ChannelStub(responses=[CustomException()]) - patch = mock.patch("google.api_core.grpc_helpers.create_channel") - with patch as create_channel: - create_channel.return_value = channel - client = errorreporting_v1beta1.ErrorStatsServiceClient() - - # Setup request - project_name = client.project_path("[PROJECT]") - - with pytest.raises(CustomException): - client.delete_events(project_name) diff --git a/tests/unit/gapic/v1beta1/test_report_errors_service_client_v1beta1.py b/tests/unit/gapic/v1beta1/test_report_errors_service_client_v1beta1.py deleted file mode 100644 index ef85fa15..00000000 --- a/tests/unit/gapic/v1beta1/test_report_errors_service_client_v1beta1.py +++ /dev/null @@ -1,104 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright 2019 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 -# -# https://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. - -"""Unit tests.""" - -import mock -import pytest - -from google.cloud import errorreporting_v1beta1 -from google.cloud.errorreporting_v1beta1.proto import report_errors_service_pb2 - - -class MultiCallableStub(object): - """Stub for the grpc.UnaryUnaryMultiCallable interface.""" - - def __init__(self, method, channel_stub): - self.method = method - self.channel_stub = channel_stub - - def __call__(self, request, timeout=None, metadata=None, credentials=None): - self.channel_stub.requests.append((self.method, request)) - - response = None - if self.channel_stub.responses: - response = self.channel_stub.responses.pop() - - if isinstance(response, Exception): - raise response - - if response: - return response - - -class ChannelStub(object): - """Stub for the grpc.Channel interface.""" - - def __init__(self, responses=[]): - self.responses = responses - self.requests = [] - - def unary_unary(self, method, request_serializer=None, response_deserializer=None): - return MultiCallableStub(method, self) - - -class CustomException(Exception): - pass - - -class TestReportErrorsServiceClient(object): - def test_report_error_event(self): - # Setup Expected Response - expected_response = {} - expected_response = report_errors_service_pb2.ReportErrorEventResponse( - **expected_response - ) - - # Mock the API response - channel = ChannelStub(responses=[expected_response]) - patch = mock.patch("google.api_core.grpc_helpers.create_channel") - with patch as create_channel: - create_channel.return_value = channel - client = errorreporting_v1beta1.ReportErrorsServiceClient() - - # Setup Request - project_name = client.project_path("[PROJECT]") - event = {} - - response = client.report_error_event(project_name, event) - assert expected_response == response - - assert len(channel.requests) == 1 - expected_request = report_errors_service_pb2.ReportErrorEventRequest( - project_name=project_name, event=event - ) - actual_request = channel.requests[0][1] - assert expected_request == actual_request - - def test_report_error_event_exception(self): - # Mock the API response - channel = ChannelStub(responses=[CustomException()]) - patch = mock.patch("google.api_core.grpc_helpers.create_channel") - with patch as create_channel: - create_channel.return_value = channel - client = errorreporting_v1beta1.ReportErrorsServiceClient() - - # Setup request - project_name = client.project_path("[PROJECT]") - event = {} - - with pytest.raises(CustomException): - client.report_error_event(project_name, event) diff --git a/tests/unit/test__gapic.py b/tests/unit/test__gapic.py index 00940f46..365eee27 100644 --- a/tests/unit/test__gapic.py +++ b/tests/unit/test__gapic.py @@ -31,8 +31,7 @@ def test_make_report_error_api(self): # Call the function being tested. patch = mock.patch( - "google.cloud.errorreporting_v1beta1." - "gapic.report_errors_service_client.ReportErrorsServiceClient" + "google.cloud.errorreporting_v1beta1.ReportErrorsServiceClient" ) with patch as patched: @@ -66,17 +65,18 @@ def test_constructor(self): self.assertEqual(gapic_client_wrapper._gapic_api, gapic_api) def test_report_error_event(self): - from google.cloud.errorreporting_v1beta1.proto import report_errors_service_pb2 + import google.cloud.errorreporting_v1beta1 - gapic_api = mock.Mock(spec=["project_path", "report_error_event"]) + gapic_api = mock.Mock(spec=["report_error_event"]) gapic_client_wrapper = self._make_one(gapic_api, self.PROJECT) error_report = {"message": "The cabs are here."} gapic_client_wrapper.report_error_event(error_report) - gapic_api.project_path.assert_called_once_with(self.PROJECT) - project_name = gapic_api.project_path.return_value - error_pb = report_errors_service_pb2.ReportedErrorEvent( + project_name = f"projects/{self.PROJECT}" + error_pb = google.cloud.errorreporting_v1beta1.ReportedErrorEvent( message=error_report["message"] ) - gapic_api.report_error_event.assert_called_once_with(project_name, error_pb) + gapic_api.report_error_event.assert_called_once_with( + project_name=project_name, event=error_pb + )