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#
16import sys
17
18import google.api_core as api_core
19
20from google.cloud.resourcemanager_v3 import gapic_version as package_version
21
22__version__ = package_version.__version__
23
24if sys.version_info >= (3, 8): # pragma: NO COVER
25 from importlib import metadata
26else: # pragma: NO COVER
27 # TODO(https://github.com/googleapis/python-api-core/issues/835): Remove
28 # this code path once we drop support for Python 3.7
29 import importlib_metadata as metadata
30
31from .services.folders import FoldersAsyncClient, FoldersClient
32from .services.organizations import OrganizationsAsyncClient, OrganizationsClient
33from .services.projects import ProjectsAsyncClient, ProjectsClient
34from .services.tag_bindings import TagBindingsAsyncClient, TagBindingsClient
35from .services.tag_holds import TagHoldsAsyncClient, TagHoldsClient
36from .services.tag_keys import TagKeysAsyncClient, TagKeysClient
37from .services.tag_values import TagValuesAsyncClient, TagValuesClient
38from .types.folders import (
39 CreateFolderMetadata,
40 CreateFolderRequest,
41 DeleteFolderMetadata,
42 DeleteFolderRequest,
43 Folder,
44 GetFolderRequest,
45 ListFoldersRequest,
46 ListFoldersResponse,
47 MoveFolderMetadata,
48 MoveFolderRequest,
49 SearchFoldersRequest,
50 SearchFoldersResponse,
51 UndeleteFolderMetadata,
52 UndeleteFolderRequest,
53 UpdateFolderMetadata,
54 UpdateFolderRequest,
55)
56from .types.organizations import (
57 DeleteOrganizationMetadata,
58 GetOrganizationRequest,
59 Organization,
60 SearchOrganizationsRequest,
61 SearchOrganizationsResponse,
62 UndeleteOrganizationMetadata,
63)
64from .types.projects import (
65 CreateProjectMetadata,
66 CreateProjectRequest,
67 DeleteProjectMetadata,
68 DeleteProjectRequest,
69 GetProjectRequest,
70 ListProjectsRequest,
71 ListProjectsResponse,
72 MoveProjectMetadata,
73 MoveProjectRequest,
74 Project,
75 SearchProjectsRequest,
76 SearchProjectsResponse,
77 UndeleteProjectMetadata,
78 UndeleteProjectRequest,
79 UpdateProjectMetadata,
80 UpdateProjectRequest,
81)
82from .types.tag_bindings import (
83 CreateTagBindingMetadata,
84 CreateTagBindingRequest,
85 DeleteTagBindingMetadata,
86 DeleteTagBindingRequest,
87 EffectiveTag,
88 ListEffectiveTagsRequest,
89 ListEffectiveTagsResponse,
90 ListTagBindingsRequest,
91 ListTagBindingsResponse,
92 TagBinding,
93)
94from .types.tag_holds import (
95 CreateTagHoldMetadata,
96 CreateTagHoldRequest,
97 DeleteTagHoldMetadata,
98 DeleteTagHoldRequest,
99 ListTagHoldsRequest,
100 ListTagHoldsResponse,
101 TagHold,
102)
103from .types.tag_keys import (
104 CreateTagKeyMetadata,
105 CreateTagKeyRequest,
106 DeleteTagKeyMetadata,
107 DeleteTagKeyRequest,
108 GetNamespacedTagKeyRequest,
109 GetTagKeyRequest,
110 ListTagKeysRequest,
111 ListTagKeysResponse,
112 Purpose,
113 TagKey,
114 UpdateTagKeyMetadata,
115 UpdateTagKeyRequest,
116)
117from .types.tag_values import (
118 CreateTagValueMetadata,
119 CreateTagValueRequest,
120 DeleteTagValueMetadata,
121 DeleteTagValueRequest,
122 GetNamespacedTagValueRequest,
123 GetTagValueRequest,
124 ListTagValuesRequest,
125 ListTagValuesResponse,
126 TagValue,
127 UpdateTagValueMetadata,
128 UpdateTagValueRequest,
129)
130
131if hasattr(api_core, "check_python_version") and hasattr(
132 api_core, "check_dependency_versions"
133): # pragma: NO COVER
134 api_core.check_python_version("google.cloud.resourcemanager_v3") # type: ignore
135 api_core.check_dependency_versions("google.cloud.resourcemanager_v3") # type: ignore
136else: # pragma: NO COVER
137 # An older version of api_core is installed which does not define the
138 # functions above. We do equivalent checks manually.
139 try:
140 import sys
141 import warnings
142
143 _py_version_str = sys.version.split()[0]
144 _package_label = "google.cloud.resourcemanager_v3"
145 if sys.version_info < (3, 9):
146 warnings.warn(
147 "You are using a non-supported Python version "
148 + f"({_py_version_str}). Google will not post any further "
149 + f"updates to {_package_label} supporting this Python version. "
150 + "Please upgrade to the latest Python version, or at "
151 + f"least to Python 3.9, and then update {_package_label}.",
152 FutureWarning,
153 )
154 if sys.version_info[:2] == (3, 9):
155 warnings.warn(
156 f"You are using a Python version ({_py_version_str}) "
157 + f"which Google will stop supporting in {_package_label} in "
158 + "January 2026. Please "
159 + "upgrade to the latest Python version, or at "
160 + "least to Python 3.10, before then, and "
161 + f"then update {_package_label}.",
162 FutureWarning,
163 )
164
165 def parse_version_to_tuple(version_string: str):
166 """Safely converts a semantic version string to a comparable tuple of integers.
167 Example: "4.25.8" -> (4, 25, 8)
168 Ignores non-numeric parts and handles common version formats.
169 Args:
170 version_string: Version string in the format "x.y.z" or "x.y.z<suffix>"
171 Returns:
172 Tuple of integers for the parsed version string.
173 """
174 parts = []
175 for part in version_string.split("."):
176 try:
177 parts.append(int(part))
178 except ValueError:
179 # If it's a non-numeric part (e.g., '1.0.0b1' -> 'b1'), stop here.
180 # This is a simplification compared to 'packaging.parse_version', but sufficient
181 # for comparing strictly numeric semantic versions.
182 break
183 return tuple(parts)
184
185 def _get_version(dependency_name):
186 try:
187 version_string: str = metadata.version(dependency_name)
188 parsed_version = parse_version_to_tuple(version_string)
189 return (parsed_version, version_string)
190 except Exception:
191 # Catch exceptions from metadata.version() (e.g., PackageNotFoundError)
192 # or errors during parse_version_to_tuple
193 return (None, "--")
194
195 _dependency_package = "google.protobuf"
196 _next_supported_version = "4.25.8"
197 _next_supported_version_tuple = (4, 25, 8)
198 _recommendation = " (we recommend 6.x)"
199 (_version_used, _version_used_string) = _get_version(_dependency_package)
200 if _version_used and _version_used < _next_supported_version_tuple:
201 warnings.warn(
202 f"Package {_package_label} depends on "
203 + f"{_dependency_package}, currently installed at version "
204 + f"{_version_used_string}. Future updates to "
205 + f"{_package_label} will require {_dependency_package} at "
206 + f"version {_next_supported_version} or higher{_recommendation}."
207 + " Please ensure "
208 + "that either (a) your Python environment doesn't pin the "
209 + f"version of {_dependency_package}, so that updates to "
210 + f"{_package_label} can require the higher version, or "
211 + "(b) you manually update your Python environment to use at "
212 + f"least version {_next_supported_version} of "
213 + f"{_dependency_package}.",
214 FutureWarning,
215 )
216 except Exception:
217 warnings.warn(
218 "Could not determine the version of Python "
219 + "currently being used. To continue receiving "
220 + "updates for {_package_label}, ensure you are "
221 + "using a supported version of Python; see "
222 + "https://devguide.python.org/versions/"
223 )
224
225__all__ = (
226 "FoldersAsyncClient",
227 "OrganizationsAsyncClient",
228 "ProjectsAsyncClient",
229 "TagBindingsAsyncClient",
230 "TagHoldsAsyncClient",
231 "TagKeysAsyncClient",
232 "TagValuesAsyncClient",
233 "CreateFolderMetadata",
234 "CreateFolderRequest",
235 "CreateProjectMetadata",
236 "CreateProjectRequest",
237 "CreateTagBindingMetadata",
238 "CreateTagBindingRequest",
239 "CreateTagHoldMetadata",
240 "CreateTagHoldRequest",
241 "CreateTagKeyMetadata",
242 "CreateTagKeyRequest",
243 "CreateTagValueMetadata",
244 "CreateTagValueRequest",
245 "DeleteFolderMetadata",
246 "DeleteFolderRequest",
247 "DeleteOrganizationMetadata",
248 "DeleteProjectMetadata",
249 "DeleteProjectRequest",
250 "DeleteTagBindingMetadata",
251 "DeleteTagBindingRequest",
252 "DeleteTagHoldMetadata",
253 "DeleteTagHoldRequest",
254 "DeleteTagKeyMetadata",
255 "DeleteTagKeyRequest",
256 "DeleteTagValueMetadata",
257 "DeleteTagValueRequest",
258 "EffectiveTag",
259 "Folder",
260 "FoldersClient",
261 "GetFolderRequest",
262 "GetNamespacedTagKeyRequest",
263 "GetNamespacedTagValueRequest",
264 "GetOrganizationRequest",
265 "GetProjectRequest",
266 "GetTagKeyRequest",
267 "GetTagValueRequest",
268 "ListEffectiveTagsRequest",
269 "ListEffectiveTagsResponse",
270 "ListFoldersRequest",
271 "ListFoldersResponse",
272 "ListProjectsRequest",
273 "ListProjectsResponse",
274 "ListTagBindingsRequest",
275 "ListTagBindingsResponse",
276 "ListTagHoldsRequest",
277 "ListTagHoldsResponse",
278 "ListTagKeysRequest",
279 "ListTagKeysResponse",
280 "ListTagValuesRequest",
281 "ListTagValuesResponse",
282 "MoveFolderMetadata",
283 "MoveFolderRequest",
284 "MoveProjectMetadata",
285 "MoveProjectRequest",
286 "Organization",
287 "OrganizationsClient",
288 "Project",
289 "ProjectsClient",
290 "Purpose",
291 "SearchFoldersRequest",
292 "SearchFoldersResponse",
293 "SearchOrganizationsRequest",
294 "SearchOrganizationsResponse",
295 "SearchProjectsRequest",
296 "SearchProjectsResponse",
297 "TagBinding",
298 "TagBindingsClient",
299 "TagHold",
300 "TagHoldsClient",
301 "TagKey",
302 "TagKeysClient",
303 "TagValue",
304 "TagValuesClient",
305 "UndeleteFolderMetadata",
306 "UndeleteFolderRequest",
307 "UndeleteOrganizationMetadata",
308 "UndeleteProjectMetadata",
309 "UndeleteProjectRequest",
310 "UpdateFolderMetadata",
311 "UpdateFolderRequest",
312 "UpdateProjectMetadata",
313 "UpdateProjectRequest",
314 "UpdateTagKeyMetadata",
315 "UpdateTagKeyRequest",
316 "UpdateTagValueMetadata",
317 "UpdateTagValueRequest",
318)