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