1# -*- coding: utf-8 -*-
2# Copyright 2025 Google LLC
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15#
16from collections import OrderedDict
17from http import HTTPStatus
18import json
19import logging as std_logging
20import os
21import re
22from typing import (
23 Dict,
24 Callable,
25 Mapping,
26 MutableMapping,
27 MutableSequence,
28 Optional,
29 Sequence,
30 Tuple,
31 Type,
32 Union,
33 cast,
34)
35import warnings
36
37from google.cloud.errorreporting_v1beta1 import gapic_version as package_version
38
39from google.api_core import client_options as client_options_lib
40from google.api_core import exceptions as core_exceptions
41from google.api_core import gapic_v1
42from google.api_core import retry as retries
43from google.auth import credentials as ga_credentials # type: ignore
44from google.auth.transport import mtls # type: ignore
45from google.auth.transport.grpc import SslCredentials # type: ignore
46from google.auth.exceptions import MutualTLSChannelError # type: ignore
47from google.oauth2 import service_account # type: ignore
48import google.protobuf
49
50try:
51 OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None]
52except AttributeError: # pragma: NO COVER
53 OptionalRetry = Union[retries.Retry, object, None] # type: ignore
54
55try:
56 from google.api_core import client_logging # type: ignore
57
58 CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER
59except ImportError: # pragma: NO COVER
60 CLIENT_LOGGING_SUPPORTED = False
61
62_LOGGER = std_logging.getLogger(__name__)
63
64from google.cloud.errorreporting_v1beta1.services.error_stats_service import pagers
65from google.cloud.errorreporting_v1beta1.types import common
66from google.cloud.errorreporting_v1beta1.types import error_stats_service
67from .transports.base import ErrorStatsServiceTransport, DEFAULT_CLIENT_INFO
68from .transports.grpc import ErrorStatsServiceGrpcTransport
69from .transports.grpc_asyncio import ErrorStatsServiceGrpcAsyncIOTransport
70from .transports.rest import ErrorStatsServiceRestTransport
71
72
73class ErrorStatsServiceClientMeta(type):
74 """Metaclass for the ErrorStatsService client.
75
76 This provides class-level methods for building and retrieving
77 support objects (e.g. transport) without polluting the client instance
78 objects.
79 """
80
81 _transport_registry = (
82 OrderedDict()
83 ) # type: Dict[str, Type[ErrorStatsServiceTransport]]
84 _transport_registry["grpc"] = ErrorStatsServiceGrpcTransport
85 _transport_registry["grpc_asyncio"] = ErrorStatsServiceGrpcAsyncIOTransport
86 _transport_registry["rest"] = ErrorStatsServiceRestTransport
87
88 def get_transport_class(
89 cls,
90 label: Optional[str] = None,
91 ) -> Type[ErrorStatsServiceTransport]:
92 """Returns an appropriate transport class.
93
94 Args:
95 label: The name of the desired transport. If none is
96 provided, then the first transport in the registry is used.
97
98 Returns:
99 The transport class to use.
100 """
101 # If a specific transport is requested, return that one.
102 if label:
103 return cls._transport_registry[label]
104
105 # No transport is requested; return the default (that is, the first one
106 # in the dictionary).
107 return next(iter(cls._transport_registry.values()))
108
109
110class ErrorStatsServiceClient(metaclass=ErrorStatsServiceClientMeta):
111 """An API for retrieving and managing error statistics as well
112 as data for individual events.
113 """
114
115 @staticmethod
116 def _get_default_mtls_endpoint(api_endpoint):
117 """Converts api endpoint to mTLS endpoint.
118
119 Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to
120 "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively.
121 Args:
122 api_endpoint (Optional[str]): the api endpoint to convert.
123 Returns:
124 str: converted mTLS api endpoint.
125 """
126 if not api_endpoint:
127 return api_endpoint
128
129 mtls_endpoint_re = re.compile(
130 r"(?P<name>[^.]+)(?P<mtls>\.mtls)?(?P<sandbox>\.sandbox)?(?P<googledomain>\.googleapis\.com)?"
131 )
132
133 m = mtls_endpoint_re.match(api_endpoint)
134 name, mtls, sandbox, googledomain = m.groups()
135 if mtls or not googledomain:
136 return api_endpoint
137
138 if sandbox:
139 return api_endpoint.replace(
140 "sandbox.googleapis.com", "mtls.sandbox.googleapis.com"
141 )
142
143 return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com")
144
145 # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead.
146 DEFAULT_ENDPOINT = "clouderrorreporting.googleapis.com"
147 DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore
148 DEFAULT_ENDPOINT
149 )
150
151 _DEFAULT_ENDPOINT_TEMPLATE = "clouderrorreporting.{UNIVERSE_DOMAIN}"
152 _DEFAULT_UNIVERSE = "googleapis.com"
153
154 @classmethod
155 def from_service_account_info(cls, info: dict, *args, **kwargs):
156 """Creates an instance of this client using the provided credentials
157 info.
158
159 Args:
160 info (dict): The service account private key info.
161 args: Additional arguments to pass to the constructor.
162 kwargs: Additional arguments to pass to the constructor.
163
164 Returns:
165 ErrorStatsServiceClient: The constructed client.
166 """
167 credentials = service_account.Credentials.from_service_account_info(info)
168 kwargs["credentials"] = credentials
169 return cls(*args, **kwargs)
170
171 @classmethod
172 def from_service_account_file(cls, filename: str, *args, **kwargs):
173 """Creates an instance of this client using the provided credentials
174 file.
175
176 Args:
177 filename (str): The path to the service account private key json
178 file.
179 args: Additional arguments to pass to the constructor.
180 kwargs: Additional arguments to pass to the constructor.
181
182 Returns:
183 ErrorStatsServiceClient: The constructed client.
184 """
185 credentials = service_account.Credentials.from_service_account_file(filename)
186 kwargs["credentials"] = credentials
187 return cls(*args, **kwargs)
188
189 from_service_account_json = from_service_account_file
190
191 @property
192 def transport(self) -> ErrorStatsServiceTransport:
193 """Returns the transport used by the client instance.
194
195 Returns:
196 ErrorStatsServiceTransport: The transport used by the client
197 instance.
198 """
199 return self._transport
200
201 @staticmethod
202 def error_group_path(
203 project: str,
204 group: str,
205 ) -> str:
206 """Returns a fully-qualified error_group string."""
207 return "projects/{project}/groups/{group}".format(
208 project=project,
209 group=group,
210 )
211
212 @staticmethod
213 def parse_error_group_path(path: str) -> Dict[str, str]:
214 """Parses a error_group path into its component segments."""
215 m = re.match(r"^projects/(?P<project>.+?)/groups/(?P<group>.+?)$", path)
216 return m.groupdict() if m else {}
217
218 @staticmethod
219 def common_billing_account_path(
220 billing_account: str,
221 ) -> str:
222 """Returns a fully-qualified billing_account string."""
223 return "billingAccounts/{billing_account}".format(
224 billing_account=billing_account,
225 )
226
227 @staticmethod
228 def parse_common_billing_account_path(path: str) -> Dict[str, str]:
229 """Parse a billing_account path into its component segments."""
230 m = re.match(r"^billingAccounts/(?P<billing_account>.+?)$", path)
231 return m.groupdict() if m else {}
232
233 @staticmethod
234 def common_folder_path(
235 folder: str,
236 ) -> str:
237 """Returns a fully-qualified folder string."""
238 return "folders/{folder}".format(
239 folder=folder,
240 )
241
242 @staticmethod
243 def parse_common_folder_path(path: str) -> Dict[str, str]:
244 """Parse a folder path into its component segments."""
245 m = re.match(r"^folders/(?P<folder>.+?)$", path)
246 return m.groupdict() if m else {}
247
248 @staticmethod
249 def common_organization_path(
250 organization: str,
251 ) -> str:
252 """Returns a fully-qualified organization string."""
253 return "organizations/{organization}".format(
254 organization=organization,
255 )
256
257 @staticmethod
258 def parse_common_organization_path(path: str) -> Dict[str, str]:
259 """Parse a organization path into its component segments."""
260 m = re.match(r"^organizations/(?P<organization>.+?)$", path)
261 return m.groupdict() if m else {}
262
263 @staticmethod
264 def common_project_path(
265 project: str,
266 ) -> str:
267 """Returns a fully-qualified project string."""
268 return "projects/{project}".format(
269 project=project,
270 )
271
272 @staticmethod
273 def parse_common_project_path(path: str) -> Dict[str, str]:
274 """Parse a project path into its component segments."""
275 m = re.match(r"^projects/(?P<project>.+?)$", path)
276 return m.groupdict() if m else {}
277
278 @staticmethod
279 def common_location_path(
280 project: str,
281 location: str,
282 ) -> str:
283 """Returns a fully-qualified location string."""
284 return "projects/{project}/locations/{location}".format(
285 project=project,
286 location=location,
287 )
288
289 @staticmethod
290 def parse_common_location_path(path: str) -> Dict[str, str]:
291 """Parse a location path into its component segments."""
292 m = re.match(r"^projects/(?P<project>.+?)/locations/(?P<location>.+?)$", path)
293 return m.groupdict() if m else {}
294
295 @classmethod
296 def get_mtls_endpoint_and_cert_source(
297 cls, client_options: Optional[client_options_lib.ClientOptions] = None
298 ):
299 """Deprecated. Return the API endpoint and client cert source for mutual TLS.
300
301 The client cert source is determined in the following order:
302 (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the
303 client cert source is None.
304 (2) if `client_options.client_cert_source` is provided, use the provided one; if the
305 default client cert source exists, use the default one; otherwise the client cert
306 source is None.
307
308 The API endpoint is determined in the following order:
309 (1) if `client_options.api_endpoint` if provided, use the provided one.
310 (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the
311 default mTLS endpoint; if the environment variable is "never", use the default API
312 endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise
313 use the default API endpoint.
314
315 More details can be found at https://google.aip.dev/auth/4114.
316
317 Args:
318 client_options (google.api_core.client_options.ClientOptions): Custom options for the
319 client. Only the `api_endpoint` and `client_cert_source` properties may be used
320 in this method.
321
322 Returns:
323 Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the
324 client cert source to use.
325
326 Raises:
327 google.auth.exceptions.MutualTLSChannelError: If any errors happen.
328 """
329
330 warnings.warn(
331 "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.",
332 DeprecationWarning,
333 )
334 if client_options is None:
335 client_options = client_options_lib.ClientOptions()
336 use_client_cert = os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false")
337 use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto")
338 if use_client_cert not in ("true", "false"):
339 raise ValueError(
340 "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`"
341 )
342 if use_mtls_endpoint not in ("auto", "never", "always"):
343 raise MutualTLSChannelError(
344 "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`"
345 )
346
347 # Figure out the client cert source to use.
348 client_cert_source = None
349 if use_client_cert == "true":
350 if client_options.client_cert_source:
351 client_cert_source = client_options.client_cert_source
352 elif mtls.has_default_client_cert_source():
353 client_cert_source = mtls.default_client_cert_source()
354
355 # Figure out which api endpoint to use.
356 if client_options.api_endpoint is not None:
357 api_endpoint = client_options.api_endpoint
358 elif use_mtls_endpoint == "always" or (
359 use_mtls_endpoint == "auto" and client_cert_source
360 ):
361 api_endpoint = cls.DEFAULT_MTLS_ENDPOINT
362 else:
363 api_endpoint = cls.DEFAULT_ENDPOINT
364
365 return api_endpoint, client_cert_source
366
367 @staticmethod
368 def _read_environment_variables():
369 """Returns the environment variables used by the client.
370
371 Returns:
372 Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE,
373 GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables.
374
375 Raises:
376 ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not
377 any of ["true", "false"].
378 google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT
379 is not any of ["auto", "never", "always"].
380 """
381 use_client_cert = os.getenv(
382 "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false"
383 ).lower()
384 use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto").lower()
385 universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN")
386 if use_client_cert not in ("true", "false"):
387 raise ValueError(
388 "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`"
389 )
390 if use_mtls_endpoint not in ("auto", "never", "always"):
391 raise MutualTLSChannelError(
392 "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`"
393 )
394 return use_client_cert == "true", use_mtls_endpoint, universe_domain_env
395
396 @staticmethod
397 def _get_client_cert_source(provided_cert_source, use_cert_flag):
398 """Return the client cert source to be used by the client.
399
400 Args:
401 provided_cert_source (bytes): The client certificate source provided.
402 use_cert_flag (bool): A flag indicating whether to use the client certificate.
403
404 Returns:
405 bytes or None: The client cert source to be used by the client.
406 """
407 client_cert_source = None
408 if use_cert_flag:
409 if provided_cert_source:
410 client_cert_source = provided_cert_source
411 elif mtls.has_default_client_cert_source():
412 client_cert_source = mtls.default_client_cert_source()
413 return client_cert_source
414
415 @staticmethod
416 def _get_api_endpoint(
417 api_override, client_cert_source, universe_domain, use_mtls_endpoint
418 ):
419 """Return the API endpoint used by the client.
420
421 Args:
422 api_override (str): The API endpoint override. If specified, this is always
423 the return value of this function and the other arguments are not used.
424 client_cert_source (bytes): The client certificate source used by the client.
425 universe_domain (str): The universe domain used by the client.
426 use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters.
427 Possible values are "always", "auto", or "never".
428
429 Returns:
430 str: The API endpoint to be used by the client.
431 """
432 if api_override is not None:
433 api_endpoint = api_override
434 elif use_mtls_endpoint == "always" or (
435 use_mtls_endpoint == "auto" and client_cert_source
436 ):
437 _default_universe = ErrorStatsServiceClient._DEFAULT_UNIVERSE
438 if universe_domain != _default_universe:
439 raise MutualTLSChannelError(
440 f"mTLS is not supported in any universe other than {_default_universe}."
441 )
442 api_endpoint = ErrorStatsServiceClient.DEFAULT_MTLS_ENDPOINT
443 else:
444 api_endpoint = ErrorStatsServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format(
445 UNIVERSE_DOMAIN=universe_domain
446 )
447 return api_endpoint
448
449 @staticmethod
450 def _get_universe_domain(
451 client_universe_domain: Optional[str], universe_domain_env: Optional[str]
452 ) -> str:
453 """Return the universe domain used by the client.
454
455 Args:
456 client_universe_domain (Optional[str]): The universe domain configured via the client options.
457 universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable.
458
459 Returns:
460 str: The universe domain to be used by the client.
461
462 Raises:
463 ValueError: If the universe domain is an empty string.
464 """
465 universe_domain = ErrorStatsServiceClient._DEFAULT_UNIVERSE
466 if client_universe_domain is not None:
467 universe_domain = client_universe_domain
468 elif universe_domain_env is not None:
469 universe_domain = universe_domain_env
470 if len(universe_domain.strip()) == 0:
471 raise ValueError("Universe Domain cannot be an empty string.")
472 return universe_domain
473
474 def _validate_universe_domain(self):
475 """Validates client's and credentials' universe domains are consistent.
476
477 Returns:
478 bool: True iff the configured universe domain is valid.
479
480 Raises:
481 ValueError: If the configured universe domain is not valid.
482 """
483
484 # NOTE (b/349488459): universe validation is disabled until further notice.
485 return True
486
487 def _add_cred_info_for_auth_errors(
488 self, error: core_exceptions.GoogleAPICallError
489 ) -> None:
490 """Adds credential info string to error details for 401/403/404 errors.
491
492 Args:
493 error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info.
494 """
495 if error.code not in [
496 HTTPStatus.UNAUTHORIZED,
497 HTTPStatus.FORBIDDEN,
498 HTTPStatus.NOT_FOUND,
499 ]:
500 return
501
502 cred = self._transport._credentials
503
504 # get_cred_info is only available in google-auth>=2.35.0
505 if not hasattr(cred, "get_cred_info"):
506 return
507
508 # ignore the type check since pypy test fails when get_cred_info
509 # is not available
510 cred_info = cred.get_cred_info() # type: ignore
511 if cred_info and hasattr(error._details, "append"):
512 error._details.append(json.dumps(cred_info))
513
514 @property
515 def api_endpoint(self):
516 """Return the API endpoint used by the client instance.
517
518 Returns:
519 str: The API endpoint used by the client instance.
520 """
521 return self._api_endpoint
522
523 @property
524 def universe_domain(self) -> str:
525 """Return the universe domain used by the client instance.
526
527 Returns:
528 str: The universe domain used by the client instance.
529 """
530 return self._universe_domain
531
532 def __init__(
533 self,
534 *,
535 credentials: Optional[ga_credentials.Credentials] = None,
536 transport: Optional[
537 Union[
538 str,
539 ErrorStatsServiceTransport,
540 Callable[..., ErrorStatsServiceTransport],
541 ]
542 ] = None,
543 client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None,
544 client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
545 ) -> None:
546 """Instantiates the error stats service client.
547
548 Args:
549 credentials (Optional[google.auth.credentials.Credentials]): The
550 authorization credentials to attach to requests. These
551 credentials identify the application to the service; if none
552 are specified, the client will attempt to ascertain the
553 credentials from the environment.
554 transport (Optional[Union[str,ErrorStatsServiceTransport,Callable[..., ErrorStatsServiceTransport]]]):
555 The transport to use, or a Callable that constructs and returns a new transport.
556 If a Callable is given, it will be called with the same set of initialization
557 arguments as used in the ErrorStatsServiceTransport constructor.
558 If set to None, a transport is chosen automatically.
559 client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]):
560 Custom options for the client.
561
562 1. The ``api_endpoint`` property can be used to override the
563 default endpoint provided by the client when ``transport`` is
564 not explicitly provided. Only if this property is not set and
565 ``transport`` was not explicitly provided, the endpoint is
566 determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment
567 variable, which have one of the following values:
568 "always" (always use the default mTLS endpoint), "never" (always
569 use the default regular endpoint) and "auto" (auto-switch to the
570 default mTLS endpoint if client certificate is present; this is
571 the default value).
572
573 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable
574 is "true", then the ``client_cert_source`` property can be used
575 to provide a client certificate for mTLS transport. If
576 not provided, the default SSL client certificate will be used if
577 present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not
578 set, no client certificate will be used.
579
580 3. The ``universe_domain`` property can be used to override the
581 default "googleapis.com" universe. Note that the ``api_endpoint``
582 property still takes precedence; and ``universe_domain`` is
583 currently not supported for mTLS.
584
585 client_info (google.api_core.gapic_v1.client_info.ClientInfo):
586 The client info used to send a user-agent string along with
587 API requests. If ``None``, then default info will be used.
588 Generally, you only need to set this if you're developing
589 your own client library.
590
591 Raises:
592 google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport
593 creation failed for any reason.
594 """
595 self._client_options = client_options
596 if isinstance(self._client_options, dict):
597 self._client_options = client_options_lib.from_dict(self._client_options)
598 if self._client_options is None:
599 self._client_options = client_options_lib.ClientOptions()
600 self._client_options = cast(
601 client_options_lib.ClientOptions, self._client_options
602 )
603
604 universe_domain_opt = getattr(self._client_options, "universe_domain", None)
605
606 (
607 self._use_client_cert,
608 self._use_mtls_endpoint,
609 self._universe_domain_env,
610 ) = ErrorStatsServiceClient._read_environment_variables()
611 self._client_cert_source = ErrorStatsServiceClient._get_client_cert_source(
612 self._client_options.client_cert_source, self._use_client_cert
613 )
614 self._universe_domain = ErrorStatsServiceClient._get_universe_domain(
615 universe_domain_opt, self._universe_domain_env
616 )
617 self._api_endpoint = None # updated below, depending on `transport`
618
619 # Initialize the universe domain validation.
620 self._is_universe_domain_valid = False
621
622 if CLIENT_LOGGING_SUPPORTED: # pragma: NO COVER
623 # Setup logging.
624 client_logging.initialize_logging()
625
626 api_key_value = getattr(self._client_options, "api_key", None)
627 if api_key_value and credentials:
628 raise ValueError(
629 "client_options.api_key and credentials are mutually exclusive"
630 )
631
632 # Save or instantiate the transport.
633 # Ordinarily, we provide the transport, but allowing a custom transport
634 # instance provides an extensibility point for unusual situations.
635 transport_provided = isinstance(transport, ErrorStatsServiceTransport)
636 if transport_provided:
637 # transport is a ErrorStatsServiceTransport instance.
638 if credentials or self._client_options.credentials_file or api_key_value:
639 raise ValueError(
640 "When providing a transport instance, "
641 "provide its credentials directly."
642 )
643 if self._client_options.scopes:
644 raise ValueError(
645 "When providing a transport instance, provide its scopes "
646 "directly."
647 )
648 self._transport = cast(ErrorStatsServiceTransport, transport)
649 self._api_endpoint = self._transport.host
650
651 self._api_endpoint = (
652 self._api_endpoint
653 or ErrorStatsServiceClient._get_api_endpoint(
654 self._client_options.api_endpoint,
655 self._client_cert_source,
656 self._universe_domain,
657 self._use_mtls_endpoint,
658 )
659 )
660
661 if not transport_provided:
662 import google.auth._default # type: ignore
663
664 if api_key_value and hasattr(
665 google.auth._default, "get_api_key_credentials"
666 ):
667 credentials = google.auth._default.get_api_key_credentials(
668 api_key_value
669 )
670
671 transport_init: Union[
672 Type[ErrorStatsServiceTransport],
673 Callable[..., ErrorStatsServiceTransport],
674 ] = (
675 ErrorStatsServiceClient.get_transport_class(transport)
676 if isinstance(transport, str) or transport is None
677 else cast(Callable[..., ErrorStatsServiceTransport], transport)
678 )
679 # initialize with the provided callable or the passed in class
680 self._transport = transport_init(
681 credentials=credentials,
682 credentials_file=self._client_options.credentials_file,
683 host=self._api_endpoint,
684 scopes=self._client_options.scopes,
685 client_cert_source_for_mtls=self._client_cert_source,
686 quota_project_id=self._client_options.quota_project_id,
687 client_info=client_info,
688 always_use_jwt_access=True,
689 api_audience=self._client_options.api_audience,
690 )
691
692 if "async" not in str(self._transport):
693 if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
694 std_logging.DEBUG
695 ): # pragma: NO COVER
696 _LOGGER.debug(
697 "Created client `google.devtools.clouderrorreporting_v1beta1.ErrorStatsServiceClient`.",
698 extra={
699 "serviceName": "google.devtools.clouderrorreporting.v1beta1.ErrorStatsService",
700 "universeDomain": getattr(
701 self._transport._credentials, "universe_domain", ""
702 ),
703 "credentialsType": f"{type(self._transport._credentials).__module__}.{type(self._transport._credentials).__qualname__}",
704 "credentialsInfo": getattr(
705 self.transport._credentials, "get_cred_info", lambda: None
706 )(),
707 }
708 if hasattr(self._transport, "_credentials")
709 else {
710 "serviceName": "google.devtools.clouderrorreporting.v1beta1.ErrorStatsService",
711 "credentialsType": None,
712 },
713 )
714
715 def list_group_stats(
716 self,
717 request: Optional[
718 Union[error_stats_service.ListGroupStatsRequest, dict]
719 ] = None,
720 *,
721 project_name: Optional[str] = None,
722 time_range: Optional[error_stats_service.QueryTimeRange] = None,
723 retry: OptionalRetry = gapic_v1.method.DEFAULT,
724 timeout: Union[float, object] = gapic_v1.method.DEFAULT,
725 metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
726 ) -> pagers.ListGroupStatsPager:
727 r"""Lists the specified groups.
728
729 .. code-block:: python
730
731 # This snippet has been automatically generated and should be regarded as a
732 # code template only.
733 # It will require modifications to work:
734 # - It may require correct/in-range values for request initialization.
735 # - It may require specifying regional endpoints when creating the service
736 # client as shown in:
737 # https://googleapis.dev/python/google-api-core/latest/client_options.html
738 from google.cloud import errorreporting_v1beta1
739
740 def sample_list_group_stats():
741 # Create a client
742 client = errorreporting_v1beta1.ErrorStatsServiceClient()
743
744 # Initialize request argument(s)
745 request = errorreporting_v1beta1.ListGroupStatsRequest(
746 project_name="project_name_value",
747 )
748
749 # Make the request
750 page_result = client.list_group_stats(request=request)
751
752 # Handle the response
753 for response in page_result:
754 print(response)
755
756 Args:
757 request (Union[google.cloud.errorreporting_v1beta1.types.ListGroupStatsRequest, dict]):
758 The request object. Specifies a set of ``ErrorGroupStats`` to return.
759 project_name (str):
760 Required. The resource name of the Google Cloud Platform
761 project. Written as ``projects/{projectID}`` or
762 ``projects/{projectNumber}``, where ``{projectID}`` and
763 ``{projectNumber}`` can be found in the `Google Cloud
764 console <https://support.google.com/cloud/answer/6158840>`__.
765 It may also include a location, such as
766 ``projects/{projectID}/locations/{location}`` where
767 ``{location}`` is a cloud region.
768
769 Examples: ``projects/my-project-123``,
770 ``projects/5551234``,
771 ``projects/my-project-123/locations/us-central1``,
772 ``projects/5551234/locations/us-central1``.
773
774 For a list of supported locations, see `Supported
775 Regions <https://cloud.google.com/logging/docs/region-support>`__.
776 ``global`` is the default when unspecified. Use ``-`` as
777 a wildcard to request group stats from all regions.
778
779 This corresponds to the ``project_name`` field
780 on the ``request`` instance; if ``request`` is provided, this
781 should not be set.
782 time_range (google.cloud.errorreporting_v1beta1.types.QueryTimeRange):
783 Optional. List data for the given time range. If not
784 set, a default time range is used. The field
785 [time_range_begin]
786 [google.devtools.clouderrorreporting.v1beta1.ListGroupStatsResponse.time_range_begin]
787 in the response will specify the beginning of this time
788 range. Only [ErrorGroupStats]
789 [google.devtools.clouderrorreporting.v1beta1.ErrorGroupStats]
790 with a non-zero count in the given time range are
791 returned, unless the request contains an explicit
792 [group_id]
793 [google.devtools.clouderrorreporting.v1beta1.ListGroupStatsRequest.group_id]
794 list. If a [group_id]
795 [google.devtools.clouderrorreporting.v1beta1.ListGroupStatsRequest.group_id]
796 list is given, also [ErrorGroupStats]
797 [google.devtools.clouderrorreporting.v1beta1.ErrorGroupStats]
798 with zero occurrences are returned.
799
800 This corresponds to the ``time_range`` field
801 on the ``request`` instance; if ``request`` is provided, this
802 should not be set.
803 retry (google.api_core.retry.Retry): Designation of what errors, if any,
804 should be retried.
805 timeout (float): The timeout for this request.
806 metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
807 sent along with the request as metadata. Normally, each value must be of type `str`,
808 but for metadata keys ending with the suffix `-bin`, the corresponding values must
809 be of type `bytes`.
810
811 Returns:
812 google.cloud.errorreporting_v1beta1.services.error_stats_service.pagers.ListGroupStatsPager:
813 Contains a set of requested error
814 group stats.
815 Iterating over this object will yield
816 results and resolve additional pages
817 automatically.
818
819 """
820 # Create or coerce a protobuf request object.
821 # - Quick check: If we got a request object, we should *not* have
822 # gotten any keyword arguments that map to the request.
823 flattened_params = [project_name, time_range]
824 has_flattened_params = (
825 len([param for param in flattened_params if param is not None]) > 0
826 )
827 if request is not None and has_flattened_params:
828 raise ValueError(
829 "If the `request` argument is set, then none of "
830 "the individual field arguments should be set."
831 )
832
833 # - Use the request object if provided (there's no risk of modifying the input as
834 # there are no flattened fields), or create one.
835 if not isinstance(request, error_stats_service.ListGroupStatsRequest):
836 request = error_stats_service.ListGroupStatsRequest(request)
837 # If we have keyword arguments corresponding to fields on the
838 # request, apply these.
839 if project_name is not None:
840 request.project_name = project_name
841 if time_range is not None:
842 request.time_range = time_range
843
844 # Wrap the RPC method; this adds retry and timeout information,
845 # and friendly error handling.
846 rpc = self._transport._wrapped_methods[self._transport.list_group_stats]
847
848 # Certain fields should be provided within the metadata header;
849 # add these here.
850 metadata = tuple(metadata) + (
851 gapic_v1.routing_header.to_grpc_metadata(
852 (("project_name", request.project_name),)
853 ),
854 )
855
856 # Validate the universe domain.
857 self._validate_universe_domain()
858
859 # Send the request.
860 response = rpc(
861 request,
862 retry=retry,
863 timeout=timeout,
864 metadata=metadata,
865 )
866
867 # This method is paged; wrap the response in a pager, which provides
868 # an `__iter__` convenience method.
869 response = pagers.ListGroupStatsPager(
870 method=rpc,
871 request=request,
872 response=response,
873 retry=retry,
874 timeout=timeout,
875 metadata=metadata,
876 )
877
878 # Done; return the response.
879 return response
880
881 def list_events(
882 self,
883 request: Optional[Union[error_stats_service.ListEventsRequest, dict]] = None,
884 *,
885 project_name: Optional[str] = None,
886 group_id: Optional[str] = None,
887 retry: OptionalRetry = gapic_v1.method.DEFAULT,
888 timeout: Union[float, object] = gapic_v1.method.DEFAULT,
889 metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
890 ) -> pagers.ListEventsPager:
891 r"""Lists the specified events.
892
893 .. code-block:: python
894
895 # This snippet has been automatically generated and should be regarded as a
896 # code template only.
897 # It will require modifications to work:
898 # - It may require correct/in-range values for request initialization.
899 # - It may require specifying regional endpoints when creating the service
900 # client as shown in:
901 # https://googleapis.dev/python/google-api-core/latest/client_options.html
902 from google.cloud import errorreporting_v1beta1
903
904 def sample_list_events():
905 # Create a client
906 client = errorreporting_v1beta1.ErrorStatsServiceClient()
907
908 # Initialize request argument(s)
909 request = errorreporting_v1beta1.ListEventsRequest(
910 project_name="project_name_value",
911 group_id="group_id_value",
912 )
913
914 # Make the request
915 page_result = client.list_events(request=request)
916
917 # Handle the response
918 for response in page_result:
919 print(response)
920
921 Args:
922 request (Union[google.cloud.errorreporting_v1beta1.types.ListEventsRequest, dict]):
923 The request object. Specifies a set of error events to
924 return.
925 project_name (str):
926 Required. The resource name of the Google Cloud Platform
927 project. Written as ``projects/{projectID}`` or
928 ``projects/{projectID}/locations/{location}``, where
929 ``{projectID}`` is the `Google Cloud Platform project
930 ID <https://support.google.com/cloud/answer/6158840>`__
931 and ``{location}`` is a Cloud region.
932
933 Examples: ``projects/my-project-123``,
934 ``projects/my-project-123/locations/global``.
935
936 For a list of supported locations, see `Supported
937 Regions <https://cloud.google.com/logging/docs/region-support>`__.
938 ``global`` is the default when unspecified.
939
940 This corresponds to the ``project_name`` field
941 on the ``request`` instance; if ``request`` is provided, this
942 should not be set.
943 group_id (str):
944 Required. The group for which events shall be returned.
945 The ``group_id`` is a unique identifier for a particular
946 error group. The identifier is derived from key parts of
947 the error-log content and is treated as Service Data.
948 For information about how Service Data is handled, see
949 `Google Cloud Privacy
950 Notice <https://cloud.google.com/terms/cloud-privacy-notice>`__.
951
952 This corresponds to the ``group_id`` field
953 on the ``request`` instance; if ``request`` is provided, this
954 should not be set.
955 retry (google.api_core.retry.Retry): Designation of what errors, if any,
956 should be retried.
957 timeout (float): The timeout for this request.
958 metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
959 sent along with the request as metadata. Normally, each value must be of type `str`,
960 but for metadata keys ending with the suffix `-bin`, the corresponding values must
961 be of type `bytes`.
962
963 Returns:
964 google.cloud.errorreporting_v1beta1.services.error_stats_service.pagers.ListEventsPager:
965 Contains a set of requested error
966 events.
967 Iterating over this object will yield
968 results and resolve additional pages
969 automatically.
970
971 """
972 # Create or coerce a protobuf request object.
973 # - Quick check: If we got a request object, we should *not* have
974 # gotten any keyword arguments that map to the request.
975 flattened_params = [project_name, group_id]
976 has_flattened_params = (
977 len([param for param in flattened_params if param is not None]) > 0
978 )
979 if request is not None and has_flattened_params:
980 raise ValueError(
981 "If the `request` argument is set, then none of "
982 "the individual field arguments should be set."
983 )
984
985 # - Use the request object if provided (there's no risk of modifying the input as
986 # there are no flattened fields), or create one.
987 if not isinstance(request, error_stats_service.ListEventsRequest):
988 request = error_stats_service.ListEventsRequest(request)
989 # If we have keyword arguments corresponding to fields on the
990 # request, apply these.
991 if project_name is not None:
992 request.project_name = project_name
993 if group_id is not None:
994 request.group_id = group_id
995
996 # Wrap the RPC method; this adds retry and timeout information,
997 # and friendly error handling.
998 rpc = self._transport._wrapped_methods[self._transport.list_events]
999
1000 # Certain fields should be provided within the metadata header;
1001 # add these here.
1002 metadata = tuple(metadata) + (
1003 gapic_v1.routing_header.to_grpc_metadata(
1004 (("project_name", request.project_name),)
1005 ),
1006 )
1007
1008 # Validate the universe domain.
1009 self._validate_universe_domain()
1010
1011 # Send the request.
1012 response = rpc(
1013 request,
1014 retry=retry,
1015 timeout=timeout,
1016 metadata=metadata,
1017 )
1018
1019 # This method is paged; wrap the response in a pager, which provides
1020 # an `__iter__` convenience method.
1021 response = pagers.ListEventsPager(
1022 method=rpc,
1023 request=request,
1024 response=response,
1025 retry=retry,
1026 timeout=timeout,
1027 metadata=metadata,
1028 )
1029
1030 # Done; return the response.
1031 return response
1032
1033 def delete_events(
1034 self,
1035 request: Optional[Union[error_stats_service.DeleteEventsRequest, dict]] = None,
1036 *,
1037 project_name: Optional[str] = None,
1038 retry: OptionalRetry = gapic_v1.method.DEFAULT,
1039 timeout: Union[float, object] = gapic_v1.method.DEFAULT,
1040 metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
1041 ) -> error_stats_service.DeleteEventsResponse:
1042 r"""Deletes all error events of a given project.
1043
1044 .. code-block:: python
1045
1046 # This snippet has been automatically generated and should be regarded as a
1047 # code template only.
1048 # It will require modifications to work:
1049 # - It may require correct/in-range values for request initialization.
1050 # - It may require specifying regional endpoints when creating the service
1051 # client as shown in:
1052 # https://googleapis.dev/python/google-api-core/latest/client_options.html
1053 from google.cloud import errorreporting_v1beta1
1054
1055 def sample_delete_events():
1056 # Create a client
1057 client = errorreporting_v1beta1.ErrorStatsServiceClient()
1058
1059 # Initialize request argument(s)
1060 request = errorreporting_v1beta1.DeleteEventsRequest(
1061 project_name="project_name_value",
1062 )
1063
1064 # Make the request
1065 response = client.delete_events(request=request)
1066
1067 # Handle the response
1068 print(response)
1069
1070 Args:
1071 request (Union[google.cloud.errorreporting_v1beta1.types.DeleteEventsRequest, dict]):
1072 The request object. Deletes all events in the project.
1073 project_name (str):
1074 Required. The resource name of the Google Cloud Platform
1075 project. Written as ``projects/{projectID}`` or
1076 ``projects/{projectID}/locations/{location}``, where
1077 ``{projectID}`` is the `Google Cloud Platform project
1078 ID <https://support.google.com/cloud/answer/6158840>`__
1079 and ``{location}`` is a Cloud region.
1080
1081 Examples: ``projects/my-project-123``,
1082 ``projects/my-project-123/locations/global``.
1083
1084 For a list of supported locations, see `Supported
1085 Regions <https://cloud.google.com/logging/docs/region-support>`__.
1086 ``global`` is the default when unspecified.
1087
1088 This corresponds to the ``project_name`` field
1089 on the ``request`` instance; if ``request`` is provided, this
1090 should not be set.
1091 retry (google.api_core.retry.Retry): Designation of what errors, if any,
1092 should be retried.
1093 timeout (float): The timeout for this request.
1094 metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
1095 sent along with the request as metadata. Normally, each value must be of type `str`,
1096 but for metadata keys ending with the suffix `-bin`, the corresponding values must
1097 be of type `bytes`.
1098
1099 Returns:
1100 google.cloud.errorreporting_v1beta1.types.DeleteEventsResponse:
1101 Response message for deleting error
1102 events.
1103
1104 """
1105 # Create or coerce a protobuf request object.
1106 # - Quick check: If we got a request object, we should *not* have
1107 # gotten any keyword arguments that map to the request.
1108 flattened_params = [project_name]
1109 has_flattened_params = (
1110 len([param for param in flattened_params if param is not None]) > 0
1111 )
1112 if request is not None and has_flattened_params:
1113 raise ValueError(
1114 "If the `request` argument is set, then none of "
1115 "the individual field arguments should be set."
1116 )
1117
1118 # - Use the request object if provided (there's no risk of modifying the input as
1119 # there are no flattened fields), or create one.
1120 if not isinstance(request, error_stats_service.DeleteEventsRequest):
1121 request = error_stats_service.DeleteEventsRequest(request)
1122 # If we have keyword arguments corresponding to fields on the
1123 # request, apply these.
1124 if project_name is not None:
1125 request.project_name = project_name
1126
1127 # Wrap the RPC method; this adds retry and timeout information,
1128 # and friendly error handling.
1129 rpc = self._transport._wrapped_methods[self._transport.delete_events]
1130
1131 # Certain fields should be provided within the metadata header;
1132 # add these here.
1133 metadata = tuple(metadata) + (
1134 gapic_v1.routing_header.to_grpc_metadata(
1135 (("project_name", request.project_name),)
1136 ),
1137 )
1138
1139 # Validate the universe domain.
1140 self._validate_universe_domain()
1141
1142 # Send the request.
1143 response = rpc(
1144 request,
1145 retry=retry,
1146 timeout=timeout,
1147 metadata=metadata,
1148 )
1149
1150 # Done; return the response.
1151 return response
1152
1153 def __enter__(self) -> "ErrorStatsServiceClient":
1154 return self
1155
1156 def __exit__(self, type, value, traceback):
1157 """Releases underlying transport's resources.
1158
1159 .. warning::
1160 ONLY use as a context manager if the transport is NOT shared
1161 with other clients! Exiting the with block will CLOSE the transport
1162 and may cause errors in other clients!
1163 """
1164 self.transport.close()
1165
1166
1167DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(
1168 gapic_version=package_version.__version__
1169)
1170
1171if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER
1172 DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__
1173
1174__all__ = ("ErrorStatsServiceClient",)