Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/google/api_core/operations_v1/transports/rest.py: 28%

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

116 statements  

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

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

16 

17from typing import Callable, Dict, Optional, Sequence, Tuple, Union 

18 

19from requests import __version__ as requests_version 

20 

21from google.api_core import exceptions as core_exceptions # type: ignore 

22from google.api_core import gapic_v1 # type: ignore 

23from google.api_core import path_template # type: ignore 

24from google.api_core import rest_helpers # type: ignore 

25from google.api_core import retry as retries # type: ignore 

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

27from google.auth.transport.requests import AuthorizedSession # type: ignore 

28from google.longrunning import operations_pb2 # type: ignore 

29from google.protobuf import empty_pb2 # type: ignore 

30from google.protobuf import json_format # type: ignore 

31import google.protobuf 

32 

33import grpc 

34from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO, OperationsTransport 

35 

36PROTOBUF_VERSION = google.protobuf.__version__ 

37 

38OptionalRetry = Union[retries.Retry, object] 

39 

40DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( 

41 gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, 

42 grpc_version=None, 

43 rest_version=f"requests@{requests_version}", 

44) 

45 

46 

47class OperationsRestTransport(OperationsTransport): 

48 """REST backend transport for Operations. 

49 

50 Manages long-running operations with an API service. 

51 

52 When an API method normally takes long time to complete, it can be 

53 designed to return [Operation][google.api_core.operations_v1.Operation] to the 

54 client, and the client can use this interface to receive the real 

55 response asynchronously by polling the operation resource, or pass 

56 the operation resource to another API (such as Google Cloud Pub/Sub 

57 API) to receive the response. Any API service that returns 

58 long-running operations should implement the ``Operations`` 

59 interface so developers can have a consistent client experience. 

60 

61 This class defines the same methods as the primary client, so the 

62 primary client can load the underlying transport implementation 

63 and call it. 

64 

65 It sends JSON representations of protocol buffers over HTTP/1.1 

66 """ 

67 

68 def __init__( 

69 self, 

70 *, 

71 host: str = "longrunning.googleapis.com", 

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

73 credentials_file: Optional[str] = None, 

74 scopes: Optional[Sequence[str]] = None, 

75 client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, 

76 quota_project_id: Optional[str] = None, 

77 client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, 

78 always_use_jwt_access: Optional[bool] = False, 

79 url_scheme: str = "https", 

80 http_options: Optional[Dict] = None, 

81 path_prefix: str = "v1", 

82 ) -> None: 

83 """Instantiate the transport. 

84 

85 Args: 

86 host (Optional[str]): 

87 The hostname to connect to. 

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

89 authorization credentials to attach to requests. These 

90 credentials identify the application to the service; if none 

91 are specified, the client will attempt to ascertain the 

92 credentials from the environment. 

93 

94 credentials_file (Optional[str]): A file with credentials that can 

95 be loaded with :func:`google.auth.load_credentials_from_file`. 

96 This argument is ignored if ``channel`` is provided. 

97 

98 .. warning:: 

99 Important: If you accept a credential configuration (credential JSON/File/Stream) 

100 from an external source for authentication to Google Cloud Platform, you must 

101 validate it before providing it to any Google API or client library. Providing an 

102 unvalidated credential configuration to Google APIs or libraries can compromise 

103 the security of your systems and data. For more information, refer to 

104 `Validate credential configurations from external sources`_. 

105 

106 .. _Validate credential configurations from external sources: 

107 

108 https://cloud.google.com/docs/authentication/external/externally-sourced-credentials 

109 scopes (Optional(Sequence[str])): A list of scopes. This argument is 

110 ignored if ``channel`` is provided. 

111 client_cert_source_for_mtls (Callable[[], Tuple[bytes, bytes]]): Client 

112 certificate to configure mutual TLS HTTP channel. It is ignored 

113 if ``channel`` is provided. 

114 quota_project_id (Optional[str]): An optional project to use for billing 

115 and quota. 

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

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

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

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

120 your own client library. 

121 always_use_jwt_access (Optional[bool]): Whether self signed JWT should 

122 be used for service account credentials. 

123 url_scheme: the protocol scheme for the API endpoint. Normally 

124 "https", but for testing or local servers, 

125 "http" can be specified. 

126 http_options: a dictionary of http_options for transcoding, to override 

127 the defaults from operations.proto. Each method has an entry 

128 with the corresponding http rules as value. 

129 path_prefix: path prefix (usually represents API version). Set to 

130 "v1" by default. 

131 

132 """ 

133 # Run the base constructor 

134 # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. 

135 # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the 

136 # credentials object 

137 super().__init__( 

138 host=host, 

139 credentials=credentials, 

140 client_info=client_info, 

141 always_use_jwt_access=always_use_jwt_access, 

142 ) 

143 self._session = AuthorizedSession( 

144 self._credentials, default_host=self.DEFAULT_HOST 

145 ) 

146 if client_cert_source_for_mtls: 

147 self._session.configure_mtls_channel(client_cert_source_for_mtls) 

148 # TODO(https://github.com/googleapis/python-api-core/issues/720): Add wrap logic directly to the property methods for callables. 

149 self._prep_wrapped_messages(client_info) 

150 self._http_options = http_options or {} 

151 self._path_prefix = path_prefix 

152 

153 def _list_operations( 

154 self, 

155 request: operations_pb2.ListOperationsRequest, 

156 *, 

157 # TODO(https://github.com/googleapis/python-api-core/issues/723): Leverage `retry` 

158 # to allow configuring retryable error codes. 

159 retry: OptionalRetry = gapic_v1.method.DEFAULT, 

160 timeout: Optional[float] = None, 

161 compression: Optional[grpc.Compression] = gapic_v1.method.DEFAULT, 

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

163 ) -> operations_pb2.ListOperationsResponse: 

164 r"""Call the list operations method over HTTP. 

165 

166 Args: 

167 request (~.operations_pb2.ListOperationsRequest): 

168 The request object. The request message for 

169 [Operations.ListOperations][google.api_core.operations_v1.Operations.ListOperations]. 

170 

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

172 should be retried. 

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

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

175 sent along with the request as metadata. 

176 

177 Returns: 

178 ~.operations_pb2.ListOperationsResponse: 

179 The response message for 

180 [Operations.ListOperations][google.api_core.operations_v1.Operations.ListOperations]. 

181 

182 """ 

183 

184 http_options = [ 

185 { 

186 "method": "get", 

187 "uri": "/{}/{{name=**}}/operations".format(self._path_prefix), 

188 }, 

189 ] 

190 if "google.longrunning.Operations.ListOperations" in self._http_options: 

191 http_options = self._http_options[ 

192 "google.longrunning.Operations.ListOperations" 

193 ] 

194 

195 request_kwargs = self._convert_protobuf_message_to_dict(request) 

196 transcoded_request = path_template.transcode(http_options, **request_kwargs) 

197 

198 uri = transcoded_request["uri"] 

199 method = transcoded_request["method"] 

200 

201 # Jsonify the query params 

202 query_params_request = operations_pb2.ListOperationsRequest() 

203 json_format.ParseDict(transcoded_request["query_params"], query_params_request) 

204 query_params = json_format.MessageToDict( 

205 query_params_request, 

206 preserving_proto_field_name=False, 

207 use_integers_for_enums=False, 

208 ) 

209 

210 # Send the request 

211 headers = dict(metadata) 

212 headers["Content-Type"] = "application/json" 

213 # TODO(https://github.com/googleapis/python-api-core/issues/721): Update incorrect use of `uri`` variable name. 

214 response = getattr(self._session, method)( 

215 "{host}{uri}".format(host=self._host, uri=uri), 

216 timeout=timeout, 

217 headers=headers, 

218 params=rest_helpers.flatten_query_params(query_params), 

219 ) 

220 

221 # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception 

222 # subclass. 

223 if response.status_code >= 400: 

224 raise core_exceptions.from_http_response(response) 

225 

226 # Return the response 

227 api_response = operations_pb2.ListOperationsResponse() 

228 json_format.Parse(response.content, api_response, ignore_unknown_fields=False) 

229 return api_response 

230 

231 def _get_operation( 

232 self, 

233 request: operations_pb2.GetOperationRequest, 

234 *, 

235 # TODO(https://github.com/googleapis/python-api-core/issues/723): Leverage `retry` 

236 # to allow configuring retryable error codes. 

237 retry: OptionalRetry = gapic_v1.method.DEFAULT, 

238 timeout: Optional[float] = None, 

239 compression: Optional[grpc.Compression] = gapic_v1.method.DEFAULT, 

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

241 ) -> operations_pb2.Operation: 

242 r"""Call the get operation method over HTTP. 

243 

244 Args: 

245 request (~.operations_pb2.GetOperationRequest): 

246 The request object. The request message for 

247 [Operations.GetOperation][google.api_core.operations_v1.Operations.GetOperation]. 

248 

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

250 should be retried. 

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

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

253 sent along with the request as metadata. 

254 

255 Returns: 

256 ~.operations_pb2.Operation: 

257 This resource represents a long- 

258 running operation that is the result of a 

259 network API call. 

260 

261 """ 

262 

263 http_options = [ 

264 { 

265 "method": "get", 

266 "uri": "/{}/{{name=**/operations/*}}".format(self._path_prefix), 

267 }, 

268 ] 

269 if "google.longrunning.Operations.GetOperation" in self._http_options: 

270 http_options = self._http_options[ 

271 "google.longrunning.Operations.GetOperation" 

272 ] 

273 

274 request_kwargs = self._convert_protobuf_message_to_dict(request) 

275 transcoded_request = path_template.transcode(http_options, **request_kwargs) 

276 

277 uri = transcoded_request["uri"] 

278 method = transcoded_request["method"] 

279 

280 # Jsonify the query params 

281 query_params_request = operations_pb2.GetOperationRequest() 

282 json_format.ParseDict(transcoded_request["query_params"], query_params_request) 

283 query_params = json_format.MessageToDict( 

284 query_params_request, 

285 preserving_proto_field_name=False, 

286 use_integers_for_enums=False, 

287 ) 

288 

289 # Send the request 

290 headers = dict(metadata) 

291 headers["Content-Type"] = "application/json" 

292 # TODO(https://github.com/googleapis/python-api-core/issues/721): Update incorrect use of `uri`` variable name. 

293 response = getattr(self._session, method)( 

294 "{host}{uri}".format(host=self._host, uri=uri), 

295 timeout=timeout, 

296 headers=headers, 

297 params=rest_helpers.flatten_query_params(query_params), 

298 ) 

299 

300 # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception 

301 # subclass. 

302 if response.status_code >= 400: 

303 raise core_exceptions.from_http_response(response) 

304 

305 # Return the response 

306 api_response = operations_pb2.Operation() 

307 json_format.Parse(response.content, api_response, ignore_unknown_fields=False) 

308 return api_response 

309 

310 def _delete_operation( 

311 self, 

312 request: operations_pb2.DeleteOperationRequest, 

313 *, 

314 # TODO(https://github.com/googleapis/python-api-core/issues/723): Leverage `retry` 

315 # to allow configuring retryable error codes. 

316 retry: OptionalRetry = gapic_v1.method.DEFAULT, 

317 timeout: Optional[float] = None, 

318 compression: Optional[grpc.Compression] = gapic_v1.method.DEFAULT, 

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

320 ) -> empty_pb2.Empty: 

321 r"""Call the delete operation method over HTTP. 

322 

323 Args: 

324 request (~.operations_pb2.DeleteOperationRequest): 

325 The request object. The request message for 

326 [Operations.DeleteOperation][google.api_core.operations_v1.Operations.DeleteOperation]. 

327 

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

329 should be retried. 

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

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

332 sent along with the request as metadata. 

333 """ 

334 

335 http_options = [ 

336 { 

337 "method": "delete", 

338 "uri": "/{}/{{name=**/operations/*}}".format(self._path_prefix), 

339 }, 

340 ] 

341 if "google.longrunning.Operations.DeleteOperation" in self._http_options: 

342 http_options = self._http_options[ 

343 "google.longrunning.Operations.DeleteOperation" 

344 ] 

345 

346 request_kwargs = self._convert_protobuf_message_to_dict(request) 

347 transcoded_request = path_template.transcode(http_options, **request_kwargs) 

348 

349 uri = transcoded_request["uri"] 

350 method = transcoded_request["method"] 

351 

352 # Jsonify the query params 

353 query_params_request = operations_pb2.DeleteOperationRequest() 

354 json_format.ParseDict(transcoded_request["query_params"], query_params_request) 

355 query_params = json_format.MessageToDict( 

356 query_params_request, 

357 preserving_proto_field_name=False, 

358 use_integers_for_enums=False, 

359 ) 

360 

361 # Send the request 

362 headers = dict(metadata) 

363 headers["Content-Type"] = "application/json" 

364 # TODO(https://github.com/googleapis/python-api-core/issues/721): Update incorrect use of `uri`` variable name. 

365 response = getattr(self._session, method)( 

366 "{host}{uri}".format(host=self._host, uri=uri), 

367 timeout=timeout, 

368 headers=headers, 

369 params=rest_helpers.flatten_query_params(query_params), 

370 ) 

371 

372 # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception 

373 # subclass. 

374 if response.status_code >= 400: 

375 raise core_exceptions.from_http_response(response) 

376 

377 return empty_pb2.Empty() 

378 

379 def _cancel_operation( 

380 self, 

381 request: operations_pb2.CancelOperationRequest, 

382 *, 

383 # TODO(https://github.com/googleapis/python-api-core/issues/723): Leverage `retry` 

384 # to allow configuring retryable error codes. 

385 retry: OptionalRetry = gapic_v1.method.DEFAULT, 

386 timeout: Optional[float] = None, 

387 compression: Optional[grpc.Compression] = gapic_v1.method.DEFAULT, 

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

389 ) -> empty_pb2.Empty: 

390 r"""Call the cancel operation method over HTTP. 

391 

392 Args: 

393 request (~.operations_pb2.CancelOperationRequest): 

394 The request object. The request message for 

395 [Operations.CancelOperation][google.api_core.operations_v1.Operations.CancelOperation]. 

396 

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

398 should be retried. 

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

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

401 sent along with the request as metadata. 

402 """ 

403 

404 http_options = [ 

405 { 

406 "method": "post", 

407 "uri": "/{}/{{name=**/operations/*}}:cancel".format(self._path_prefix), 

408 "body": "*", 

409 }, 

410 ] 

411 if "google.longrunning.Operations.CancelOperation" in self._http_options: 

412 http_options = self._http_options[ 

413 "google.longrunning.Operations.CancelOperation" 

414 ] 

415 

416 request_kwargs = self._convert_protobuf_message_to_dict(request) 

417 transcoded_request = path_template.transcode(http_options, **request_kwargs) 

418 

419 # Jsonify the request body 

420 body_request = operations_pb2.CancelOperationRequest() 

421 json_format.ParseDict(transcoded_request["body"], body_request) 

422 body = json_format.MessageToDict( 

423 body_request, 

424 preserving_proto_field_name=False, 

425 use_integers_for_enums=False, 

426 ) 

427 uri = transcoded_request["uri"] 

428 method = transcoded_request["method"] 

429 

430 # Jsonify the query params 

431 query_params_request = operations_pb2.CancelOperationRequest() 

432 json_format.ParseDict(transcoded_request["query_params"], query_params_request) 

433 query_params = json_format.MessageToDict( 

434 query_params_request, 

435 preserving_proto_field_name=False, 

436 use_integers_for_enums=False, 

437 ) 

438 

439 # Send the request 

440 headers = dict(metadata) 

441 headers["Content-Type"] = "application/json" 

442 # TODO(https://github.com/googleapis/python-api-core/issues/721): Update incorrect use of `uri`` variable name. 

443 response = getattr(self._session, method)( 

444 "{host}{uri}".format(host=self._host, uri=uri), 

445 timeout=timeout, 

446 headers=headers, 

447 params=rest_helpers.flatten_query_params(query_params), 

448 data=body, 

449 ) 

450 

451 # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception 

452 # subclass. 

453 if response.status_code >= 400: 

454 raise core_exceptions.from_http_response(response) 

455 

456 return empty_pb2.Empty() 

457 

458 @property 

459 def list_operations( 

460 self, 

461 ) -> Callable[ 

462 [operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse 

463 ]: 

464 return self._list_operations 

465 

466 @property 

467 def get_operation( 

468 self, 

469 ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: 

470 return self._get_operation 

471 

472 @property 

473 def delete_operation( 

474 self, 

475 ) -> Callable[[operations_pb2.DeleteOperationRequest], empty_pb2.Empty]: 

476 return self._delete_operation 

477 

478 @property 

479 def cancel_operation( 

480 self, 

481 ) -> Callable[[operations_pb2.CancelOperationRequest], empty_pb2.Empty]: 

482 return self._cancel_operation 

483 

484 

485__all__ = ("OperationsRestTransport",)