1# -*- coding: utf-8 -*-
2# Copyright 2026 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#
16import dataclasses
17import json # type: ignore
18import logging
19import warnings
20from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union
21
22import google.protobuf
23from google.api_core import exceptions as core_exceptions
24from google.api_core import gapic_v1, rest_helpers, rest_streaming
25from google.api_core import retry as retries
26from google.auth import credentials as ga_credentials # type: ignore
27from google.auth.transport.requests import AuthorizedSession # type: ignore
28from google.protobuf import json_format
29from requests import __version__ as requests_version
30
31from google.cloud.iam_credentials_v1.types import common
32
33from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO
34from .rest_base import _BaseIAMCredentialsRestTransport
35
36try:
37 OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None]
38except AttributeError: # pragma: NO COVER
39 OptionalRetry = Union[retries.Retry, object, None] # type: ignore
40
41try:
42 from google.api_core import client_logging # type: ignore
43
44 CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER
45except ImportError: # pragma: NO COVER
46 CLIENT_LOGGING_SUPPORTED = False
47
48_LOGGER = logging.getLogger(__name__)
49
50DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(
51 gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version,
52 grpc_version=None,
53 rest_version=f"requests@{requests_version}",
54)
55
56DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__
57
58
59class IAMCredentialsRestInterceptor:
60 """Interceptor for IAMCredentials.
61
62 Interceptors are used to manipulate requests, request metadata, and responses
63 in arbitrary ways.
64 Example use cases include:
65 * Logging
66 * Verifying requests according to service or custom semantics
67 * Stripping extraneous information from responses
68
69 These use cases and more can be enabled by injecting an
70 instance of a custom subclass when constructing the IAMCredentialsRestTransport.
71
72 .. code-block:: python
73 class MyCustomIAMCredentialsInterceptor(IAMCredentialsRestInterceptor):
74 def pre_generate_access_token(self, request, metadata):
75 logging.log(f"Received request: {request}")
76 return request, metadata
77
78 def post_generate_access_token(self, response):
79 logging.log(f"Received response: {response}")
80 return response
81
82 def pre_generate_id_token(self, request, metadata):
83 logging.log(f"Received request: {request}")
84 return request, metadata
85
86 def post_generate_id_token(self, response):
87 logging.log(f"Received response: {response}")
88 return response
89
90 def pre_sign_blob(self, request, metadata):
91 logging.log(f"Received request: {request}")
92 return request, metadata
93
94 def post_sign_blob(self, response):
95 logging.log(f"Received response: {response}")
96 return response
97
98 def pre_sign_jwt(self, request, metadata):
99 logging.log(f"Received request: {request}")
100 return request, metadata
101
102 def post_sign_jwt(self, response):
103 logging.log(f"Received response: {response}")
104 return response
105
106 transport = IAMCredentialsRestTransport(interceptor=MyCustomIAMCredentialsInterceptor())
107 client = IAMCredentialsClient(transport=transport)
108
109
110 """
111
112 def pre_generate_access_token(
113 self,
114 request: common.GenerateAccessTokenRequest,
115 metadata: Sequence[Tuple[str, Union[str, bytes]]],
116 ) -> Tuple[
117 common.GenerateAccessTokenRequest, Sequence[Tuple[str, Union[str, bytes]]]
118 ]:
119 """Pre-rpc interceptor for generate_access_token
120
121 Override in a subclass to manipulate the request or metadata
122 before they are sent to the IAMCredentials server.
123 """
124 return request, metadata
125
126 def post_generate_access_token(
127 self, response: common.GenerateAccessTokenResponse
128 ) -> common.GenerateAccessTokenResponse:
129 """Post-rpc interceptor for generate_access_token
130
131 DEPRECATED. Please use the `post_generate_access_token_with_metadata`
132 interceptor instead.
133
134 Override in a subclass to read or manipulate the response
135 after it is returned by the IAMCredentials server but before
136 it is returned to user code. This `post_generate_access_token` interceptor runs
137 before the `post_generate_access_token_with_metadata` interceptor.
138 """
139 return response
140
141 def post_generate_access_token_with_metadata(
142 self,
143 response: common.GenerateAccessTokenResponse,
144 metadata: Sequence[Tuple[str, Union[str, bytes]]],
145 ) -> Tuple[
146 common.GenerateAccessTokenResponse, Sequence[Tuple[str, Union[str, bytes]]]
147 ]:
148 """Post-rpc interceptor for generate_access_token
149
150 Override in a subclass to read or manipulate the response or metadata after it
151 is returned by the IAMCredentials server but before it is returned to user code.
152
153 We recommend only using this `post_generate_access_token_with_metadata`
154 interceptor in new development instead of the `post_generate_access_token` interceptor.
155 When both interceptors are used, this `post_generate_access_token_with_metadata` interceptor runs after the
156 `post_generate_access_token` interceptor. The (possibly modified) response returned by
157 `post_generate_access_token` will be passed to
158 `post_generate_access_token_with_metadata`.
159 """
160 return response, metadata
161
162 def pre_generate_id_token(
163 self,
164 request: common.GenerateIdTokenRequest,
165 metadata: Sequence[Tuple[str, Union[str, bytes]]],
166 ) -> Tuple[common.GenerateIdTokenRequest, Sequence[Tuple[str, Union[str, bytes]]]]:
167 """Pre-rpc interceptor for generate_id_token
168
169 Override in a subclass to manipulate the request or metadata
170 before they are sent to the IAMCredentials server.
171 """
172 return request, metadata
173
174 def post_generate_id_token(
175 self, response: common.GenerateIdTokenResponse
176 ) -> common.GenerateIdTokenResponse:
177 """Post-rpc interceptor for generate_id_token
178
179 DEPRECATED. Please use the `post_generate_id_token_with_metadata`
180 interceptor instead.
181
182 Override in a subclass to read or manipulate the response
183 after it is returned by the IAMCredentials server but before
184 it is returned to user code. This `post_generate_id_token` interceptor runs
185 before the `post_generate_id_token_with_metadata` interceptor.
186 """
187 return response
188
189 def post_generate_id_token_with_metadata(
190 self,
191 response: common.GenerateIdTokenResponse,
192 metadata: Sequence[Tuple[str, Union[str, bytes]]],
193 ) -> Tuple[common.GenerateIdTokenResponse, Sequence[Tuple[str, Union[str, bytes]]]]:
194 """Post-rpc interceptor for generate_id_token
195
196 Override in a subclass to read or manipulate the response or metadata after it
197 is returned by the IAMCredentials server but before it is returned to user code.
198
199 We recommend only using this `post_generate_id_token_with_metadata`
200 interceptor in new development instead of the `post_generate_id_token` interceptor.
201 When both interceptors are used, this `post_generate_id_token_with_metadata` interceptor runs after the
202 `post_generate_id_token` interceptor. The (possibly modified) response returned by
203 `post_generate_id_token` will be passed to
204 `post_generate_id_token_with_metadata`.
205 """
206 return response, metadata
207
208 def pre_sign_blob(
209 self,
210 request: common.SignBlobRequest,
211 metadata: Sequence[Tuple[str, Union[str, bytes]]],
212 ) -> Tuple[common.SignBlobRequest, Sequence[Tuple[str, Union[str, bytes]]]]:
213 """Pre-rpc interceptor for sign_blob
214
215 Override in a subclass to manipulate the request or metadata
216 before they are sent to the IAMCredentials server.
217 """
218 return request, metadata
219
220 def post_sign_blob(
221 self, response: common.SignBlobResponse
222 ) -> common.SignBlobResponse:
223 """Post-rpc interceptor for sign_blob
224
225 DEPRECATED. Please use the `post_sign_blob_with_metadata`
226 interceptor instead.
227
228 Override in a subclass to read or manipulate the response
229 after it is returned by the IAMCredentials server but before
230 it is returned to user code. This `post_sign_blob` interceptor runs
231 before the `post_sign_blob_with_metadata` interceptor.
232 """
233 return response
234
235 def post_sign_blob_with_metadata(
236 self,
237 response: common.SignBlobResponse,
238 metadata: Sequence[Tuple[str, Union[str, bytes]]],
239 ) -> Tuple[common.SignBlobResponse, Sequence[Tuple[str, Union[str, bytes]]]]:
240 """Post-rpc interceptor for sign_blob
241
242 Override in a subclass to read or manipulate the response or metadata after it
243 is returned by the IAMCredentials server but before it is returned to user code.
244
245 We recommend only using this `post_sign_blob_with_metadata`
246 interceptor in new development instead of the `post_sign_blob` interceptor.
247 When both interceptors are used, this `post_sign_blob_with_metadata` interceptor runs after the
248 `post_sign_blob` interceptor. The (possibly modified) response returned by
249 `post_sign_blob` will be passed to
250 `post_sign_blob_with_metadata`.
251 """
252 return response, metadata
253
254 def pre_sign_jwt(
255 self,
256 request: common.SignJwtRequest,
257 metadata: Sequence[Tuple[str, Union[str, bytes]]],
258 ) -> Tuple[common.SignJwtRequest, Sequence[Tuple[str, Union[str, bytes]]]]:
259 """Pre-rpc interceptor for sign_jwt
260
261 Override in a subclass to manipulate the request or metadata
262 before they are sent to the IAMCredentials server.
263 """
264 return request, metadata
265
266 def post_sign_jwt(self, response: common.SignJwtResponse) -> common.SignJwtResponse:
267 """Post-rpc interceptor for sign_jwt
268
269 DEPRECATED. Please use the `post_sign_jwt_with_metadata`
270 interceptor instead.
271
272 Override in a subclass to read or manipulate the response
273 after it is returned by the IAMCredentials server but before
274 it is returned to user code. This `post_sign_jwt` interceptor runs
275 before the `post_sign_jwt_with_metadata` interceptor.
276 """
277 return response
278
279 def post_sign_jwt_with_metadata(
280 self,
281 response: common.SignJwtResponse,
282 metadata: Sequence[Tuple[str, Union[str, bytes]]],
283 ) -> Tuple[common.SignJwtResponse, Sequence[Tuple[str, Union[str, bytes]]]]:
284 """Post-rpc interceptor for sign_jwt
285
286 Override in a subclass to read or manipulate the response or metadata after it
287 is returned by the IAMCredentials server but before it is returned to user code.
288
289 We recommend only using this `post_sign_jwt_with_metadata`
290 interceptor in new development instead of the `post_sign_jwt` interceptor.
291 When both interceptors are used, this `post_sign_jwt_with_metadata` interceptor runs after the
292 `post_sign_jwt` interceptor. The (possibly modified) response returned by
293 `post_sign_jwt` will be passed to
294 `post_sign_jwt_with_metadata`.
295 """
296 return response, metadata
297
298
299@dataclasses.dataclass
300class IAMCredentialsRestStub:
301 _session: AuthorizedSession
302 _host: str
303 _interceptor: IAMCredentialsRestInterceptor
304
305
306class IAMCredentialsRestTransport(_BaseIAMCredentialsRestTransport):
307 """REST backend synchronous transport for IAMCredentials.
308
309 A service account is a special type of Google account that
310 belongs to your application or a virtual machine (VM), instead
311 of to an individual end user. Your application assumes the
312 identity of the service account to call Google APIs, so that the
313 users aren't directly involved.
314
315 Service account credentials are used to temporarily assume the
316 identity of the service account. Supported credential types
317 include OAuth 2.0 access tokens, OpenID Connect ID tokens,
318 self-signed JSON Web Tokens (JWTs), and more.
319
320 This class defines the same methods as the primary client, so the
321 primary client can load the underlying transport implementation
322 and call it.
323
324 It sends JSON representations of protocol buffers over HTTP/1.1
325 """
326
327 def __init__(
328 self,
329 *,
330 host: str = "iamcredentials.googleapis.com",
331 credentials: Optional[ga_credentials.Credentials] = None,
332 credentials_file: Optional[str] = None,
333 scopes: Optional[Sequence[str]] = None,
334 client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None,
335 quota_project_id: Optional[str] = None,
336 client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
337 always_use_jwt_access: Optional[bool] = False,
338 url_scheme: str = "https",
339 interceptor: Optional[IAMCredentialsRestInterceptor] = None,
340 api_audience: Optional[str] = None,
341 ) -> None:
342 """Instantiate the transport.
343
344 Args:
345 host (Optional[str]):
346 The hostname to connect to (default: 'iamcredentials.googleapis.com').
347 credentials (Optional[google.auth.credentials.Credentials]): The
348 authorization credentials to attach to requests. These
349 credentials identify the application to the service; if none
350 are specified, the client will attempt to ascertain the
351 credentials from the environment.
352
353 credentials_file (Optional[str]): Deprecated. A file with credentials that can
354 be loaded with :func:`google.auth.load_credentials_from_file`.
355 This argument is ignored if ``channel`` is provided. This argument will be
356 removed in the next major version of this library.
357 scopes (Optional(Sequence[str])): A list of scopes. This argument is
358 ignored if ``channel`` is provided.
359 client_cert_source_for_mtls (Callable[[], Tuple[bytes, bytes]]): Client
360 certificate to configure mutual TLS HTTP channel. It is ignored
361 if ``channel`` is provided.
362 quota_project_id (Optional[str]): An optional project to use for billing
363 and quota.
364 client_info (google.api_core.gapic_v1.client_info.ClientInfo):
365 The client info used to send a user-agent string along with
366 API requests. If ``None``, then default info will be used.
367 Generally, you only need to set this if you are developing
368 your own client library.
369 always_use_jwt_access (Optional[bool]): Whether self signed JWT should
370 be used for service account credentials.
371 url_scheme: the protocol scheme for the API endpoint. Normally
372 "https", but for testing or local servers,
373 "http" can be specified.
374 interceptor (Optional[IAMCredentialsRestInterceptor]): Interceptor used
375 to manipulate requests, request metadata, and responses.
376 api_audience (Optional[str]): The intended audience for the API calls
377 to the service that will be set when using certain 3rd party
378 authentication flows. Audience is typically a resource identifier.
379 If not set, the host value will be used as a default.
380 """
381 # Run the base constructor
382 # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc.
383 # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the
384 # credentials object
385 super().__init__(
386 host=host,
387 credentials=credentials,
388 client_info=client_info,
389 always_use_jwt_access=always_use_jwt_access,
390 url_scheme=url_scheme,
391 api_audience=api_audience,
392 )
393 self._session = AuthorizedSession(
394 self._credentials, default_host=self.DEFAULT_HOST
395 )
396 if client_cert_source_for_mtls:
397 self._session.configure_mtls_channel(client_cert_source_for_mtls)
398 self._interceptor = interceptor or IAMCredentialsRestInterceptor()
399 self._prep_wrapped_messages(client_info)
400
401 class _GenerateAccessToken(
402 _BaseIAMCredentialsRestTransport._BaseGenerateAccessToken,
403 IAMCredentialsRestStub,
404 ):
405 def __hash__(self):
406 return hash("IAMCredentialsRestTransport.GenerateAccessToken")
407
408 @staticmethod
409 def _get_response(
410 host,
411 metadata,
412 query_params,
413 session,
414 timeout,
415 transcoded_request,
416 body=None,
417 ):
418 uri = transcoded_request["uri"]
419 method = transcoded_request["method"]
420 headers = dict(metadata)
421 headers["Content-Type"] = "application/json"
422 response = getattr(session, method)(
423 "{host}{uri}".format(host=host, uri=uri),
424 timeout=timeout,
425 headers=headers,
426 params=rest_helpers.flatten_query_params(query_params, strict=True),
427 data=body,
428 )
429 return response
430
431 def __call__(
432 self,
433 request: common.GenerateAccessTokenRequest,
434 *,
435 retry: OptionalRetry = gapic_v1.method.DEFAULT,
436 timeout: Optional[float] = None,
437 metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
438 ) -> common.GenerateAccessTokenResponse:
439 r"""Call the generate access token method over HTTP.
440
441 Args:
442 request (~.common.GenerateAccessTokenRequest):
443 The request object.
444 retry (google.api_core.retry.Retry): Designation of what errors, if any,
445 should be retried.
446 timeout (float): The timeout for this request.
447 metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
448 sent along with the request as metadata. Normally, each value must be of type `str`,
449 but for metadata keys ending with the suffix `-bin`, the corresponding values must
450 be of type `bytes`.
451
452 Returns:
453 ~.common.GenerateAccessTokenResponse:
454
455 """
456
457 http_options = _BaseIAMCredentialsRestTransport._BaseGenerateAccessToken._get_http_options()
458
459 request, metadata = self._interceptor.pre_generate_access_token(
460 request, metadata
461 )
462 transcoded_request = _BaseIAMCredentialsRestTransport._BaseGenerateAccessToken._get_transcoded_request(
463 http_options, request
464 )
465
466 body = _BaseIAMCredentialsRestTransport._BaseGenerateAccessToken._get_request_body_json(
467 transcoded_request
468 )
469
470 # Jsonify the query params
471 query_params = _BaseIAMCredentialsRestTransport._BaseGenerateAccessToken._get_query_params_json(
472 transcoded_request
473 )
474
475 if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
476 logging.DEBUG
477 ): # pragma: NO COVER
478 request_url = "{host}{uri}".format(
479 host=self._host, uri=transcoded_request["uri"]
480 )
481 method = transcoded_request["method"]
482 try:
483 request_payload = type(request).to_json(request)
484 except:
485 request_payload = None
486 http_request = {
487 "payload": request_payload,
488 "requestMethod": method,
489 "requestUrl": request_url,
490 "headers": dict(metadata),
491 }
492 _LOGGER.debug(
493 f"Sending request for google.iam.credentials_v1.IAMCredentialsClient.GenerateAccessToken",
494 extra={
495 "serviceName": "google.iam.credentials.v1.IAMCredentials",
496 "rpcName": "GenerateAccessToken",
497 "httpRequest": http_request,
498 "metadata": http_request["headers"],
499 },
500 )
501
502 # Send the request
503 response = IAMCredentialsRestTransport._GenerateAccessToken._get_response(
504 self._host,
505 metadata,
506 query_params,
507 self._session,
508 timeout,
509 transcoded_request,
510 body,
511 )
512
513 # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
514 # subclass.
515 if response.status_code >= 400:
516 raise core_exceptions.from_http_response(response)
517
518 # Return the response
519 resp = common.GenerateAccessTokenResponse()
520 pb_resp = common.GenerateAccessTokenResponse.pb(resp)
521
522 json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True)
523
524 resp = self._interceptor.post_generate_access_token(resp)
525 response_metadata = [(k, str(v)) for k, v in response.headers.items()]
526 resp, _ = self._interceptor.post_generate_access_token_with_metadata(
527 resp, response_metadata
528 )
529 if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
530 logging.DEBUG
531 ): # pragma: NO COVER
532 try:
533 response_payload = common.GenerateAccessTokenResponse.to_json(
534 response
535 )
536 except:
537 response_payload = None
538 http_response = {
539 "payload": response_payload,
540 "headers": dict(response.headers),
541 "status": response.status_code,
542 }
543 _LOGGER.debug(
544 "Received response for google.iam.credentials_v1.IAMCredentialsClient.generate_access_token",
545 extra={
546 "serviceName": "google.iam.credentials.v1.IAMCredentials",
547 "rpcName": "GenerateAccessToken",
548 "metadata": http_response["headers"],
549 "httpResponse": http_response,
550 },
551 )
552 return resp
553
554 class _GenerateIdToken(
555 _BaseIAMCredentialsRestTransport._BaseGenerateIdToken, IAMCredentialsRestStub
556 ):
557 def __hash__(self):
558 return hash("IAMCredentialsRestTransport.GenerateIdToken")
559
560 @staticmethod
561 def _get_response(
562 host,
563 metadata,
564 query_params,
565 session,
566 timeout,
567 transcoded_request,
568 body=None,
569 ):
570 uri = transcoded_request["uri"]
571 method = transcoded_request["method"]
572 headers = dict(metadata)
573 headers["Content-Type"] = "application/json"
574 response = getattr(session, method)(
575 "{host}{uri}".format(host=host, uri=uri),
576 timeout=timeout,
577 headers=headers,
578 params=rest_helpers.flatten_query_params(query_params, strict=True),
579 data=body,
580 )
581 return response
582
583 def __call__(
584 self,
585 request: common.GenerateIdTokenRequest,
586 *,
587 retry: OptionalRetry = gapic_v1.method.DEFAULT,
588 timeout: Optional[float] = None,
589 metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
590 ) -> common.GenerateIdTokenResponse:
591 r"""Call the generate id token method over HTTP.
592
593 Args:
594 request (~.common.GenerateIdTokenRequest):
595 The request object.
596 retry (google.api_core.retry.Retry): Designation of what errors, if any,
597 should be retried.
598 timeout (float): The timeout for this request.
599 metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
600 sent along with the request as metadata. Normally, each value must be of type `str`,
601 but for metadata keys ending with the suffix `-bin`, the corresponding values must
602 be of type `bytes`.
603
604 Returns:
605 ~.common.GenerateIdTokenResponse:
606
607 """
608
609 http_options = _BaseIAMCredentialsRestTransport._BaseGenerateIdToken._get_http_options()
610
611 request, metadata = self._interceptor.pre_generate_id_token(
612 request, metadata
613 )
614 transcoded_request = _BaseIAMCredentialsRestTransport._BaseGenerateIdToken._get_transcoded_request(
615 http_options, request
616 )
617
618 body = _BaseIAMCredentialsRestTransport._BaseGenerateIdToken._get_request_body_json(
619 transcoded_request
620 )
621
622 # Jsonify the query params
623 query_params = _BaseIAMCredentialsRestTransport._BaseGenerateIdToken._get_query_params_json(
624 transcoded_request
625 )
626
627 if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
628 logging.DEBUG
629 ): # pragma: NO COVER
630 request_url = "{host}{uri}".format(
631 host=self._host, uri=transcoded_request["uri"]
632 )
633 method = transcoded_request["method"]
634 try:
635 request_payload = type(request).to_json(request)
636 except:
637 request_payload = None
638 http_request = {
639 "payload": request_payload,
640 "requestMethod": method,
641 "requestUrl": request_url,
642 "headers": dict(metadata),
643 }
644 _LOGGER.debug(
645 f"Sending request for google.iam.credentials_v1.IAMCredentialsClient.GenerateIdToken",
646 extra={
647 "serviceName": "google.iam.credentials.v1.IAMCredentials",
648 "rpcName": "GenerateIdToken",
649 "httpRequest": http_request,
650 "metadata": http_request["headers"],
651 },
652 )
653
654 # Send the request
655 response = IAMCredentialsRestTransport._GenerateIdToken._get_response(
656 self._host,
657 metadata,
658 query_params,
659 self._session,
660 timeout,
661 transcoded_request,
662 body,
663 )
664
665 # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
666 # subclass.
667 if response.status_code >= 400:
668 raise core_exceptions.from_http_response(response)
669
670 # Return the response
671 resp = common.GenerateIdTokenResponse()
672 pb_resp = common.GenerateIdTokenResponse.pb(resp)
673
674 json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True)
675
676 resp = self._interceptor.post_generate_id_token(resp)
677 response_metadata = [(k, str(v)) for k, v in response.headers.items()]
678 resp, _ = self._interceptor.post_generate_id_token_with_metadata(
679 resp, response_metadata
680 )
681 if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
682 logging.DEBUG
683 ): # pragma: NO COVER
684 try:
685 response_payload = common.GenerateIdTokenResponse.to_json(response)
686 except:
687 response_payload = None
688 http_response = {
689 "payload": response_payload,
690 "headers": dict(response.headers),
691 "status": response.status_code,
692 }
693 _LOGGER.debug(
694 "Received response for google.iam.credentials_v1.IAMCredentialsClient.generate_id_token",
695 extra={
696 "serviceName": "google.iam.credentials.v1.IAMCredentials",
697 "rpcName": "GenerateIdToken",
698 "metadata": http_response["headers"],
699 "httpResponse": http_response,
700 },
701 )
702 return resp
703
704 class _SignBlob(
705 _BaseIAMCredentialsRestTransport._BaseSignBlob, IAMCredentialsRestStub
706 ):
707 def __hash__(self):
708 return hash("IAMCredentialsRestTransport.SignBlob")
709
710 @staticmethod
711 def _get_response(
712 host,
713 metadata,
714 query_params,
715 session,
716 timeout,
717 transcoded_request,
718 body=None,
719 ):
720 uri = transcoded_request["uri"]
721 method = transcoded_request["method"]
722 headers = dict(metadata)
723 headers["Content-Type"] = "application/json"
724 response = getattr(session, method)(
725 "{host}{uri}".format(host=host, uri=uri),
726 timeout=timeout,
727 headers=headers,
728 params=rest_helpers.flatten_query_params(query_params, strict=True),
729 data=body,
730 )
731 return response
732
733 def __call__(
734 self,
735 request: common.SignBlobRequest,
736 *,
737 retry: OptionalRetry = gapic_v1.method.DEFAULT,
738 timeout: Optional[float] = None,
739 metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
740 ) -> common.SignBlobResponse:
741 r"""Call the sign blob method over HTTP.
742
743 Args:
744 request (~.common.SignBlobRequest):
745 The request object.
746 retry (google.api_core.retry.Retry): Designation of what errors, if any,
747 should be retried.
748 timeout (float): The timeout for this request.
749 metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
750 sent along with the request as metadata. Normally, each value must be of type `str`,
751 but for metadata keys ending with the suffix `-bin`, the corresponding values must
752 be of type `bytes`.
753
754 Returns:
755 ~.common.SignBlobResponse:
756
757 """
758
759 http_options = (
760 _BaseIAMCredentialsRestTransport._BaseSignBlob._get_http_options()
761 )
762
763 request, metadata = self._interceptor.pre_sign_blob(request, metadata)
764 transcoded_request = (
765 _BaseIAMCredentialsRestTransport._BaseSignBlob._get_transcoded_request(
766 http_options, request
767 )
768 )
769
770 body = (
771 _BaseIAMCredentialsRestTransport._BaseSignBlob._get_request_body_json(
772 transcoded_request
773 )
774 )
775
776 # Jsonify the query params
777 query_params = (
778 _BaseIAMCredentialsRestTransport._BaseSignBlob._get_query_params_json(
779 transcoded_request
780 )
781 )
782
783 if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
784 logging.DEBUG
785 ): # pragma: NO COVER
786 request_url = "{host}{uri}".format(
787 host=self._host, uri=transcoded_request["uri"]
788 )
789 method = transcoded_request["method"]
790 try:
791 request_payload = type(request).to_json(request)
792 except:
793 request_payload = None
794 http_request = {
795 "payload": request_payload,
796 "requestMethod": method,
797 "requestUrl": request_url,
798 "headers": dict(metadata),
799 }
800 _LOGGER.debug(
801 f"Sending request for google.iam.credentials_v1.IAMCredentialsClient.SignBlob",
802 extra={
803 "serviceName": "google.iam.credentials.v1.IAMCredentials",
804 "rpcName": "SignBlob",
805 "httpRequest": http_request,
806 "metadata": http_request["headers"],
807 },
808 )
809
810 # Send the request
811 response = IAMCredentialsRestTransport._SignBlob._get_response(
812 self._host,
813 metadata,
814 query_params,
815 self._session,
816 timeout,
817 transcoded_request,
818 body,
819 )
820
821 # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
822 # subclass.
823 if response.status_code >= 400:
824 raise core_exceptions.from_http_response(response)
825
826 # Return the response
827 resp = common.SignBlobResponse()
828 pb_resp = common.SignBlobResponse.pb(resp)
829
830 json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True)
831
832 resp = self._interceptor.post_sign_blob(resp)
833 response_metadata = [(k, str(v)) for k, v in response.headers.items()]
834 resp, _ = self._interceptor.post_sign_blob_with_metadata(
835 resp, response_metadata
836 )
837 if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
838 logging.DEBUG
839 ): # pragma: NO COVER
840 try:
841 response_payload = common.SignBlobResponse.to_json(response)
842 except:
843 response_payload = None
844 http_response = {
845 "payload": response_payload,
846 "headers": dict(response.headers),
847 "status": response.status_code,
848 }
849 _LOGGER.debug(
850 "Received response for google.iam.credentials_v1.IAMCredentialsClient.sign_blob",
851 extra={
852 "serviceName": "google.iam.credentials.v1.IAMCredentials",
853 "rpcName": "SignBlob",
854 "metadata": http_response["headers"],
855 "httpResponse": http_response,
856 },
857 )
858 return resp
859
860 class _SignJwt(
861 _BaseIAMCredentialsRestTransport._BaseSignJwt, IAMCredentialsRestStub
862 ):
863 def __hash__(self):
864 return hash("IAMCredentialsRestTransport.SignJwt")
865
866 @staticmethod
867 def _get_response(
868 host,
869 metadata,
870 query_params,
871 session,
872 timeout,
873 transcoded_request,
874 body=None,
875 ):
876 uri = transcoded_request["uri"]
877 method = transcoded_request["method"]
878 headers = dict(metadata)
879 headers["Content-Type"] = "application/json"
880 response = getattr(session, method)(
881 "{host}{uri}".format(host=host, uri=uri),
882 timeout=timeout,
883 headers=headers,
884 params=rest_helpers.flatten_query_params(query_params, strict=True),
885 data=body,
886 )
887 return response
888
889 def __call__(
890 self,
891 request: common.SignJwtRequest,
892 *,
893 retry: OptionalRetry = gapic_v1.method.DEFAULT,
894 timeout: Optional[float] = None,
895 metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
896 ) -> common.SignJwtResponse:
897 r"""Call the sign jwt method over HTTP.
898
899 Args:
900 request (~.common.SignJwtRequest):
901 The request object.
902 retry (google.api_core.retry.Retry): Designation of what errors, if any,
903 should be retried.
904 timeout (float): The timeout for this request.
905 metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
906 sent along with the request as metadata. Normally, each value must be of type `str`,
907 but for metadata keys ending with the suffix `-bin`, the corresponding values must
908 be of type `bytes`.
909
910 Returns:
911 ~.common.SignJwtResponse:
912
913 """
914
915 http_options = (
916 _BaseIAMCredentialsRestTransport._BaseSignJwt._get_http_options()
917 )
918
919 request, metadata = self._interceptor.pre_sign_jwt(request, metadata)
920 transcoded_request = (
921 _BaseIAMCredentialsRestTransport._BaseSignJwt._get_transcoded_request(
922 http_options, request
923 )
924 )
925
926 body = _BaseIAMCredentialsRestTransport._BaseSignJwt._get_request_body_json(
927 transcoded_request
928 )
929
930 # Jsonify the query params
931 query_params = (
932 _BaseIAMCredentialsRestTransport._BaseSignJwt._get_query_params_json(
933 transcoded_request
934 )
935 )
936
937 if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
938 logging.DEBUG
939 ): # pragma: NO COVER
940 request_url = "{host}{uri}".format(
941 host=self._host, uri=transcoded_request["uri"]
942 )
943 method = transcoded_request["method"]
944 try:
945 request_payload = type(request).to_json(request)
946 except:
947 request_payload = None
948 http_request = {
949 "payload": request_payload,
950 "requestMethod": method,
951 "requestUrl": request_url,
952 "headers": dict(metadata),
953 }
954 _LOGGER.debug(
955 f"Sending request for google.iam.credentials_v1.IAMCredentialsClient.SignJwt",
956 extra={
957 "serviceName": "google.iam.credentials.v1.IAMCredentials",
958 "rpcName": "SignJwt",
959 "httpRequest": http_request,
960 "metadata": http_request["headers"],
961 },
962 )
963
964 # Send the request
965 response = IAMCredentialsRestTransport._SignJwt._get_response(
966 self._host,
967 metadata,
968 query_params,
969 self._session,
970 timeout,
971 transcoded_request,
972 body,
973 )
974
975 # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
976 # subclass.
977 if response.status_code >= 400:
978 raise core_exceptions.from_http_response(response)
979
980 # Return the response
981 resp = common.SignJwtResponse()
982 pb_resp = common.SignJwtResponse.pb(resp)
983
984 json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True)
985
986 resp = self._interceptor.post_sign_jwt(resp)
987 response_metadata = [(k, str(v)) for k, v in response.headers.items()]
988 resp, _ = self._interceptor.post_sign_jwt_with_metadata(
989 resp, response_metadata
990 )
991 if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
992 logging.DEBUG
993 ): # pragma: NO COVER
994 try:
995 response_payload = common.SignJwtResponse.to_json(response)
996 except:
997 response_payload = None
998 http_response = {
999 "payload": response_payload,
1000 "headers": dict(response.headers),
1001 "status": response.status_code,
1002 }
1003 _LOGGER.debug(
1004 "Received response for google.iam.credentials_v1.IAMCredentialsClient.sign_jwt",
1005 extra={
1006 "serviceName": "google.iam.credentials.v1.IAMCredentials",
1007 "rpcName": "SignJwt",
1008 "metadata": http_response["headers"],
1009 "httpResponse": http_response,
1010 },
1011 )
1012 return resp
1013
1014 @property
1015 def generate_access_token(
1016 self,
1017 ) -> Callable[
1018 [common.GenerateAccessTokenRequest], common.GenerateAccessTokenResponse
1019 ]:
1020 # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
1021 # In C++ this would require a dynamic_cast
1022 return self._GenerateAccessToken(self._session, self._host, self._interceptor) # type: ignore
1023
1024 @property
1025 def generate_id_token(
1026 self,
1027 ) -> Callable[[common.GenerateIdTokenRequest], common.GenerateIdTokenResponse]:
1028 # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
1029 # In C++ this would require a dynamic_cast
1030 return self._GenerateIdToken(self._session, self._host, self._interceptor) # type: ignore
1031
1032 @property
1033 def sign_blob(self) -> Callable[[common.SignBlobRequest], common.SignBlobResponse]:
1034 # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
1035 # In C++ this would require a dynamic_cast
1036 return self._SignBlob(self._session, self._host, self._interceptor) # type: ignore
1037
1038 @property
1039 def sign_jwt(self) -> Callable[[common.SignJwtRequest], common.SignJwtResponse]:
1040 # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
1041 # In C++ this would require a dynamic_cast
1042 return self._SignJwt(self._session, self._host, self._interceptor) # type: ignore
1043
1044 @property
1045 def kind(self) -> str:
1046 return "rest"
1047
1048 def close(self):
1049 self._session.close()
1050
1051
1052__all__ = ("IAMCredentialsRestTransport",)