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

157 statements  

« prev     ^ index     » next       coverage.py v7.3.2, created at 2023-12-08 06:45 +0000

1# -*- coding: utf-8 -*- 

2# Copyright 2023 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 

17import os 

18import re 

19from typing import ( 

20 Dict, 

21 Mapping, 

22 MutableMapping, 

23 MutableSequence, 

24 Optional, 

25 Sequence, 

26 Tuple, 

27 Type, 

28 Union, 

29 cast, 

30) 

31 

32from google.cloud.errorreporting_v1beta1 import gapic_version as package_version 

33 

34from google.api_core import client_options as client_options_lib 

35from google.api_core import exceptions as core_exceptions 

36from google.api_core import gapic_v1 

37from google.api_core import retry as retries 

38from google.auth import credentials as ga_credentials # type: ignore 

39from google.auth.transport import mtls # type: ignore 

40from google.auth.transport.grpc import SslCredentials # type: ignore 

41from google.auth.exceptions import MutualTLSChannelError # type: ignore 

42from google.oauth2 import service_account # type: ignore 

43 

44try: 

45 OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] 

46except AttributeError: # pragma: NO COVER 

47 OptionalRetry = Union[retries.Retry, object] # type: ignore 

48 

49from google.cloud.errorreporting_v1beta1.types import report_errors_service 

50from .transports.base import ReportErrorsServiceTransport, DEFAULT_CLIENT_INFO 

51from .transports.grpc import ReportErrorsServiceGrpcTransport 

52from .transports.grpc_asyncio import ReportErrorsServiceGrpcAsyncIOTransport 

53from .transports.rest import ReportErrorsServiceRestTransport 

54 

55 

56class ReportErrorsServiceClientMeta(type): 

57 """Metaclass for the ReportErrorsService client. 

58 

59 This provides class-level methods for building and retrieving 

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

61 objects. 

62 """ 

63 

64 _transport_registry = ( 

65 OrderedDict() 

66 ) # type: Dict[str, Type[ReportErrorsServiceTransport]] 

67 _transport_registry["grpc"] = ReportErrorsServiceGrpcTransport 

68 _transport_registry["grpc_asyncio"] = ReportErrorsServiceGrpcAsyncIOTransport 

69 _transport_registry["rest"] = ReportErrorsServiceRestTransport 

70 

71 def get_transport_class( 

72 cls, 

73 label: Optional[str] = None, 

74 ) -> Type[ReportErrorsServiceTransport]: 

75 """Returns an appropriate transport class. 

76 

77 Args: 

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

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

80 

81 Returns: 

82 The transport class to use. 

83 """ 

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

85 if label: 

86 return cls._transport_registry[label] 

87 

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

89 # in the dictionary). 

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

91 

92 

93class ReportErrorsServiceClient(metaclass=ReportErrorsServiceClientMeta): 

94 """An API for reporting error events.""" 

95 

96 @staticmethod 

97 def _get_default_mtls_endpoint(api_endpoint): 

98 """Converts api endpoint to mTLS endpoint. 

99 

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

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

102 Args: 

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

104 Returns: 

105 str: converted mTLS api endpoint. 

106 """ 

107 if not api_endpoint: 

108 return api_endpoint 

109 

110 mtls_endpoint_re = re.compile( 

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

112 ) 

113 

114 m = mtls_endpoint_re.match(api_endpoint) 

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

116 if mtls or not googledomain: 

117 return api_endpoint 

118 

119 if sandbox: 

120 return api_endpoint.replace( 

121 "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" 

122 ) 

123 

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

125 

126 DEFAULT_ENDPOINT = "clouderrorreporting.googleapis.com" 

127 DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore 

128 DEFAULT_ENDPOINT 

129 ) 

130 

131 @classmethod 

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

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

134 info. 

135 

136 Args: 

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

138 args: Additional arguments to pass to the constructor. 

139 kwargs: Additional arguments to pass to the constructor. 

140 

141 Returns: 

142 ReportErrorsServiceClient: The constructed client. 

143 """ 

144 credentials = service_account.Credentials.from_service_account_info(info) 

145 kwargs["credentials"] = credentials 

146 return cls(*args, **kwargs) 

147 

148 @classmethod 

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

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

151 file. 

152 

153 Args: 

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

155 file. 

156 args: Additional arguments to pass to the constructor. 

157 kwargs: Additional arguments to pass to the constructor. 

158 

159 Returns: 

160 ReportErrorsServiceClient: The constructed client. 

161 """ 

162 credentials = service_account.Credentials.from_service_account_file(filename) 

163 kwargs["credentials"] = credentials 

164 return cls(*args, **kwargs) 

165 

166 from_service_account_json = from_service_account_file 

167 

168 @property 

169 def transport(self) -> ReportErrorsServiceTransport: 

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

171 

172 Returns: 

173 ReportErrorsServiceTransport: The transport used by the client 

174 instance. 

175 """ 

176 return self._transport 

177 

178 @staticmethod 

179 def common_billing_account_path( 

180 billing_account: str, 

181 ) -> str: 

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

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

184 billing_account=billing_account, 

185 ) 

186 

187 @staticmethod 

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

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

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

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

192 

193 @staticmethod 

194 def common_folder_path( 

195 folder: str, 

196 ) -> str: 

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

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

199 folder=folder, 

200 ) 

201 

202 @staticmethod 

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

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

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

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

207 

208 @staticmethod 

209 def common_organization_path( 

210 organization: str, 

211 ) -> str: 

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

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

214 organization=organization, 

215 ) 

216 

217 @staticmethod 

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

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

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

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

222 

223 @staticmethod 

224 def common_project_path( 

225 project: str, 

226 ) -> str: 

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

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

229 project=project, 

230 ) 

231 

232 @staticmethod 

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

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

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

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

237 

238 @staticmethod 

239 def common_location_path( 

240 project: str, 

241 location: str, 

242 ) -> str: 

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

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

245 project=project, 

246 location=location, 

247 ) 

248 

249 @staticmethod 

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

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

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

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

254 

255 @classmethod 

256 def get_mtls_endpoint_and_cert_source( 

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

258 ): 

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

260 

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

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

263 client cert source is None. 

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

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

266 source is None. 

267 

268 The API endpoint is determined in the following order: 

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

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

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

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

273 use the default API endpoint. 

274 

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

276 

277 Args: 

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

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

280 in this method. 

281 

282 Returns: 

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

284 client cert source to use. 

285 

286 Raises: 

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

288 """ 

289 if client_options is None: 

290 client_options = client_options_lib.ClientOptions() 

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

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

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

294 raise ValueError( 

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

296 ) 

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

298 raise MutualTLSChannelError( 

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

300 ) 

301 

302 # Figure out the client cert source to use. 

303 client_cert_source = None 

304 if use_client_cert == "true": 

305 if client_options.client_cert_source: 

306 client_cert_source = client_options.client_cert_source 

307 elif mtls.has_default_client_cert_source(): 

308 client_cert_source = mtls.default_client_cert_source() 

309 

310 # Figure out which api endpoint to use. 

311 if client_options.api_endpoint is not None: 

312 api_endpoint = client_options.api_endpoint 

313 elif use_mtls_endpoint == "always" or ( 

314 use_mtls_endpoint == "auto" and client_cert_source 

315 ): 

316 api_endpoint = cls.DEFAULT_MTLS_ENDPOINT 

317 else: 

318 api_endpoint = cls.DEFAULT_ENDPOINT 

319 

320 return api_endpoint, client_cert_source 

321 

322 def __init__( 

323 self, 

324 *, 

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

326 transport: Optional[Union[str, ReportErrorsServiceTransport]] = None, 

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

328 client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, 

329 ) -> None: 

330 """Instantiates the report errors service client. 

331 

332 Args: 

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

334 authorization credentials to attach to requests. These 

335 credentials identify the application to the service; if none 

336 are specified, the client will attempt to ascertain the 

337 credentials from the environment. 

338 transport (Union[str, ReportErrorsServiceTransport]): The 

339 transport to use. If set to None, a transport is chosen 

340 automatically. 

341 client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): Custom options for the 

342 client. It won't take effect if a ``transport`` instance is provided. 

343 (1) The ``api_endpoint`` property can be used to override the 

344 default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT 

345 environment variable can also be used to override the endpoint: 

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

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

348 default mTLS endpoint if client certificate is present, this is 

349 the default value). However, the ``api_endpoint`` property takes 

350 precedence if provided. 

351 (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable 

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

353 to provide client certificate for mutual TLS transport. If 

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

355 present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not 

356 set, no client certificate will be used. 

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

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

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

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

361 your own client library. 

362 

363 Raises: 

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

365 creation failed for any reason. 

366 """ 

367 if isinstance(client_options, dict): 

368 client_options = client_options_lib.from_dict(client_options) 

369 if client_options is None: 

370 client_options = client_options_lib.ClientOptions() 

371 client_options = cast(client_options_lib.ClientOptions, client_options) 

372 

373 api_endpoint, client_cert_source_func = self.get_mtls_endpoint_and_cert_source( 

374 client_options 

375 ) 

376 

377 api_key_value = getattr(client_options, "api_key", None) 

378 if api_key_value and credentials: 

379 raise ValueError( 

380 "client_options.api_key and credentials are mutually exclusive" 

381 ) 

382 

383 # Save or instantiate the transport. 

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

385 # instance provides an extensibility point for unusual situations. 

386 if isinstance(transport, ReportErrorsServiceTransport): 

387 # transport is a ReportErrorsServiceTransport instance. 

388 if credentials or client_options.credentials_file or api_key_value: 

389 raise ValueError( 

390 "When providing a transport instance, " 

391 "provide its credentials directly." 

392 ) 

393 if client_options.scopes: 

394 raise ValueError( 

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

396 "directly." 

397 ) 

398 self._transport = transport 

399 else: 

400 import google.auth._default # type: ignore 

401 

402 if api_key_value and hasattr( 

403 google.auth._default, "get_api_key_credentials" 

404 ): 

405 credentials = google.auth._default.get_api_key_credentials( 

406 api_key_value 

407 ) 

408 

409 Transport = type(self).get_transport_class(transport) 

410 self._transport = Transport( 

411 credentials=credentials, 

412 credentials_file=client_options.credentials_file, 

413 host=api_endpoint, 

414 scopes=client_options.scopes, 

415 client_cert_source_for_mtls=client_cert_source_func, 

416 quota_project_id=client_options.quota_project_id, 

417 client_info=client_info, 

418 always_use_jwt_access=True, 

419 api_audience=client_options.api_audience, 

420 ) 

421 

422 def report_error_event( 

423 self, 

424 request: Optional[ 

425 Union[report_errors_service.ReportErrorEventRequest, dict] 

426 ] = None, 

427 *, 

428 project_name: Optional[str] = None, 

429 event: Optional[report_errors_service.ReportedErrorEvent] = None, 

430 retry: OptionalRetry = gapic_v1.method.DEFAULT, 

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

432 metadata: Sequence[Tuple[str, str]] = (), 

433 ) -> report_errors_service.ReportErrorEventResponse: 

434 r"""Report an individual error event and record the event to a log. 

435 

436 This endpoint accepts **either** an OAuth token, **or** an `API 

437 key <https://support.google.com/cloud/answer/6158862>`__ for 

438 authentication. To use an API key, append it to the URL as the 

439 value of a ``key`` parameter. For example: 

440 

441 ``POST https://clouderrorreporting.googleapis.com/v1beta1/{projectName}/events:report?key=123ABC456`` 

442 

443 **Note:** `Error Reporting </error-reporting>`__ is a global 

444 service built on Cloud Logging and doesn't analyze logs stored 

445 in regional log buckets or logs routed to other Google Cloud 

446 projects. 

447 

448 .. code-block:: python 

449 

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

451 # code template only. 

452 # It will require modifications to work: 

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

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

455 # client as shown in: 

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

457 from google.cloud import errorreporting_v1beta1 

458 

459 def sample_report_error_event(): 

460 # Create a client 

461 client = errorreporting_v1beta1.ReportErrorsServiceClient() 

462 

463 # Initialize request argument(s) 

464 event = errorreporting_v1beta1.ReportedErrorEvent() 

465 event.message = "message_value" 

466 

467 request = errorreporting_v1beta1.ReportErrorEventRequest( 

468 project_name="project_name_value", 

469 event=event, 

470 ) 

471 

472 # Make the request 

473 response = client.report_error_event(request=request) 

474 

475 # Handle the response 

476 print(response) 

477 

478 Args: 

479 request (Union[google.cloud.errorreporting_v1beta1.types.ReportErrorEventRequest, dict]): 

480 The request object. A request for reporting an individual 

481 error event. 

482 project_name (str): 

483 Required. The resource name of the Google Cloud Platform 

484 project. Written as ``projects/{projectId}``, where 

485 ``{projectId}`` is the `Google Cloud Platform project 

486 ID <https://support.google.com/cloud/answer/6158840>`__. 

487 

488 Example: // ``projects/my-project-123``. 

489 

490 This corresponds to the ``project_name`` field 

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

492 should not be set. 

493 event (google.cloud.errorreporting_v1beta1.types.ReportedErrorEvent): 

494 Required. The error event to be 

495 reported. 

496 

497 This corresponds to the ``event`` field 

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

499 should not be set. 

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

501 should be retried. 

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

503 metadata (Sequence[Tuple[str, str]]): Strings which should be 

504 sent along with the request as metadata. 

505 

506 Returns: 

507 google.cloud.errorreporting_v1beta1.types.ReportErrorEventResponse: 

508 Response for reporting an individual 

509 error event. Data may be added to this 

510 message in the future. 

511 

512 """ 

513 # Create or coerce a protobuf request object. 

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

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

516 has_flattened_params = any([project_name, event]) 

517 if request is not None and has_flattened_params: 

518 raise ValueError( 

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

520 "the individual field arguments should be set." 

521 ) 

522 

523 # Minor optimization to avoid making a copy if the user passes 

524 # in a report_errors_service.ReportErrorEventRequest. 

525 # There's no risk of modifying the input as we've already verified 

526 # there are no flattened fields. 

527 if not isinstance(request, report_errors_service.ReportErrorEventRequest): 

528 request = report_errors_service.ReportErrorEventRequest(request) 

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

530 # request, apply these. 

531 if project_name is not None: 

532 request.project_name = project_name 

533 if event is not None: 

534 request.event = event 

535 

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

537 # and friendly error handling. 

538 rpc = self._transport._wrapped_methods[self._transport.report_error_event] 

539 

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

541 # add these here. 

542 metadata = tuple(metadata) + ( 

543 gapic_v1.routing_header.to_grpc_metadata( 

544 (("project_name", request.project_name),) 

545 ), 

546 ) 

547 

548 # Send the request. 

549 response = rpc( 

550 request, 

551 retry=retry, 

552 timeout=timeout, 

553 metadata=metadata, 

554 ) 

555 

556 # Done; return the response. 

557 return response 

558 

559 def __enter__(self) -> "ReportErrorsServiceClient": 

560 return self 

561 

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

563 """Releases underlying transport's resources. 

564 

565 .. warning:: 

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

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

568 and may cause errors in other clients! 

569 """ 

570 self.transport.close() 

571 

572 

573DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( 

574 gapic_version=package_version.__version__ 

575) 

576 

577 

578__all__ = ("ReportErrorsServiceClient",)