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

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

259 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 common 

65from google.cloud.errorreporting_v1beta1.types import error_group_service 

66from .transports.base import ErrorGroupServiceTransport, DEFAULT_CLIENT_INFO 

67from .transports.grpc import ErrorGroupServiceGrpcTransport 

68from .transports.grpc_asyncio import ErrorGroupServiceGrpcAsyncIOTransport 

69from .transports.rest import ErrorGroupServiceRestTransport 

70 

71 

72class ErrorGroupServiceClientMeta(type): 

73 """Metaclass for the ErrorGroupService client. 

74 

75 This provides class-level methods for building and retrieving 

76 support objects (e.g. transport) without polluting the client instance 

77 objects. 

78 """ 

79 

80 _transport_registry = ( 

81 OrderedDict() 

82 ) # type: Dict[str, Type[ErrorGroupServiceTransport]] 

83 _transport_registry["grpc"] = ErrorGroupServiceGrpcTransport 

84 _transport_registry["grpc_asyncio"] = ErrorGroupServiceGrpcAsyncIOTransport 

85 _transport_registry["rest"] = ErrorGroupServiceRestTransport 

86 

87 def get_transport_class( 

88 cls, 

89 label: Optional[str] = None, 

90 ) -> Type[ErrorGroupServiceTransport]: 

91 """Returns an appropriate transport class. 

92 

93 Args: 

94 label: The name of the desired transport. If none is 

95 provided, then the first transport in the registry is used. 

96 

97 Returns: 

98 The transport class to use. 

99 """ 

100 # If a specific transport is requested, return that one. 

101 if label: 

102 return cls._transport_registry[label] 

103 

104 # No transport is requested; return the default (that is, the first one 

105 # in the dictionary). 

106 return next(iter(cls._transport_registry.values())) 

107 

108 

109class ErrorGroupServiceClient(metaclass=ErrorGroupServiceClientMeta): 

110 """Service for retrieving and updating individual error groups.""" 

111 

112 @staticmethod 

113 def _get_default_mtls_endpoint(api_endpoint): 

114 """Converts api endpoint to mTLS endpoint. 

115 

116 Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to 

117 "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. 

118 Args: 

119 api_endpoint (Optional[str]): the api endpoint to convert. 

120 Returns: 

121 str: converted mTLS api endpoint. 

122 """ 

123 if not api_endpoint: 

124 return api_endpoint 

125 

126 mtls_endpoint_re = re.compile( 

127 r"(?P<name>[^.]+)(?P<mtls>\.mtls)?(?P<sandbox>\.sandbox)?(?P<googledomain>\.googleapis\.com)?" 

128 ) 

129 

130 m = mtls_endpoint_re.match(api_endpoint) 

131 name, mtls, sandbox, googledomain = m.groups() 

132 if mtls or not googledomain: 

133 return api_endpoint 

134 

135 if sandbox: 

136 return api_endpoint.replace( 

137 "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" 

138 ) 

139 

140 return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") 

141 

142 # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. 

143 DEFAULT_ENDPOINT = "clouderrorreporting.googleapis.com" 

144 DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore 

145 DEFAULT_ENDPOINT 

146 ) 

147 

148 _DEFAULT_ENDPOINT_TEMPLATE = "clouderrorreporting.{UNIVERSE_DOMAIN}" 

149 _DEFAULT_UNIVERSE = "googleapis.com" 

150 

151 @classmethod 

152 def from_service_account_info(cls, info: dict, *args, **kwargs): 

153 """Creates an instance of this client using the provided credentials 

154 info. 

155 

156 Args: 

157 info (dict): The service account private key info. 

158 args: Additional arguments to pass to the constructor. 

159 kwargs: Additional arguments to pass to the constructor. 

160 

161 Returns: 

162 ErrorGroupServiceClient: The constructed client. 

163 """ 

164 credentials = service_account.Credentials.from_service_account_info(info) 

165 kwargs["credentials"] = credentials 

166 return cls(*args, **kwargs) 

167 

168 @classmethod 

169 def from_service_account_file(cls, filename: str, *args, **kwargs): 

170 """Creates an instance of this client using the provided credentials 

171 file. 

172 

173 Args: 

174 filename (str): The path to the service account private key json 

175 file. 

176 args: Additional arguments to pass to the constructor. 

177 kwargs: Additional arguments to pass to the constructor. 

178 

179 Returns: 

180 ErrorGroupServiceClient: The constructed client. 

181 """ 

182 credentials = service_account.Credentials.from_service_account_file(filename) 

183 kwargs["credentials"] = credentials 

184 return cls(*args, **kwargs) 

185 

186 from_service_account_json = from_service_account_file 

187 

188 @property 

189 def transport(self) -> ErrorGroupServiceTransport: 

190 """Returns the transport used by the client instance. 

191 

192 Returns: 

193 ErrorGroupServiceTransport: The transport used by the client 

194 instance. 

195 """ 

196 return self._transport 

197 

198 @staticmethod 

199 def error_group_path( 

200 project: str, 

201 group: str, 

202 ) -> str: 

203 """Returns a fully-qualified error_group string.""" 

204 return "projects/{project}/groups/{group}".format( 

205 project=project, 

206 group=group, 

207 ) 

208 

209 @staticmethod 

210 def parse_error_group_path(path: str) -> Dict[str, str]: 

211 """Parses a error_group path into its component segments.""" 

212 m = re.match(r"^projects/(?P<project>.+?)/groups/(?P<group>.+?)$", path) 

213 return m.groupdict() if m else {} 

214 

215 @staticmethod 

216 def common_billing_account_path( 

217 billing_account: str, 

218 ) -> str: 

219 """Returns a fully-qualified billing_account string.""" 

220 return "billingAccounts/{billing_account}".format( 

221 billing_account=billing_account, 

222 ) 

223 

224 @staticmethod 

225 def parse_common_billing_account_path(path: str) -> Dict[str, str]: 

226 """Parse a billing_account path into its component segments.""" 

227 m = re.match(r"^billingAccounts/(?P<billing_account>.+?)$", path) 

228 return m.groupdict() if m else {} 

229 

230 @staticmethod 

231 def common_folder_path( 

232 folder: str, 

233 ) -> str: 

234 """Returns a fully-qualified folder string.""" 

235 return "folders/{folder}".format( 

236 folder=folder, 

237 ) 

238 

239 @staticmethod 

240 def parse_common_folder_path(path: str) -> Dict[str, str]: 

241 """Parse a folder path into its component segments.""" 

242 m = re.match(r"^folders/(?P<folder>.+?)$", path) 

243 return m.groupdict() if m else {} 

244 

245 @staticmethod 

246 def common_organization_path( 

247 organization: str, 

248 ) -> str: 

249 """Returns a fully-qualified organization string.""" 

250 return "organizations/{organization}".format( 

251 organization=organization, 

252 ) 

253 

254 @staticmethod 

255 def parse_common_organization_path(path: str) -> Dict[str, str]: 

256 """Parse a organization path into its component segments.""" 

257 m = re.match(r"^organizations/(?P<organization>.+?)$", path) 

258 return m.groupdict() if m else {} 

259 

260 @staticmethod 

261 def common_project_path( 

262 project: str, 

263 ) -> str: 

264 """Returns a fully-qualified project string.""" 

265 return "projects/{project}".format( 

266 project=project, 

267 ) 

268 

269 @staticmethod 

270 def parse_common_project_path(path: str) -> Dict[str, str]: 

271 """Parse a project path into its component segments.""" 

272 m = re.match(r"^projects/(?P<project>.+?)$", path) 

273 return m.groupdict() if m else {} 

274 

275 @staticmethod 

276 def common_location_path( 

277 project: str, 

278 location: str, 

279 ) -> str: 

280 """Returns a fully-qualified location string.""" 

281 return "projects/{project}/locations/{location}".format( 

282 project=project, 

283 location=location, 

284 ) 

285 

286 @staticmethod 

287 def parse_common_location_path(path: str) -> Dict[str, str]: 

288 """Parse a location path into its component segments.""" 

289 m = re.match(r"^projects/(?P<project>.+?)/locations/(?P<location>.+?)$", path) 

290 return m.groupdict() if m else {} 

291 

292 @classmethod 

293 def get_mtls_endpoint_and_cert_source( 

294 cls, client_options: Optional[client_options_lib.ClientOptions] = None 

295 ): 

296 """Deprecated. Return the API endpoint and client cert source for mutual TLS. 

297 

298 The client cert source is determined in the following order: 

299 (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the 

300 client cert source is None. 

301 (2) if `client_options.client_cert_source` is provided, use the provided one; if the 

302 default client cert source exists, use the default one; otherwise the client cert 

303 source is None. 

304 

305 The API endpoint is determined in the following order: 

306 (1) if `client_options.api_endpoint` if provided, use the provided one. 

307 (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the 

308 default mTLS endpoint; if the environment variable is "never", use the default API 

309 endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise 

310 use the default API endpoint. 

311 

312 More details can be found at https://google.aip.dev/auth/4114. 

313 

314 Args: 

315 client_options (google.api_core.client_options.ClientOptions): Custom options for the 

316 client. Only the `api_endpoint` and `client_cert_source` properties may be used 

317 in this method. 

318 

319 Returns: 

320 Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the 

321 client cert source to use. 

322 

323 Raises: 

324 google.auth.exceptions.MutualTLSChannelError: If any errors happen. 

325 """ 

326 

327 warnings.warn( 

328 "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", 

329 DeprecationWarning, 

330 ) 

331 if client_options is None: 

332 client_options = client_options_lib.ClientOptions() 

333 use_client_cert = os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") 

334 use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") 

335 if use_client_cert not in ("true", "false"): 

336 raise ValueError( 

337 "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" 

338 ) 

339 if use_mtls_endpoint not in ("auto", "never", "always"): 

340 raise MutualTLSChannelError( 

341 "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" 

342 ) 

343 

344 # Figure out the client cert source to use. 

345 client_cert_source = None 

346 if use_client_cert == "true": 

347 if client_options.client_cert_source: 

348 client_cert_source = client_options.client_cert_source 

349 elif mtls.has_default_client_cert_source(): 

350 client_cert_source = mtls.default_client_cert_source() 

351 

352 # Figure out which api endpoint to use. 

353 if client_options.api_endpoint is not None: 

354 api_endpoint = client_options.api_endpoint 

355 elif use_mtls_endpoint == "always" or ( 

356 use_mtls_endpoint == "auto" and client_cert_source 

357 ): 

358 api_endpoint = cls.DEFAULT_MTLS_ENDPOINT 

359 else: 

360 api_endpoint = cls.DEFAULT_ENDPOINT 

361 

362 return api_endpoint, client_cert_source 

363 

364 @staticmethod 

365 def _read_environment_variables(): 

366 """Returns the environment variables used by the client. 

367 

368 Returns: 

369 Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, 

370 GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. 

371 

372 Raises: 

373 ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not 

374 any of ["true", "false"]. 

375 google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT 

376 is not any of ["auto", "never", "always"]. 

377 """ 

378 use_client_cert = os.getenv( 

379 "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" 

380 ).lower() 

381 use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto").lower() 

382 universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") 

383 if use_client_cert not in ("true", "false"): 

384 raise ValueError( 

385 "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" 

386 ) 

387 if use_mtls_endpoint not in ("auto", "never", "always"): 

388 raise MutualTLSChannelError( 

389 "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" 

390 ) 

391 return use_client_cert == "true", use_mtls_endpoint, universe_domain_env 

392 

393 @staticmethod 

394 def _get_client_cert_source(provided_cert_source, use_cert_flag): 

395 """Return the client cert source to be used by the client. 

396 

397 Args: 

398 provided_cert_source (bytes): The client certificate source provided. 

399 use_cert_flag (bool): A flag indicating whether to use the client certificate. 

400 

401 Returns: 

402 bytes or None: The client cert source to be used by the client. 

403 """ 

404 client_cert_source = None 

405 if use_cert_flag: 

406 if provided_cert_source: 

407 client_cert_source = provided_cert_source 

408 elif mtls.has_default_client_cert_source(): 

409 client_cert_source = mtls.default_client_cert_source() 

410 return client_cert_source 

411 

412 @staticmethod 

413 def _get_api_endpoint( 

414 api_override, client_cert_source, universe_domain, use_mtls_endpoint 

415 ): 

416 """Return the API endpoint used by the client. 

417 

418 Args: 

419 api_override (str): The API endpoint override. If specified, this is always 

420 the return value of this function and the other arguments are not used. 

421 client_cert_source (bytes): The client certificate source used by the client. 

422 universe_domain (str): The universe domain used by the client. 

423 use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. 

424 Possible values are "always", "auto", or "never". 

425 

426 Returns: 

427 str: The API endpoint to be used by the client. 

428 """ 

429 if api_override is not None: 

430 api_endpoint = api_override 

431 elif use_mtls_endpoint == "always" or ( 

432 use_mtls_endpoint == "auto" and client_cert_source 

433 ): 

434 _default_universe = ErrorGroupServiceClient._DEFAULT_UNIVERSE 

435 if universe_domain != _default_universe: 

436 raise MutualTLSChannelError( 

437 f"mTLS is not supported in any universe other than {_default_universe}." 

438 ) 

439 api_endpoint = ErrorGroupServiceClient.DEFAULT_MTLS_ENDPOINT 

440 else: 

441 api_endpoint = ErrorGroupServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( 

442 UNIVERSE_DOMAIN=universe_domain 

443 ) 

444 return api_endpoint 

445 

446 @staticmethod 

447 def _get_universe_domain( 

448 client_universe_domain: Optional[str], universe_domain_env: Optional[str] 

449 ) -> str: 

450 """Return the universe domain used by the client. 

451 

452 Args: 

453 client_universe_domain (Optional[str]): The universe domain configured via the client options. 

454 universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. 

455 

456 Returns: 

457 str: The universe domain to be used by the client. 

458 

459 Raises: 

460 ValueError: If the universe domain is an empty string. 

461 """ 

462 universe_domain = ErrorGroupServiceClient._DEFAULT_UNIVERSE 

463 if client_universe_domain is not None: 

464 universe_domain = client_universe_domain 

465 elif universe_domain_env is not None: 

466 universe_domain = universe_domain_env 

467 if len(universe_domain.strip()) == 0: 

468 raise ValueError("Universe Domain cannot be an empty string.") 

469 return universe_domain 

470 

471 def _validate_universe_domain(self): 

472 """Validates client's and credentials' universe domains are consistent. 

473 

474 Returns: 

475 bool: True iff the configured universe domain is valid. 

476 

477 Raises: 

478 ValueError: If the configured universe domain is not valid. 

479 """ 

480 

481 # NOTE (b/349488459): universe validation is disabled until further notice. 

482 return True 

483 

484 def _add_cred_info_for_auth_errors( 

485 self, error: core_exceptions.GoogleAPICallError 

486 ) -> None: 

487 """Adds credential info string to error details for 401/403/404 errors. 

488 

489 Args: 

490 error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. 

491 """ 

492 if error.code not in [ 

493 HTTPStatus.UNAUTHORIZED, 

494 HTTPStatus.FORBIDDEN, 

495 HTTPStatus.NOT_FOUND, 

496 ]: 

497 return 

498 

499 cred = self._transport._credentials 

500 

501 # get_cred_info is only available in google-auth>=2.35.0 

502 if not hasattr(cred, "get_cred_info"): 

503 return 

504 

505 # ignore the type check since pypy test fails when get_cred_info 

506 # is not available 

507 cred_info = cred.get_cred_info() # type: ignore 

508 if cred_info and hasattr(error._details, "append"): 

509 error._details.append(json.dumps(cred_info)) 

510 

511 @property 

512 def api_endpoint(self): 

513 """Return the API endpoint used by the client instance. 

514 

515 Returns: 

516 str: The API endpoint used by the client instance. 

517 """ 

518 return self._api_endpoint 

519 

520 @property 

521 def universe_domain(self) -> str: 

522 """Return the universe domain used by the client instance. 

523 

524 Returns: 

525 str: The universe domain used by the client instance. 

526 """ 

527 return self._universe_domain 

528 

529 def __init__( 

530 self, 

531 *, 

532 credentials: Optional[ga_credentials.Credentials] = None, 

533 transport: Optional[ 

534 Union[ 

535 str, 

536 ErrorGroupServiceTransport, 

537 Callable[..., ErrorGroupServiceTransport], 

538 ] 

539 ] = None, 

540 client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None, 

541 client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, 

542 ) -> None: 

543 """Instantiates the error group service client. 

544 

545 Args: 

546 credentials (Optional[google.auth.credentials.Credentials]): The 

547 authorization credentials to attach to requests. These 

548 credentials identify the application to the service; if none 

549 are specified, the client will attempt to ascertain the 

550 credentials from the environment. 

551 transport (Optional[Union[str,ErrorGroupServiceTransport,Callable[..., ErrorGroupServiceTransport]]]): 

552 The transport to use, or a Callable that constructs and returns a new transport. 

553 If a Callable is given, it will be called with the same set of initialization 

554 arguments as used in the ErrorGroupServiceTransport constructor. 

555 If set to None, a transport is chosen automatically. 

556 client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): 

557 Custom options for the client. 

558 

559 1. The ``api_endpoint`` property can be used to override the 

560 default endpoint provided by the client when ``transport`` is 

561 not explicitly provided. Only if this property is not set and 

562 ``transport`` was not explicitly provided, the endpoint is 

563 determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment 

564 variable, which have one of the following values: 

565 "always" (always use the default mTLS endpoint), "never" (always 

566 use the default regular endpoint) and "auto" (auto-switch to the 

567 default mTLS endpoint if client certificate is present; this is 

568 the default value). 

569 

570 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable 

571 is "true", then the ``client_cert_source`` property can be used 

572 to provide a client certificate for mTLS transport. If 

573 not provided, the default SSL client certificate will be used if 

574 present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not 

575 set, no client certificate will be used. 

576 

577 3. The ``universe_domain`` property can be used to override the 

578 default "googleapis.com" universe. Note that the ``api_endpoint`` 

579 property still takes precedence; and ``universe_domain`` is 

580 currently not supported for mTLS. 

581 

582 client_info (google.api_core.gapic_v1.client_info.ClientInfo): 

583 The client info used to send a user-agent string along with 

584 API requests. If ``None``, then default info will be used. 

585 Generally, you only need to set this if you're developing 

586 your own client library. 

587 

588 Raises: 

589 google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport 

590 creation failed for any reason. 

591 """ 

592 self._client_options = client_options 

593 if isinstance(self._client_options, dict): 

594 self._client_options = client_options_lib.from_dict(self._client_options) 

595 if self._client_options is None: 

596 self._client_options = client_options_lib.ClientOptions() 

597 self._client_options = cast( 

598 client_options_lib.ClientOptions, self._client_options 

599 ) 

600 

601 universe_domain_opt = getattr(self._client_options, "universe_domain", None) 

602 

603 ( 

604 self._use_client_cert, 

605 self._use_mtls_endpoint, 

606 self._universe_domain_env, 

607 ) = ErrorGroupServiceClient._read_environment_variables() 

608 self._client_cert_source = ErrorGroupServiceClient._get_client_cert_source( 

609 self._client_options.client_cert_source, self._use_client_cert 

610 ) 

611 self._universe_domain = ErrorGroupServiceClient._get_universe_domain( 

612 universe_domain_opt, self._universe_domain_env 

613 ) 

614 self._api_endpoint = None # updated below, depending on `transport` 

615 

616 # Initialize the universe domain validation. 

617 self._is_universe_domain_valid = False 

618 

619 if CLIENT_LOGGING_SUPPORTED: # pragma: NO COVER 

620 # Setup logging. 

621 client_logging.initialize_logging() 

622 

623 api_key_value = getattr(self._client_options, "api_key", None) 

624 if api_key_value and credentials: 

625 raise ValueError( 

626 "client_options.api_key and credentials are mutually exclusive" 

627 ) 

628 

629 # Save or instantiate the transport. 

630 # Ordinarily, we provide the transport, but allowing a custom transport 

631 # instance provides an extensibility point for unusual situations. 

632 transport_provided = isinstance(transport, ErrorGroupServiceTransport) 

633 if transport_provided: 

634 # transport is a ErrorGroupServiceTransport instance. 

635 if credentials or self._client_options.credentials_file or api_key_value: 

636 raise ValueError( 

637 "When providing a transport instance, " 

638 "provide its credentials directly." 

639 ) 

640 if self._client_options.scopes: 

641 raise ValueError( 

642 "When providing a transport instance, provide its scopes " 

643 "directly." 

644 ) 

645 self._transport = cast(ErrorGroupServiceTransport, transport) 

646 self._api_endpoint = self._transport.host 

647 

648 self._api_endpoint = ( 

649 self._api_endpoint 

650 or ErrorGroupServiceClient._get_api_endpoint( 

651 self._client_options.api_endpoint, 

652 self._client_cert_source, 

653 self._universe_domain, 

654 self._use_mtls_endpoint, 

655 ) 

656 ) 

657 

658 if not transport_provided: 

659 import google.auth._default # type: ignore 

660 

661 if api_key_value and hasattr( 

662 google.auth._default, "get_api_key_credentials" 

663 ): 

664 credentials = google.auth._default.get_api_key_credentials( 

665 api_key_value 

666 ) 

667 

668 transport_init: Union[ 

669 Type[ErrorGroupServiceTransport], 

670 Callable[..., ErrorGroupServiceTransport], 

671 ] = ( 

672 ErrorGroupServiceClient.get_transport_class(transport) 

673 if isinstance(transport, str) or transport is None 

674 else cast(Callable[..., ErrorGroupServiceTransport], transport) 

675 ) 

676 # initialize with the provided callable or the passed in class 

677 self._transport = transport_init( 

678 credentials=credentials, 

679 credentials_file=self._client_options.credentials_file, 

680 host=self._api_endpoint, 

681 scopes=self._client_options.scopes, 

682 client_cert_source_for_mtls=self._client_cert_source, 

683 quota_project_id=self._client_options.quota_project_id, 

684 client_info=client_info, 

685 always_use_jwt_access=True, 

686 api_audience=self._client_options.api_audience, 

687 ) 

688 

689 if "async" not in str(self._transport): 

690 if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( 

691 std_logging.DEBUG 

692 ): # pragma: NO COVER 

693 _LOGGER.debug( 

694 "Created client `google.devtools.clouderrorreporting_v1beta1.ErrorGroupServiceClient`.", 

695 extra={ 

696 "serviceName": "google.devtools.clouderrorreporting.v1beta1.ErrorGroupService", 

697 "universeDomain": getattr( 

698 self._transport._credentials, "universe_domain", "" 

699 ), 

700 "credentialsType": f"{type(self._transport._credentials).__module__}.{type(self._transport._credentials).__qualname__}", 

701 "credentialsInfo": getattr( 

702 self.transport._credentials, "get_cred_info", lambda: None 

703 )(), 

704 } 

705 if hasattr(self._transport, "_credentials") 

706 else { 

707 "serviceName": "google.devtools.clouderrorreporting.v1beta1.ErrorGroupService", 

708 "credentialsType": None, 

709 }, 

710 ) 

711 

712 def get_group( 

713 self, 

714 request: Optional[Union[error_group_service.GetGroupRequest, dict]] = None, 

715 *, 

716 group_name: Optional[str] = None, 

717 retry: OptionalRetry = gapic_v1.method.DEFAULT, 

718 timeout: Union[float, object] = gapic_v1.method.DEFAULT, 

719 metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), 

720 ) -> common.ErrorGroup: 

721 r"""Get the specified group. 

722 

723 .. code-block:: python 

724 

725 # This snippet has been automatically generated and should be regarded as a 

726 # code template only. 

727 # It will require modifications to work: 

728 # - It may require correct/in-range values for request initialization. 

729 # - It may require specifying regional endpoints when creating the service 

730 # client as shown in: 

731 # https://googleapis.dev/python/google-api-core/latest/client_options.html 

732 from google.cloud import errorreporting_v1beta1 

733 

734 def sample_get_group(): 

735 # Create a client 

736 client = errorreporting_v1beta1.ErrorGroupServiceClient() 

737 

738 # Initialize request argument(s) 

739 request = errorreporting_v1beta1.GetGroupRequest( 

740 group_name="group_name_value", 

741 ) 

742 

743 # Make the request 

744 response = client.get_group(request=request) 

745 

746 # Handle the response 

747 print(response) 

748 

749 Args: 

750 request (Union[google.cloud.errorreporting_v1beta1.types.GetGroupRequest, dict]): 

751 The request object. A request to return an individual 

752 group. 

753 group_name (str): 

754 Required. The group resource name. Written as either 

755 ``projects/{projectID}/groups/{group_id}`` or 

756 ``projects/{projectID}/locations/{location}/groups/{group_id}``. 

757 Call [groupStats.list] 

758 [google.devtools.clouderrorreporting.v1beta1.ErrorStatsService.ListGroupStats] 

759 to return a list of groups belonging to this project. 

760 

761 Examples: ``projects/my-project-123/groups/my-group``, 

762 ``projects/my-project-123/locations/global/groups/my-group`` 

763 

764 In the group resource name, the ``group_id`` is a unique 

765 identifier for a particular error group. The identifier 

766 is derived from key parts of the error-log content and 

767 is treated as Service Data. For information about how 

768 Service Data is handled, see `Google Cloud Privacy 

769 Notice <https://cloud.google.com/terms/cloud-privacy-notice>`__. 

770 

771 For a list of supported locations, see `Supported 

772 Regions <https://cloud.google.com/logging/docs/region-support>`__. 

773 ``global`` is the default when unspecified. 

774 

775 This corresponds to the ``group_name`` field 

776 on the ``request`` instance; if ``request`` is provided, this 

777 should not be set. 

778 retry (google.api_core.retry.Retry): Designation of what errors, if any, 

779 should be retried. 

780 timeout (float): The timeout for this request. 

781 metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be 

782 sent along with the request as metadata. Normally, each value must be of type `str`, 

783 but for metadata keys ending with the suffix `-bin`, the corresponding values must 

784 be of type `bytes`. 

785 

786 Returns: 

787 google.cloud.errorreporting_v1beta1.types.ErrorGroup: 

788 Description of a group of similar 

789 error events. 

790 

791 """ 

792 # Create or coerce a protobuf request object. 

793 # - Quick check: If we got a request object, we should *not* have 

794 # gotten any keyword arguments that map to the request. 

795 flattened_params = [group_name] 

796 has_flattened_params = ( 

797 len([param for param in flattened_params if param is not None]) > 0 

798 ) 

799 if request is not None and has_flattened_params: 

800 raise ValueError( 

801 "If the `request` argument is set, then none of " 

802 "the individual field arguments should be set." 

803 ) 

804 

805 # - Use the request object if provided (there's no risk of modifying the input as 

806 # there are no flattened fields), or create one. 

807 if not isinstance(request, error_group_service.GetGroupRequest): 

808 request = error_group_service.GetGroupRequest(request) 

809 # If we have keyword arguments corresponding to fields on the 

810 # request, apply these. 

811 if group_name is not None: 

812 request.group_name = group_name 

813 

814 # Wrap the RPC method; this adds retry and timeout information, 

815 # and friendly error handling. 

816 rpc = self._transport._wrapped_methods[self._transport.get_group] 

817 

818 # Certain fields should be provided within the metadata header; 

819 # add these here. 

820 metadata = tuple(metadata) + ( 

821 gapic_v1.routing_header.to_grpc_metadata( 

822 (("group_name", request.group_name),) 

823 ), 

824 ) 

825 

826 # Validate the universe domain. 

827 self._validate_universe_domain() 

828 

829 # Send the request. 

830 response = rpc( 

831 request, 

832 retry=retry, 

833 timeout=timeout, 

834 metadata=metadata, 

835 ) 

836 

837 # Done; return the response. 

838 return response 

839 

840 def update_group( 

841 self, 

842 request: Optional[Union[error_group_service.UpdateGroupRequest, dict]] = None, 

843 *, 

844 group: Optional[common.ErrorGroup] = None, 

845 retry: OptionalRetry = gapic_v1.method.DEFAULT, 

846 timeout: Union[float, object] = gapic_v1.method.DEFAULT, 

847 metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), 

848 ) -> common.ErrorGroup: 

849 r"""Replace the data for the specified group. 

850 Fails if the group does not exist. 

851 

852 .. code-block:: python 

853 

854 # This snippet has been automatically generated and should be regarded as a 

855 # code template only. 

856 # It will require modifications to work: 

857 # - It may require correct/in-range values for request initialization. 

858 # - It may require specifying regional endpoints when creating the service 

859 # client as shown in: 

860 # https://googleapis.dev/python/google-api-core/latest/client_options.html 

861 from google.cloud import errorreporting_v1beta1 

862 

863 def sample_update_group(): 

864 # Create a client 

865 client = errorreporting_v1beta1.ErrorGroupServiceClient() 

866 

867 # Initialize request argument(s) 

868 request = errorreporting_v1beta1.UpdateGroupRequest( 

869 ) 

870 

871 # Make the request 

872 response = client.update_group(request=request) 

873 

874 # Handle the response 

875 print(response) 

876 

877 Args: 

878 request (Union[google.cloud.errorreporting_v1beta1.types.UpdateGroupRequest, dict]): 

879 The request object. A request to replace the existing 

880 data for the given group. 

881 group (google.cloud.errorreporting_v1beta1.types.ErrorGroup): 

882 Required. The group which replaces 

883 the resource on the server. 

884 

885 This corresponds to the ``group`` field 

886 on the ``request`` instance; if ``request`` is provided, this 

887 should not be set. 

888 retry (google.api_core.retry.Retry): Designation of what errors, if any, 

889 should be retried. 

890 timeout (float): The timeout for this request. 

891 metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be 

892 sent along with the request as metadata. Normally, each value must be of type `str`, 

893 but for metadata keys ending with the suffix `-bin`, the corresponding values must 

894 be of type `bytes`. 

895 

896 Returns: 

897 google.cloud.errorreporting_v1beta1.types.ErrorGroup: 

898 Description of a group of similar 

899 error events. 

900 

901 """ 

902 # Create or coerce a protobuf request object. 

903 # - Quick check: If we got a request object, we should *not* have 

904 # gotten any keyword arguments that map to the request. 

905 flattened_params = [group] 

906 has_flattened_params = ( 

907 len([param for param in flattened_params if param is not None]) > 0 

908 ) 

909 if request is not None and has_flattened_params: 

910 raise ValueError( 

911 "If the `request` argument is set, then none of " 

912 "the individual field arguments should be set." 

913 ) 

914 

915 # - Use the request object if provided (there's no risk of modifying the input as 

916 # there are no flattened fields), or create one. 

917 if not isinstance(request, error_group_service.UpdateGroupRequest): 

918 request = error_group_service.UpdateGroupRequest(request) 

919 # If we have keyword arguments corresponding to fields on the 

920 # request, apply these. 

921 if group is not None: 

922 request.group = group 

923 

924 # Wrap the RPC method; this adds retry and timeout information, 

925 # and friendly error handling. 

926 rpc = self._transport._wrapped_methods[self._transport.update_group] 

927 

928 # Certain fields should be provided within the metadata header; 

929 # add these here. 

930 metadata = tuple(metadata) + ( 

931 gapic_v1.routing_header.to_grpc_metadata( 

932 (("group.name", request.group.name),) 

933 ), 

934 ) 

935 

936 # Validate the universe domain. 

937 self._validate_universe_domain() 

938 

939 # Send the request. 

940 response = rpc( 

941 request, 

942 retry=retry, 

943 timeout=timeout, 

944 metadata=metadata, 

945 ) 

946 

947 # Done; return the response. 

948 return response 

949 

950 def __enter__(self) -> "ErrorGroupServiceClient": 

951 return self 

952 

953 def __exit__(self, type, value, traceback): 

954 """Releases underlying transport's resources. 

955 

956 .. warning:: 

957 ONLY use as a context manager if the transport is NOT shared 

958 with other clients! Exiting the with block will CLOSE the transport 

959 and may cause errors in other clients! 

960 """ 

961 self.transport.close() 

962 

963 

964DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( 

965 gapic_version=package_version.__version__ 

966) 

967 

968if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER 

969 DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ 

970 

971__all__ = ("ErrorGroupServiceClient",)