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 sys
17
18import google.api_core as api_core
19
20from google.cloud.iam_credentials_v1 import gapic_version as package_version
21
22__version__ = package_version.__version__
23
24from importlib import metadata
25
26# PEP 0810: Explicit Lazy Imports
27# Python 3.15+ natively intercepts and defers these imports.
28# Developers can disable this behavior and force eager imports.
29# For more information, see:
30# https://docs.python.org/3.15/library/sys.html#sys.set_lazy_imports_filter
31# Older Python versions safely ignore this variable.
32__lazy_modules__ = {
33 "google.cloud.iam_credentials_v1.services.iam_credentials",
34 "google.cloud.iam_credentials_v1.types.common",
35 "google.cloud.iam_credentials_v1.types.iamcredentials",
36}
37
38
39from .services.iam_credentials import IAMCredentialsAsyncClient, IAMCredentialsClient
40from .types.common import (
41 GenerateAccessTokenRequest,
42 GenerateAccessTokenResponse,
43 GenerateIdTokenRequest,
44 GenerateIdTokenResponse,
45 SignBlobRequest,
46 SignBlobResponse,
47 SignJwtRequest,
48 SignJwtResponse,
49)
50
51if hasattr(api_core, "check_python_version") and hasattr(
52 api_core, "check_dependency_versions"
53): # pragma: NO COVER
54 api_core.check_python_version("google.cloud.iam_credentials_v1") # type: ignore
55 api_core.check_dependency_versions("google.cloud.iam_credentials_v1") # type: ignore
56else: # pragma: NO COVER
57 # An older version of api_core is installed which does not define the
58 # functions above. We do equivalent checks manually.
59 try:
60 import warnings
61
62 _py_version_str = sys.version.split()[0]
63 _package_label = "google.cloud.iam_credentials_v1"
64 if sys.version_info < (3, 10):
65 warnings.warn(
66 "You are using a non-supported Python version "
67 + f"({_py_version_str}). Google will not post any further "
68 + f"updates to {_package_label} supporting this Python version. "
69 + "Please upgrade to the latest Python version, or at "
70 + f"least to Python 3.10, and then update {_package_label}.",
71 FutureWarning,
72 )
73
74 def parse_version_to_tuple(version_string: str):
75 """Safely converts a semantic version string to a comparable tuple of integers.
76 Example: "6.33.5" -> (6, 33, 5)
77 Ignores non-numeric parts and handles common version formats.
78 Args:
79 version_string: Version string in the format "x.y.z" or "x.y.z<suffix>"
80 Returns:
81 Tuple of integers for the parsed version string.
82 """
83 parts = []
84 for part in version_string.split("."):
85 try:
86 parts.append(int(part))
87 except ValueError:
88 # If it's a non-numeric part (e.g., '1.0.0b1' -> 'b1'), stop here.
89 # This is a simplification compared to 'packaging.parse_version', but sufficient
90 # for comparing strictly numeric semantic versions.
91 break
92 return tuple(parts)
93
94 def _get_version(dependency_name):
95 try:
96 version_string: str = metadata.version(dependency_name)
97 parsed_version = parse_version_to_tuple(version_string)
98 return (parsed_version, version_string)
99 except Exception:
100 # Catch exceptions from metadata.version() (e.g., PackageNotFoundError)
101 # or errors during parse_version_to_tuple
102 return (None, "--")
103
104 _dependency_package = "google.protobuf"
105 _next_supported_version = "6.33.5"
106 _next_supported_version_tuple = (6, 33, 5)
107 _recommendation = " (we recommend 7.x)"
108 (_version_used, _version_used_string) = _get_version(_dependency_package)
109 if _version_used and _version_used < _next_supported_version_tuple:
110 warnings.warn(
111 f"Package {_package_label} depends on "
112 + f"{_dependency_package}, currently installed at version "
113 + f"{_version_used_string}. Future updates to "
114 + f"{_package_label} will require {_dependency_package} at "
115 + f"version {_next_supported_version} or higher{_recommendation}."
116 + " Please ensure "
117 + "that either (a) your Python environment doesn't pin the "
118 + f"version of {_dependency_package}, so that updates to "
119 + f"{_package_label} can require the higher version, or "
120 + "(b) you manually update your Python environment to use at "
121 + f"least version {_next_supported_version} of "
122 + f"{_dependency_package}.",
123 FutureWarning,
124 )
125 except Exception:
126 warnings.warn(
127 "Could not determine the version of Python "
128 + "currently being used. To continue receiving "
129 + "updates for {_package_label}, ensure you are "
130 + "using a supported version of Python; see "
131 + "https://devguide.python.org/versions/"
132 )
133
134__all__ = (
135 "IAMCredentialsAsyncClient",
136 "GenerateAccessTokenRequest",
137 "GenerateAccessTokenResponse",
138 "GenerateIdTokenRequest",
139 "GenerateIdTokenResponse",
140 "IAMCredentialsClient",
141 "SignBlobRequest",
142 "SignBlobResponse",
143 "SignJwtRequest",
144 "SignJwtResponse",
145)