Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings
This repository was archived by the owner on Apr 1, 2026. It is now read-only.

Commit ca20219

Browse filesBrowse files
feat(gapic): support mTLS certificates when available (#1249)
feat: update image to us-central1-docker.pkg.dev/cloud-sdk-librarian-prod/images-prod/python-librarian-generator@sha256:b8058df4c45e9a6e07f6b4d65b458d0d059241dd34c814f151c8bf6b89211209
1 parent 544db1c commit ca20219
Copy full SHA for ca20219

14 files changed

+993-562Lines changed: 993 additions & 562 deletions

File tree

Expand file treeCollapse file tree
Open diff view settings
Filter options
Expand file treeCollapse file tree
Open diff view settings
Collapse file

‎.librarian/generator-input/setup.py‎

Copy file name to clipboardExpand all lines: .librarian/generator-input/setup.py
-4Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -94,10 +94,6 @@
9494
packages=packages,
9595
install_requires=dependencies,
9696
extras_require=extras,
97-
scripts=[
98-
"scripts/fixup_bigtable_v2_keywords.py",
99-
"scripts/fixup_admin_v2_keywords.py",
100-
],
10197
python_requires=">=3.7",
10298
include_package_data=True,
10399
zip_safe=False,
Collapse file

‎.librarian/state.yaml‎

Copy file name to clipboardExpand all lines: .librarian/state.yaml
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
image: us-central1-docker.pkg.dev/cloud-sdk-librarian-prod/images-prod/python-librarian-generator@sha256:8e2c32496077054105bd06c54a59d6a6694287bc053588e24debe6da6920ad91
1+
image: us-central1-docker.pkg.dev/cloud-sdk-librarian-prod/images-prod/python-librarian-generator@sha256:b8058df4c45e9a6e07f6b4d65b458d0d059241dd34c814f151c8bf6b89211209
22
libraries:
33
- id: google-cloud-bigtable
44
version: 2.34.0
Collapse file

‎google/cloud/bigtable_admin_v2/__init__.py‎

Copy file name to clipboardExpand all lines: google/cloud/bigtable_admin_v2/__init__.py
+104Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,18 @@
1515
#
1616
from google.cloud.bigtable_admin_v2 import gapic_version as package_version
1717

18+
import google.api_core as api_core
19+
import sys
20+
1821
__version__ = package_version.__version__
1922

23+
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+
2030

2131
from .services.bigtable_instance_admin import BigtableInstanceAdminClient
2232
from .services.bigtable_instance_admin import BigtableInstanceAdminAsyncClient
@@ -143,6 +153,100 @@
143153
from .types.table import RestoreSourceType
144154
from .types.types import Type
145155

156+
if hasattr(api_core, "check_python_version") and hasattr(
157+
api_core, "check_dependency_versions"
158+
): # pragma: NO COVER
159+
api_core.check_python_version("google.cloud.bigtable_admin_v2") # type: ignore
160+
api_core.check_dependency_versions("google.cloud.bigtable_admin_v2") # type: ignore
161+
else: # pragma: NO COVER
162+
# An older version of api_core is installed which does not define the
163+
# functions above. We do equivalent checks manually.
164+
try:
165+
import warnings
166+
import sys
167+
168+
_py_version_str = sys.version.split()[0]
169+
_package_label = "google.cloud.bigtable_admin_v2"
170+
if sys.version_info < (3, 9):
171+
warnings.warn(
172+
"You are using a non-supported Python version "
173+
+ f"({_py_version_str}). Google will not post any further "
174+
+ f"updates to {_package_label} supporting this Python version. "
175+
+ "Please upgrade to the latest Python version, or at "
176+
+ f"least to Python 3.9, and then update {_package_label}.",
177+
FutureWarning,
178+
)
179+
if sys.version_info[:2] == (3, 9):
180+
warnings.warn(
181+
f"You are using a Python version ({_py_version_str}) "
182+
+ f"which Google will stop supporting in {_package_label} in "
183+
+ "January 2026. Please "
184+
+ "upgrade to the latest Python version, or at "
185+
+ "least to Python 3.10, before then, and "
186+
+ f"then update {_package_label}.",
187+
FutureWarning,
188+
)
189+
190+
def parse_version_to_tuple(version_string: str):
191+
"""Safely converts a semantic version string to a comparable tuple of integers.
192+
Example: "4.25.8" -> (4, 25, 8)
193+
Ignores non-numeric parts and handles common version formats.
194+
Args:
195+
version_string: Version string in the format "x.y.z" or "x.y.z<suffix>"
196+
Returns:
197+
Tuple of integers for the parsed version string.
198+
"""
199+
parts = []
200+
for part in version_string.split("."):
201+
try:
202+
parts.append(int(part))
203+
except ValueError:
204+
# If it's a non-numeric part (e.g., '1.0.0b1' -> 'b1'), stop here.
205+
# This is a simplification compared to 'packaging.parse_version', but sufficient
206+
# for comparing strictly numeric semantic versions.
207+
break
208+
return tuple(parts)
209+
210+
def _get_version(dependency_name):
211+
try:
212+
version_string: str = metadata.version(dependency_name)
213+
parsed_version = parse_version_to_tuple(version_string)
214+
return (parsed_version, version_string)
215+
except Exception:
216+
# Catch exceptions from metadata.version() (e.g., PackageNotFoundError)
217+
# or errors during parse_version_to_tuple
218+
return (None, "--")
219+
220+
_dependency_package = "google.protobuf"
221+
_next_supported_version = "4.25.8"
222+
_next_supported_version_tuple = (4, 25, 8)
223+
_recommendation = " (we recommend 6.x)"
224+
(_version_used, _version_used_string) = _get_version(_dependency_package)
225+
if _version_used and _version_used < _next_supported_version_tuple:
226+
warnings.warn(
227+
f"Package {_package_label} depends on "
228+
+ f"{_dependency_package}, currently installed at version "
229+
+ f"{_version_used_string}. Future updates to "
230+
+ f"{_package_label} will require {_dependency_package} at "
231+
+ f"version {_next_supported_version} or higher{_recommendation}."
232+
+ " Please ensure "
233+
+ "that either (a) your Python environment doesn't pin the "
234+
+ f"version of {_dependency_package}, so that updates to "
235+
+ f"{_package_label} can require the higher version, or "
236+
+ "(b) you manually update your Python environment to use at "
237+
+ f"least version {_next_supported_version} of "
238+
+ f"{_dependency_package}.",
239+
FutureWarning,
240+
)
241+
except Exception:
242+
warnings.warn(
243+
"Could not determine the version of Python "
244+
+ "currently being used. To continue receiving "
245+
+ "updates for {_package_label}, ensure you are "
246+
+ "using a supported version of Python; see "
247+
+ "https://devguide.python.org/versions/"
248+
)
249+
146250
__all__ = (
147251
"BaseBigtableTableAdminAsyncClient",
148252
"BigtableInstanceAdminAsyncClient",
Collapse file

‎google/cloud/bigtable_admin_v2/services/bigtable_instance_admin/client.py‎

Copy file name to clipboardExpand all lines: google/cloud/bigtable_admin_v2/services/bigtable_instance_admin/client.py
+32-14Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,34 @@ def _get_default_mtls_endpoint(api_endpoint):
161161
_DEFAULT_ENDPOINT_TEMPLATE = "bigtableadmin.{UNIVERSE_DOMAIN}"
162162
_DEFAULT_UNIVERSE = "googleapis.com"
163163

164+
@staticmethod
165+
def _use_client_cert_effective():
166+
"""Returns whether client certificate should be used for mTLS if the
167+
google-auth version supports should_use_client_cert automatic mTLS enablement.
168+
169+
Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var.
170+
171+
Returns:
172+
bool: whether client certificate should be used for mTLS
173+
Raises:
174+
ValueError: (If using a version of google-auth without should_use_client_cert and
175+
GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.)
176+
"""
177+
# check if google-auth version supports should_use_client_cert for automatic mTLS enablement
178+
if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER
179+
return mtls.should_use_client_cert()
180+
else: # pragma: NO COVER
181+
# if unsupported, fallback to reading from env var
182+
use_client_cert_str = os.getenv(
183+
"GOOGLE_API_USE_CLIENT_CERTIFICATE", "false"
184+
).lower()
185+
if use_client_cert_str not in ("true", "false"):
186+
raise ValueError(
187+
"Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be"
188+
" either `true` or `false`"
189+
)
190+
return use_client_cert_str == "true"
191+
164192
@classmethod
165193
def from_service_account_info(cls, info: dict, *args, **kwargs):
166194
"""Creates an instance of this client using the provided credentials
@@ -503,20 +531,16 @@ def get_mtls_endpoint_and_cert_source(
503531
)
504532
if client_options is None:
505533
client_options = client_options_lib.ClientOptions()
506-
use_client_cert = os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false")
534+
use_client_cert = BigtableInstanceAdminClient._use_client_cert_effective()
507535
use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto")
508-
if use_client_cert not in ("true", "false"):
509-
raise ValueError(
510-
"Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`"
511-
)
512536
if use_mtls_endpoint not in ("auto", "never", "always"):
513537
raise MutualTLSChannelError(
514538
"Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`"
515539
)
516540

517541
# Figure out the client cert source to use.
518542
client_cert_source = None
519-
if use_client_cert == "true":
543+
if use_client_cert:
520544
if client_options.client_cert_source:
521545
client_cert_source = client_options.client_cert_source
522546
elif mtls.has_default_client_cert_source():
@@ -548,20 +572,14 @@ def _read_environment_variables():
548572
google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT
549573
is not any of ["auto", "never", "always"].
550574
"""
551-
use_client_cert = os.getenv(
552-
"GOOGLE_API_USE_CLIENT_CERTIFICATE", "false"
553-
).lower()
575+
use_client_cert = BigtableInstanceAdminClient._use_client_cert_effective()
554576
use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto").lower()
555577
universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN")
556-
if use_client_cert not in ("true", "false"):
557-
raise ValueError(
558-
"Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`"
559-
)
560578
if use_mtls_endpoint not in ("auto", "never", "always"):
561579
raise MutualTLSChannelError(
562580
"Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`"
563581
)
564-
return use_client_cert == "true", use_mtls_endpoint, universe_domain_env
582+
return use_client_cert, use_mtls_endpoint, universe_domain_env
565583

566584
@staticmethod
567585
def _get_client_cert_source(provided_cert_source, use_cert_flag):
Collapse file

‎google/cloud/bigtable_admin_v2/services/bigtable_table_admin/client.py‎

Copy file name to clipboardExpand all lines: google/cloud/bigtable_admin_v2/services/bigtable_table_admin/client.py
+32-14Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,34 @@ def _get_default_mtls_endpoint(api_endpoint):
162162
_DEFAULT_ENDPOINT_TEMPLATE = "bigtableadmin.{UNIVERSE_DOMAIN}"
163163
_DEFAULT_UNIVERSE = "googleapis.com"
164164

165+
@staticmethod
166+
def _use_client_cert_effective():
167+
"""Returns whether client certificate should be used for mTLS if the
168+
google-auth version supports should_use_client_cert automatic mTLS enablement.
169+
170+
Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var.
171+
172+
Returns:
173+
bool: whether client certificate should be used for mTLS
174+
Raises:
175+
ValueError: (If using a version of google-auth without should_use_client_cert and
176+
GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.)
177+
"""
178+
# check if google-auth version supports should_use_client_cert for automatic mTLS enablement
179+
if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER
180+
return mtls.should_use_client_cert()
181+
else: # pragma: NO COVER
182+
# if unsupported, fallback to reading from env var
183+
use_client_cert_str = os.getenv(
184+
"GOOGLE_API_USE_CLIENT_CERTIFICATE", "false"
185+
).lower()
186+
if use_client_cert_str not in ("true", "false"):
187+
raise ValueError(
188+
"Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be"
189+
" either `true` or `false`"
190+
)
191+
return use_client_cert_str == "true"
192+
165193
@classmethod
166194
def from_service_account_info(cls, info: dict, *args, **kwargs):
167195
"""Creates an instance of this client using the provided credentials
@@ -510,20 +538,16 @@ def get_mtls_endpoint_and_cert_source(
510538
)
511539
if client_options is None:
512540
client_options = client_options_lib.ClientOptions()
513-
use_client_cert = os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false")
541+
use_client_cert = BaseBigtableTableAdminClient._use_client_cert_effective()
514542
use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto")
515-
if use_client_cert not in ("true", "false"):
516-
raise ValueError(
517-
"Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`"
518-
)
519543
if use_mtls_endpoint not in ("auto", "never", "always"):
520544
raise MutualTLSChannelError(
521545
"Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`"
522546
)
523547

524548
# Figure out the client cert source to use.
525549
client_cert_source = None
526-
if use_client_cert == "true":
550+
if use_client_cert:
527551
if client_options.client_cert_source:
528552
client_cert_source = client_options.client_cert_source
529553
elif mtls.has_default_client_cert_source():
@@ -555,20 +579,14 @@ def _read_environment_variables():
555579
google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT
556580
is not any of ["auto", "never", "always"].
557581
"""
558-
use_client_cert = os.getenv(
559-
"GOOGLE_API_USE_CLIENT_CERTIFICATE", "false"
560-
).lower()
582+
use_client_cert = BaseBigtableTableAdminClient._use_client_cert_effective()
561583
use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto").lower()
562584
universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN")
563-
if use_client_cert not in ("true", "false"):
564-
raise ValueError(
565-
"Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`"
566-
)
567585
if use_mtls_endpoint not in ("auto", "never", "always"):
568586
raise MutualTLSChannelError(
569587
"Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`"
570588
)
571-
return use_client_cert == "true", use_mtls_endpoint, universe_domain_env
589+
return use_client_cert, use_mtls_endpoint, universe_domain_env
572590

573591
@staticmethod
574592
def _get_client_cert_source(provided_cert_source, use_cert_flag):

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.