Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/google/cloud/errorreporting_v1beta1/services/report_errors_service/client.py: 41%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

239 statements  

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",)