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.types import report_errors_service
65from .transports.base import ReportErrorsServiceTransport, DEFAULT_CLIENT_INFO
66from .transports.grpc import ReportErrorsServiceGrpcTransport
67from .transports.grpc_asyncio import ReportErrorsServiceGrpcAsyncIOTransport
68from .transports.rest import ReportErrorsServiceRestTransport
69
70
71class ReportErrorsServiceClientMeta(type):
72 """Metaclass for the ReportErrorsService client.
73
74 This provides class-level methods for building and retrieving
75 support objects (e.g. transport) without polluting the client instance
76 objects.
77 """
78
79 _transport_registry = (
80 OrderedDict()
81 ) # type: Dict[str, Type[ReportErrorsServiceTransport]]
82 _transport_registry["grpc"] = ReportErrorsServiceGrpcTransport
83 _transport_registry["grpc_asyncio"] = ReportErrorsServiceGrpcAsyncIOTransport
84 _transport_registry["rest"] = ReportErrorsServiceRestTransport
85
86 def get_transport_class(
87 cls,
88 label: Optional[str] = None,
89 ) -> Type[ReportErrorsServiceTransport]:
90 """Returns an appropriate transport class.
91
92 Args:
93 label: The name of the desired transport. If none is
94 provided, then the first transport in the registry is used.
95
96 Returns:
97 The transport class to use.
98 """
99 # If a specific transport is requested, return that one.
100 if label:
101 return cls._transport_registry[label]
102
103 # No transport is requested; return the default (that is, the first one
104 # in the dictionary).
105 return next(iter(cls._transport_registry.values()))
106
107
108class ReportErrorsServiceClient(metaclass=ReportErrorsServiceClientMeta):
109 """An API for reporting error events."""
110
111 @staticmethod
112 def _get_default_mtls_endpoint(api_endpoint):
113 """Converts api endpoint to mTLS endpoint.
114
115 Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to
116 "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively.
117 Args:
118 api_endpoint (Optional[str]): the api endpoint to convert.
119 Returns:
120 str: converted mTLS api endpoint.
121 """
122 if not api_endpoint:
123 return api_endpoint
124
125 mtls_endpoint_re = re.compile(
126 r"(?P<name>[^.]+)(?P<mtls>\.mtls)?(?P<sandbox>\.sandbox)?(?P<googledomain>\.googleapis\.com)?"
127 )
128
129 m = mtls_endpoint_re.match(api_endpoint)
130 name, mtls, sandbox, googledomain = m.groups()
131 if mtls or not googledomain:
132 return api_endpoint
133
134 if sandbox:
135 return api_endpoint.replace(
136 "sandbox.googleapis.com", "mtls.sandbox.googleapis.com"
137 )
138
139 return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com")
140
141 # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead.
142 DEFAULT_ENDPOINT = "clouderrorreporting.googleapis.com"
143 DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore
144 DEFAULT_ENDPOINT
145 )
146
147 _DEFAULT_ENDPOINT_TEMPLATE = "clouderrorreporting.{UNIVERSE_DOMAIN}"
148 _DEFAULT_UNIVERSE = "googleapis.com"
149
150 @classmethod
151 def from_service_account_info(cls, info: dict, *args, **kwargs):
152 """Creates an instance of this client using the provided credentials
153 info.
154
155 Args:
156 info (dict): The service account private key info.
157 args: Additional arguments to pass to the constructor.
158 kwargs: Additional arguments to pass to the constructor.
159
160 Returns:
161 ReportErrorsServiceClient: The constructed client.
162 """
163 credentials = service_account.Credentials.from_service_account_info(info)
164 kwargs["credentials"] = credentials
165 return cls(*args, **kwargs)
166
167 @classmethod
168 def from_service_account_file(cls, filename: str, *args, **kwargs):
169 """Creates an instance of this client using the provided credentials
170 file.
171
172 Args:
173 filename (str): The path to the service account private key json
174 file.
175 args: Additional arguments to pass to the constructor.
176 kwargs: Additional arguments to pass to the constructor.
177
178 Returns:
179 ReportErrorsServiceClient: The constructed client.
180 """
181 credentials = service_account.Credentials.from_service_account_file(filename)
182 kwargs["credentials"] = credentials
183 return cls(*args, **kwargs)
184
185 from_service_account_json = from_service_account_file
186
187 @property
188 def transport(self) -> ReportErrorsServiceTransport:
189 """Returns the transport used by the client instance.
190
191 Returns:
192 ReportErrorsServiceTransport: The transport used by the client
193 instance.
194 """
195 return self._transport
196
197 @staticmethod
198 def common_billing_account_path(
199 billing_account: str,
200 ) -> str:
201 """Returns a fully-qualified billing_account string."""
202 return "billingAccounts/{billing_account}".format(
203 billing_account=billing_account,
204 )
205
206 @staticmethod
207 def parse_common_billing_account_path(path: str) -> Dict[str, str]:
208 """Parse a billing_account path into its component segments."""
209 m = re.match(r"^billingAccounts/(?P<billing_account>.+?)$", path)
210 return m.groupdict() if m else {}
211
212 @staticmethod
213 def common_folder_path(
214 folder: str,
215 ) -> str:
216 """Returns a fully-qualified folder string."""
217 return "folders/{folder}".format(
218 folder=folder,
219 )
220
221 @staticmethod
222 def parse_common_folder_path(path: str) -> Dict[str, str]:
223 """Parse a folder path into its component segments."""
224 m = re.match(r"^folders/(?P<folder>.+?)$", path)
225 return m.groupdict() if m else {}
226
227 @staticmethod
228 def common_organization_path(
229 organization: str,
230 ) -> str:
231 """Returns a fully-qualified organization string."""
232 return "organizations/{organization}".format(
233 organization=organization,
234 )
235
236 @staticmethod
237 def parse_common_organization_path(path: str) -> Dict[str, str]:
238 """Parse a organization path into its component segments."""
239 m = re.match(r"^organizations/(?P<organization>.+?)$", path)
240 return m.groupdict() if m else {}
241
242 @staticmethod
243 def common_project_path(
244 project: str,
245 ) -> str:
246 """Returns a fully-qualified project string."""
247 return "projects/{project}".format(
248 project=project,
249 )
250
251 @staticmethod
252 def parse_common_project_path(path: str) -> Dict[str, str]:
253 """Parse a project path into its component segments."""
254 m = re.match(r"^projects/(?P<project>.+?)$", path)
255 return m.groupdict() if m else {}
256
257 @staticmethod
258 def common_location_path(
259 project: str,
260 location: str,
261 ) -> str:
262 """Returns a fully-qualified location string."""
263 return "projects/{project}/locations/{location}".format(
264 project=project,
265 location=location,
266 )
267
268 @staticmethod
269 def parse_common_location_path(path: str) -> Dict[str, str]:
270 """Parse a location path into its component segments."""
271 m = re.match(r"^projects/(?P<project>.+?)/locations/(?P<location>.+?)$", path)
272 return m.groupdict() if m else {}
273
274 @classmethod
275 def get_mtls_endpoint_and_cert_source(
276 cls, client_options: Optional[client_options_lib.ClientOptions] = None
277 ):
278 """Deprecated. Return the API endpoint and client cert source for mutual TLS.
279
280 The client cert source is determined in the following order:
281 (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the
282 client cert source is None.
283 (2) if `client_options.client_cert_source` is provided, use the provided one; if the
284 default client cert source exists, use the default one; otherwise the client cert
285 source is None.
286
287 The API endpoint is determined in the following order:
288 (1) if `client_options.api_endpoint` if provided, use the provided one.
289 (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the
290 default mTLS endpoint; if the environment variable is "never", use the default API
291 endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise
292 use the default API endpoint.
293
294 More details can be found at https://google.aip.dev/auth/4114.
295
296 Args:
297 client_options (google.api_core.client_options.ClientOptions): Custom options for the
298 client. Only the `api_endpoint` and `client_cert_source` properties may be used
299 in this method.
300
301 Returns:
302 Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the
303 client cert source to use.
304
305 Raises:
306 google.auth.exceptions.MutualTLSChannelError: If any errors happen.
307 """
308
309 warnings.warn(
310 "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.",
311 DeprecationWarning,
312 )
313 if client_options is None:
314 client_options = client_options_lib.ClientOptions()
315 use_client_cert = os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false")
316 use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto")
317 if use_client_cert not in ("true", "false"):
318 raise ValueError(
319 "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`"
320 )
321 if use_mtls_endpoint not in ("auto", "never", "always"):
322 raise MutualTLSChannelError(
323 "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`"
324 )
325
326 # Figure out the client cert source to use.
327 client_cert_source = None
328 if use_client_cert == "true":
329 if client_options.client_cert_source:
330 client_cert_source = client_options.client_cert_source
331 elif mtls.has_default_client_cert_source():
332 client_cert_source = mtls.default_client_cert_source()
333
334 # Figure out which api endpoint to use.
335 if client_options.api_endpoint is not None:
336 api_endpoint = client_options.api_endpoint
337 elif use_mtls_endpoint == "always" or (
338 use_mtls_endpoint == "auto" and client_cert_source
339 ):
340 api_endpoint = cls.DEFAULT_MTLS_ENDPOINT
341 else:
342 api_endpoint = cls.DEFAULT_ENDPOINT
343
344 return api_endpoint, client_cert_source
345
346 @staticmethod
347 def _read_environment_variables():
348 """Returns the environment variables used by the client.
349
350 Returns:
351 Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE,
352 GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables.
353
354 Raises:
355 ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not
356 any of ["true", "false"].
357 google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT
358 is not any of ["auto", "never", "always"].
359 """
360 use_client_cert = os.getenv(
361 "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false"
362 ).lower()
363 use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto").lower()
364 universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN")
365 if use_client_cert not in ("true", "false"):
366 raise ValueError(
367 "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`"
368 )
369 if use_mtls_endpoint not in ("auto", "never", "always"):
370 raise MutualTLSChannelError(
371 "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`"
372 )
373 return use_client_cert == "true", use_mtls_endpoint, universe_domain_env
374
375 @staticmethod
376 def _get_client_cert_source(provided_cert_source, use_cert_flag):
377 """Return the client cert source to be used by the client.
378
379 Args:
380 provided_cert_source (bytes): The client certificate source provided.
381 use_cert_flag (bool): A flag indicating whether to use the client certificate.
382
383 Returns:
384 bytes or None: The client cert source to be used by the client.
385 """
386 client_cert_source = None
387 if use_cert_flag:
388 if provided_cert_source:
389 client_cert_source = provided_cert_source
390 elif mtls.has_default_client_cert_source():
391 client_cert_source = mtls.default_client_cert_source()
392 return client_cert_source
393
394 @staticmethod
395 def _get_api_endpoint(
396 api_override, client_cert_source, universe_domain, use_mtls_endpoint
397 ):
398 """Return the API endpoint used by the client.
399
400 Args:
401 api_override (str): The API endpoint override. If specified, this is always
402 the return value of this function and the other arguments are not used.
403 client_cert_source (bytes): The client certificate source used by the client.
404 universe_domain (str): The universe domain used by the client.
405 use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters.
406 Possible values are "always", "auto", or "never".
407
408 Returns:
409 str: The API endpoint to be used by the client.
410 """
411 if api_override is not None:
412 api_endpoint = api_override
413 elif use_mtls_endpoint == "always" or (
414 use_mtls_endpoint == "auto" and client_cert_source
415 ):
416 _default_universe = ReportErrorsServiceClient._DEFAULT_UNIVERSE
417 if universe_domain != _default_universe:
418 raise MutualTLSChannelError(
419 f"mTLS is not supported in any universe other than {_default_universe}."
420 )
421 api_endpoint = ReportErrorsServiceClient.DEFAULT_MTLS_ENDPOINT
422 else:
423 api_endpoint = ReportErrorsServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format(
424 UNIVERSE_DOMAIN=universe_domain
425 )
426 return api_endpoint
427
428 @staticmethod
429 def _get_universe_domain(
430 client_universe_domain: Optional[str], universe_domain_env: Optional[str]
431 ) -> str:
432 """Return the universe domain used by the client.
433
434 Args:
435 client_universe_domain (Optional[str]): The universe domain configured via the client options.
436 universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable.
437
438 Returns:
439 str: The universe domain to be used by the client.
440
441 Raises:
442 ValueError: If the universe domain is an empty string.
443 """
444 universe_domain = ReportErrorsServiceClient._DEFAULT_UNIVERSE
445 if client_universe_domain is not None:
446 universe_domain = client_universe_domain
447 elif universe_domain_env is not None:
448 universe_domain = universe_domain_env
449 if len(universe_domain.strip()) == 0:
450 raise ValueError("Universe Domain cannot be an empty string.")
451 return universe_domain
452
453 def _validate_universe_domain(self):
454 """Validates client's and credentials' universe domains are consistent.
455
456 Returns:
457 bool: True iff the configured universe domain is valid.
458
459 Raises:
460 ValueError: If the configured universe domain is not valid.
461 """
462
463 # NOTE (b/349488459): universe validation is disabled until further notice.
464 return True
465
466 def _add_cred_info_for_auth_errors(
467 self, error: core_exceptions.GoogleAPICallError
468 ) -> None:
469 """Adds credential info string to error details for 401/403/404 errors.
470
471 Args:
472 error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info.
473 """
474 if error.code not in [
475 HTTPStatus.UNAUTHORIZED,
476 HTTPStatus.FORBIDDEN,
477 HTTPStatus.NOT_FOUND,
478 ]:
479 return
480
481 cred = self._transport._credentials
482
483 # get_cred_info is only available in google-auth>=2.35.0
484 if not hasattr(cred, "get_cred_info"):
485 return
486
487 # ignore the type check since pypy test fails when get_cred_info
488 # is not available
489 cred_info = cred.get_cred_info() # type: ignore
490 if cred_info and hasattr(error._details, "append"):
491 error._details.append(json.dumps(cred_info))
492
493 @property
494 def api_endpoint(self):
495 """Return the API endpoint used by the client instance.
496
497 Returns:
498 str: The API endpoint used by the client instance.
499 """
500 return self._api_endpoint
501
502 @property
503 def universe_domain(self) -> str:
504 """Return the universe domain used by the client instance.
505
506 Returns:
507 str: The universe domain used by the client instance.
508 """
509 return self._universe_domain
510
511 def __init__(
512 self,
513 *,
514 credentials: Optional[ga_credentials.Credentials] = None,
515 transport: Optional[
516 Union[
517 str,
518 ReportErrorsServiceTransport,
519 Callable[..., ReportErrorsServiceTransport],
520 ]
521 ] = None,
522 client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None,
523 client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
524 ) -> None:
525 """Instantiates the report errors service client.
526
527 Args:
528 credentials (Optional[google.auth.credentials.Credentials]): The
529 authorization credentials to attach to requests. These
530 credentials identify the application to the service; if none
531 are specified, the client will attempt to ascertain the
532 credentials from the environment.
533 transport (Optional[Union[str,ReportErrorsServiceTransport,Callable[..., ReportErrorsServiceTransport]]]):
534 The transport to use, or a Callable that constructs and returns a new transport.
535 If a Callable is given, it will be called with the same set of initialization
536 arguments as used in the ReportErrorsServiceTransport constructor.
537 If set to None, a transport is chosen automatically.
538 client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]):
539 Custom options for the client.
540
541 1. The ``api_endpoint`` property can be used to override the
542 default endpoint provided by the client when ``transport`` is
543 not explicitly provided. Only if this property is not set and
544 ``transport`` was not explicitly provided, the endpoint is
545 determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment
546 variable, which have one of the following values:
547 "always" (always use the default mTLS endpoint), "never" (always
548 use the default regular endpoint) and "auto" (auto-switch to the
549 default mTLS endpoint if client certificate is present; this is
550 the default value).
551
552 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable
553 is "true", then the ``client_cert_source`` property can be used
554 to provide a client certificate for mTLS transport. If
555 not provided, the default SSL client certificate will be used if
556 present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not
557 set, no client certificate will be used.
558
559 3. The ``universe_domain`` property can be used to override the
560 default "googleapis.com" universe. Note that the ``api_endpoint``
561 property still takes precedence; and ``universe_domain`` is
562 currently not supported for mTLS.
563
564 client_info (google.api_core.gapic_v1.client_info.ClientInfo):
565 The client info used to send a user-agent string along with
566 API requests. If ``None``, then default info will be used.
567 Generally, you only need to set this if you're developing
568 your own client library.
569
570 Raises:
571 google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport
572 creation failed for any reason.
573 """
574 self._client_options = client_options
575 if isinstance(self._client_options, dict):
576 self._client_options = client_options_lib.from_dict(self._client_options)
577 if self._client_options is None:
578 self._client_options = client_options_lib.ClientOptions()
579 self._client_options = cast(
580 client_options_lib.ClientOptions, self._client_options
581 )
582
583 universe_domain_opt = getattr(self._client_options, "universe_domain", None)
584
585 (
586 self._use_client_cert,
587 self._use_mtls_endpoint,
588 self._universe_domain_env,
589 ) = ReportErrorsServiceClient._read_environment_variables()
590 self._client_cert_source = ReportErrorsServiceClient._get_client_cert_source(
591 self._client_options.client_cert_source, self._use_client_cert
592 )
593 self._universe_domain = ReportErrorsServiceClient._get_universe_domain(
594 universe_domain_opt, self._universe_domain_env
595 )
596 self._api_endpoint = None # updated below, depending on `transport`
597
598 # Initialize the universe domain validation.
599 self._is_universe_domain_valid = False
600
601 if CLIENT_LOGGING_SUPPORTED: # pragma: NO COVER
602 # Setup logging.
603 client_logging.initialize_logging()
604
605 api_key_value = getattr(self._client_options, "api_key", None)
606 if api_key_value and credentials:
607 raise ValueError(
608 "client_options.api_key and credentials are mutually exclusive"
609 )
610
611 # Save or instantiate the transport.
612 # Ordinarily, we provide the transport, but allowing a custom transport
613 # instance provides an extensibility point for unusual situations.
614 transport_provided = isinstance(transport, ReportErrorsServiceTransport)
615 if transport_provided:
616 # transport is a ReportErrorsServiceTransport instance.
617 if credentials or self._client_options.credentials_file or api_key_value:
618 raise ValueError(
619 "When providing a transport instance, "
620 "provide its credentials directly."
621 )
622 if self._client_options.scopes:
623 raise ValueError(
624 "When providing a transport instance, provide its scopes "
625 "directly."
626 )
627 self._transport = cast(ReportErrorsServiceTransport, transport)
628 self._api_endpoint = self._transport.host
629
630 self._api_endpoint = (
631 self._api_endpoint
632 or ReportErrorsServiceClient._get_api_endpoint(
633 self._client_options.api_endpoint,
634 self._client_cert_source,
635 self._universe_domain,
636 self._use_mtls_endpoint,
637 )
638 )
639
640 if not transport_provided:
641 import google.auth._default # type: ignore
642
643 if api_key_value and hasattr(
644 google.auth._default, "get_api_key_credentials"
645 ):
646 credentials = google.auth._default.get_api_key_credentials(
647 api_key_value
648 )
649
650 transport_init: Union[
651 Type[ReportErrorsServiceTransport],
652 Callable[..., ReportErrorsServiceTransport],
653 ] = (
654 ReportErrorsServiceClient.get_transport_class(transport)
655 if isinstance(transport, str) or transport is None
656 else cast(Callable[..., ReportErrorsServiceTransport], transport)
657 )
658 # initialize with the provided callable or the passed in class
659 self._transport = transport_init(
660 credentials=credentials,
661 credentials_file=self._client_options.credentials_file,
662 host=self._api_endpoint,
663 scopes=self._client_options.scopes,
664 client_cert_source_for_mtls=self._client_cert_source,
665 quota_project_id=self._client_options.quota_project_id,
666 client_info=client_info,
667 always_use_jwt_access=True,
668 api_audience=self._client_options.api_audience,
669 )
670
671 if "async" not in str(self._transport):
672 if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
673 std_logging.DEBUG
674 ): # pragma: NO COVER
675 _LOGGER.debug(
676 "Created client `google.devtools.clouderrorreporting_v1beta1.ReportErrorsServiceClient`.",
677 extra={
678 "serviceName": "google.devtools.clouderrorreporting.v1beta1.ReportErrorsService",
679 "universeDomain": getattr(
680 self._transport._credentials, "universe_domain", ""
681 ),
682 "credentialsType": f"{type(self._transport._credentials).__module__}.{type(self._transport._credentials).__qualname__}",
683 "credentialsInfo": getattr(
684 self.transport._credentials, "get_cred_info", lambda: None
685 )(),
686 }
687 if hasattr(self._transport, "_credentials")
688 else {
689 "serviceName": "google.devtools.clouderrorreporting.v1beta1.ReportErrorsService",
690 "credentialsType": None,
691 },
692 )
693
694 def report_error_event(
695 self,
696 request: Optional[
697 Union[report_errors_service.ReportErrorEventRequest, dict]
698 ] = None,
699 *,
700 project_name: Optional[str] = None,
701 event: Optional[report_errors_service.ReportedErrorEvent] = None,
702 retry: OptionalRetry = gapic_v1.method.DEFAULT,
703 timeout: Union[float, object] = gapic_v1.method.DEFAULT,
704 metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
705 ) -> report_errors_service.ReportErrorEventResponse:
706 r"""Report an individual error event and record the event to a log.
707
708 This endpoint accepts **either** an OAuth token, **or** an `API
709 key <https://support.google.com/cloud/answer/6158862>`__ for
710 authentication. To use an API key, append it to the URL as the
711 value of a ``key`` parameter. For example:
712
713 ``POST https://clouderrorreporting.googleapis.com/v1beta1/{projectName}/events:report?key=123ABC456``
714
715 **Note:** [Error Reporting]
716 (https://cloud.google.com/error-reporting) is a service built on
717 Cloud Logging and can analyze log entries when all of the
718 following are true:
719
720 - Customer-managed encryption keys (CMEK) are disabled on the
721 log bucket.
722 - The log bucket satisfies one of the following:
723
724 - The log bucket is stored in the same project where the
725 logs originated.
726 - The logs were routed to a project, and then that project
727 stored those logs in a log bucket that it owns.
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_report_error_event():
741 # Create a client
742 client = errorreporting_v1beta1.ReportErrorsServiceClient()
743
744 # Initialize request argument(s)
745 event = errorreporting_v1beta1.ReportedErrorEvent()
746 event.message = "message_value"
747
748 request = errorreporting_v1beta1.ReportErrorEventRequest(
749 project_name="project_name_value",
750 event=event,
751 )
752
753 # Make the request
754 response = client.report_error_event(request=request)
755
756 # Handle the response
757 print(response)
758
759 Args:
760 request (Union[google.cloud.errorreporting_v1beta1.types.ReportErrorEventRequest, dict]):
761 The request object. A request for reporting an individual
762 error event.
763 project_name (str):
764 Required. The resource name of the Google Cloud Platform
765 project. Written as ``projects/{projectId}``, where
766 ``{projectId}`` is the `Google Cloud Platform project
767 ID <https://support.google.com/cloud/answer/6158840>`__.
768
769 Example: // ``projects/my-project-123``.
770
771 This corresponds to the ``project_name`` field
772 on the ``request`` instance; if ``request`` is provided, this
773 should not be set.
774 event (google.cloud.errorreporting_v1beta1.types.ReportedErrorEvent):
775 Required. The error event to be
776 reported.
777
778 This corresponds to the ``event`` field
779 on the ``request`` instance; if ``request`` is provided, this
780 should not be set.
781 retry (google.api_core.retry.Retry): Designation of what errors, if any,
782 should be retried.
783 timeout (float): The timeout for this request.
784 metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
785 sent along with the request as metadata. Normally, each value must be of type `str`,
786 but for metadata keys ending with the suffix `-bin`, the corresponding values must
787 be of type `bytes`.
788
789 Returns:
790 google.cloud.errorreporting_v1beta1.types.ReportErrorEventResponse:
791 Response for reporting an individual
792 error event. Data may be added to this
793 message in the future.
794
795 """
796 # Create or coerce a protobuf request object.
797 # - Quick check: If we got a request object, we should *not* have
798 # gotten any keyword arguments that map to the request.
799 flattened_params = [project_name, event]
800 has_flattened_params = (
801 len([param for param in flattened_params if param is not None]) > 0
802 )
803 if request is not None and has_flattened_params:
804 raise ValueError(
805 "If the `request` argument is set, then none of "
806 "the individual field arguments should be set."
807 )
808
809 # - Use the request object if provided (there's no risk of modifying the input as
810 # there are no flattened fields), or create one.
811 if not isinstance(request, report_errors_service.ReportErrorEventRequest):
812 request = report_errors_service.ReportErrorEventRequest(request)
813 # If we have keyword arguments corresponding to fields on the
814 # request, apply these.
815 if project_name is not None:
816 request.project_name = project_name
817 if event is not None:
818 request.event = event
819
820 # Wrap the RPC method; this adds retry and timeout information,
821 # and friendly error handling.
822 rpc = self._transport._wrapped_methods[self._transport.report_error_event]
823
824 # Certain fields should be provided within the metadata header;
825 # add these here.
826 metadata = tuple(metadata) + (
827 gapic_v1.routing_header.to_grpc_metadata(
828 (("project_name", request.project_name),)
829 ),
830 )
831
832 # Validate the universe domain.
833 self._validate_universe_domain()
834
835 # Send the request.
836 response = rpc(
837 request,
838 retry=retry,
839 timeout=timeout,
840 metadata=metadata,
841 )
842
843 # Done; return the response.
844 return response
845
846 def __enter__(self) -> "ReportErrorsServiceClient":
847 return self
848
849 def __exit__(self, type, value, traceback):
850 """Releases underlying transport's resources.
851
852 .. warning::
853 ONLY use as a context manager if the transport is NOT shared
854 with other clients! Exiting the with block will CLOSE the transport
855 and may cause errors in other clients!
856 """
857 self.transport.close()
858
859
860DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(
861 gapic_version=package_version.__version__
862)
863
864if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER
865 DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__
866
867__all__ = ("ReportErrorsServiceClient",)