feat(gapic): support mTLS certificates when available (#1467) · googleapis/python-spanner@df87c3e
@@ -15,8 +15,18 @@
1515#
1616from google.cloud.spanner_admin_database_v1 import gapic_version as package_version
171718+import google.api_core as api_core
19+import sys
20+1821__version__ = package_version.__version__
192223+if sys.version_info >= (3, 8): # pragma: NO COVER
24+from importlib import metadata
25+else: # pragma: NO COVER
26+# TODO(https://github.com/googleapis/python-api-core/issues/835): Remove
27+# this code path once we drop support for Python 3.7
28+import importlib_metadata as metadata
29+20302131from .services.database_admin import DatabaseAdminClient
2232from .services.database_admin import DatabaseAdminAsyncClient
8393from .types.spanner_database_admin import UpdateDatabaseRequest
8494from .types.spanner_database_admin import RestoreSourceType
859596+if hasattr(api_core, "check_python_version") and hasattr(
97+api_core, "check_dependency_versions"
98+): # pragma: NO COVER
99+api_core.check_python_version("google.cloud.spanner_admin_database_v1") # type: ignore
100+api_core.check_dependency_versions("google.cloud.spanner_admin_database_v1") # type: ignore
101+else: # pragma: NO COVER
102+# An older version of api_core is installed which does not define the
103+# functions above. We do equivalent checks manually.
104+try:
105+import warnings
106+import sys
107+108+_py_version_str = sys.version.split()[0]
109+_package_label = "google.cloud.spanner_admin_database_v1"
110+if sys.version_info < (3, 9):
111+warnings.warn(
112+"You are using a non-supported Python version "
113++ f"({_py_version_str}). Google will not post any further "
114++ f"updates to {_package_label} supporting this Python version. "
115++ "Please upgrade to the latest Python version, or at "
116++ f"least to Python 3.9, and then update {_package_label}.",
117+FutureWarning,
118+ )
119+if sys.version_info[:2] == (3, 9):
120+warnings.warn(
121+f"You are using a Python version ({_py_version_str}) "
122++ f"which Google will stop supporting in {_package_label} in "
123++ "January 2026. Please "
124++ "upgrade to the latest Python version, or at "
125++ "least to Python 3.10, before then, and "
126++ f"then update {_package_label}.",
127+FutureWarning,
128+ )
129+130+def parse_version_to_tuple(version_string: str):
131+"""Safely converts a semantic version string to a comparable tuple of integers.
132+ Example: "4.25.8" -> (4, 25, 8)
133+ Ignores non-numeric parts and handles common version formats.
134+ Args:
135+ version_string: Version string in the format "x.y.z" or "x.y.z<suffix>"
136+ Returns:
137+ Tuple of integers for the parsed version string.
138+ """
139+parts = []
140+for part in version_string.split("."):
141+try:
142+parts.append(int(part))
143+except ValueError:
144+# If it's a non-numeric part (e.g., '1.0.0b1' -> 'b1'), stop here.
145+# This is a simplification compared to 'packaging.parse_version', but sufficient
146+# for comparing strictly numeric semantic versions.
147+break
148+return tuple(parts)
149+150+def _get_version(dependency_name):
151+try:
152+version_string: str = metadata.version(dependency_name)
153+parsed_version = parse_version_to_tuple(version_string)
154+return (parsed_version, version_string)
155+except Exception:
156+# Catch exceptions from metadata.version() (e.g., PackageNotFoundError)
157+# or errors during parse_version_to_tuple
158+return (None, "--")
159+160+_dependency_package = "google.protobuf"
161+_next_supported_version = "4.25.8"
162+_next_supported_version_tuple = (4, 25, 8)
163+_recommendation = " (we recommend 6.x)"
164+ (_version_used, _version_used_string) = _get_version(_dependency_package)
165+if _version_used and _version_used < _next_supported_version_tuple:
166+warnings.warn(
167+f"Package {_package_label} depends on "
168++ f"{_dependency_package}, currently installed at version "
169++ f"{_version_used_string}. Future updates to "
170++ f"{_package_label} will require {_dependency_package} at "
171++ f"version {_next_supported_version} or higher{_recommendation}."
172++ " Please ensure "
173++ "that either (a) your Python environment doesn't pin the "
174++ f"version of {_dependency_package}, so that updates to "
175++ f"{_package_label} can require the higher version, or "
176++ "(b) you manually update your Python environment to use at "
177++ f"least version {_next_supported_version} of "
178++ f"{_dependency_package}.",
179+FutureWarning,
180+ )
181+except Exception:
182+warnings.warn(
183+"Could not determine the version of Python "
184++ "currently being used. To continue receiving "
185++ "updates for {_package_label}, ensure you are "
186++ "using a supported version of Python; see "
187++ "https://devguide.python.org/versions/"
188+ )
189+86190__all__ = (
87191"DatabaseAdminAsyncClient",
88192"AddSplitPointsRequest",