Skip to content

Commit d2b35b2

Browse files
authored
chore: librarian update image pull request: 20251216T231917Z (#14974)
feat: update image to us-central1-docker.pkg.dev/cloud-sdk-librarian-prod/images-prod/python-librarian-generator@sha256:b8058df4c45e9a6e07f6b4d65b458d0d059241dd34c814f151c8bf6b89211209 BEGIN_COMMIT BEGIN_NESTED_COMMIT feat: auto-enable mTLS when supported certificates are detected feat: check Python and dependency versions in generated GAPICs PiperOrigin-RevId: 845448683 Library-IDs: google-cloud-bigquery-storage,google-cloud-discoveryengine,google-cloud-secret-manager,google-cloud-speech Source-link: googleapis/googleapis@14967163 END_NESTED_COMMIT END_COMMIT
1 parent 02f36c1 commit d2b35b2

File tree

184 files changed

+21641
-6068
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

184 files changed

+21641
-6068
lines changed

.librarian/generator-input/client-post-processing/bigquery-storage-integration.yaml

Lines changed: 45 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -183,13 +183,12 @@ replacements:
183183
"ReadRowsStream",
184184
"ReadSession",
185185
count: 1
186-
# Given that this file is mostly handwritten, we could omit the file completely when we migrate to librarian
187-
# See `preserve_regex` in https://github.com/googleapis/librarian/blob/main/doc/language-onboarding.md#generate
186+
# Given that this file is mostly handwritten, we could omit the file during code generation
187+
# This will require a change to gapic-generator-python to provide the ability to omit files
188188
- paths: [
189189
packages/google-cloud-bigquery-storage/google/cloud/bigquery_storage_v1/__init__.py,
190190
]
191191
before: |
192-
__version__ = package_version.__version__\n\n
193192
from .services.big_query_read import BigQueryReadAsyncClient, BigQueryReadClient
194193
from .services.big_query_write import BigQueryWriteAsyncClient, BigQueryWriteClient
195194
from .types.arrow import ArrowRecordBatch, ArrowSchema, ArrowSerializationOptions
@@ -224,6 +223,19 @@ replacements:
224223
WriteStreamView,
225224
\)
226225
from .types.table import TableFieldSchema, TableSchema\n
226+
after: |
227+
from google.cloud.bigquery_storage_v1 import client, types\n\n
228+
class BigQueryReadClient(client.BigQueryReadClient):
229+
__doc__ = client.BigQueryReadClient.__doc__\n\n
230+
class BigQueryWriteClient(client.BigQueryWriteClient):
231+
__doc__ = client.BigQueryWriteClient.__doc__\n\n
232+
count: 1
233+
# Given that this file is mostly handwritten, we could omit the file during code generation
234+
# This will require a change to gapic-generator-python to provide the ability to omit files
235+
- paths: [
236+
packages/google-cloud-bigquery-storage/google/cloud/bigquery_storage_v1/__init__.py,
237+
]
238+
before: |
227239
__all__ = \(
228240
"BigQueryReadAsyncClient",
229241
"BigQueryWriteAsyncClient",
@@ -265,12 +277,6 @@ replacements:
265277
"WriteStreamView",
266278
\)
267279
after: |
268-
__version__ = package_version.__version__\n
269-
from google.cloud.bigquery_storage_v1 import client, types\n\n
270-
class BigQueryReadClient(client.BigQueryReadClient):
271-
__doc__ = client.BigQueryReadClient.__doc__\n\n
272-
class BigQueryWriteClient(client.BigQueryWriteClient):
273-
__doc__ = client.BigQueryWriteClient.__doc__\n\n
274280
__all__ = (
275281
# google.cloud.bigquery_storage_v1
276282
"__version__",
@@ -280,14 +286,13 @@ replacements:
280286
"BigQueryWriteClient",
281287
)
282288
count: 1
283-
# Given that this file is mostly handwritten, we could omit the file completely when we migrate to librarian
284-
# See `preserve_regex` in https://github.com/googleapis/librarian/blob/main/doc/language-onboarding.md#generate
289+
# Given that this file is mostly handwritten, we could omit the file during code generation
290+
# This will require a change to gapic-generator-python to provide the ability to omit files
285291
- paths: [
286292
packages/google-cloud-bigquery-storage/google/cloud/bigquery_storage_v1alpha/__init__.py,
287293
packages/google-cloud-bigquery-storage/google/cloud/bigquery_storage_v1beta/__init__.py,
288294
]
289295
before: |
290-
__version__ = package_version.__version__\n\n
291296
from .services.metastore_partition_service import \(
292297
MetastorePartitionServiceAsyncClient,
293298
MetastorePartitionServiceClient,
@@ -316,6 +321,16 @@ replacements:
316321
StorageDescriptor,
317322
StreamList,
318323
\)\n
324+
after: ""
325+
count: 2
326+
# Given that this file is mostly handwritten, we could omit the file during code generation
327+
# This will require a change to gapic-generator-python to provide the ability to omit files
328+
- paths: [
329+
packages/google-cloud-bigquery-storage/google/cloud/bigquery_storage_v1alpha/__init__.py,
330+
packages/google-cloud-bigquery-storage/google/cloud/bigquery_storage_v1beta/__init__.py,
331+
]
332+
before: |
333+
\)\n
319334
__all__ = \(
320335
"MetastorePartitionServiceAsyncClient",
321336
"BatchCreateMetastorePartitionsRequest",
@@ -341,15 +356,14 @@ replacements:
341356
"UpdateMetastorePartitionRequest",
342357
\)
343358
after: |
344-
__version__ = package_version.__version__
359+
)
345360
count: 2
346-
# Given that this file is mostly handwritten, we could omit the file completely when we migrate to librarian
347-
# See `preserve_regex` in https://github.com/googleapis/librarian/blob/main/doc/language-onboarding.md#generate
361+
# Given that this file is mostly handwritten, we could omit the file during code generation
362+
# This will require a change to gapic-generator-python to provide the ability to omit files
348363
- paths: [
349364
packages/google-cloud-bigquery-storage/google/cloud/bigquery_storage_v1beta2/__init__.py,
350365
]
351366
before: |
352-
__version__ = package_version.__version__\n\n
353367
from .services.big_query_read import BigQueryReadAsyncClient, BigQueryReadClient
354368
from .services.big_query_write import BigQueryWriteAsyncClient, BigQueryWriteClient
355369
from .types.arrow import ArrowRecordBatch, ArrowSchema, ArrowSerializationOptions
@@ -377,6 +391,19 @@ replacements:
377391
\)
378392
from .types.stream import DataFormat, ReadSession, ReadStream, WriteStream
379393
from .types.table import TableFieldSchema, TableSchema\n
394+
after: |
395+
from google.cloud.bigquery_storage_v1beta2 import client, types\n\n
396+
class BigQueryReadClient(client.BigQueryReadClient):
397+
__doc__ = client.BigQueryReadClient.__doc__\n\n
398+
class BigQueryWriteClient(client.BigQueryWriteClient):
399+
__doc__ = client.BigQueryWriteClient.__doc__\n\n
400+
count: 1
401+
# Given that this file is mostly handwritten, we could omit the file during code generation
402+
# This will require a change to gapic-generator-python to provide the ability to omit files
403+
- paths: [
404+
packages/google-cloud-bigquery-storage/google/cloud/bigquery_storage_v1beta2/__init__.py,
405+
]
406+
before: |
380407
__all__ = \(
381408
"BigQueryReadAsyncClient",
382409
"BigQueryWriteAsyncClient",
@@ -415,12 +442,6 @@ replacements:
415442
"WriteStream",
416443
\)
417444
after: |
418-
__version__ = package_version.__version__\n
419-
from google.cloud.bigquery_storage_v1beta2 import client, types\n\n
420-
class BigQueryReadClient(client.BigQueryReadClient):
421-
__doc__ = client.BigQueryReadClient.__doc__\n\n
422-
class BigQueryWriteClient(client.BigQueryWriteClient):
423-
__doc__ = client.BigQueryWriteClient.__doc__\n\n
424445
__all__ = (
425446
# google.cloud.bigquery_storage_v1beta2
426447
"__version__",
@@ -430,9 +451,6 @@ replacements:
430451
"BigQueryWriteClient",
431452
)
432453
count: 1
433-
# Given that this file is mostly handwritten, we could omit the file completely when we migrate to librarian
434-
# See `preserve_regex` in https://github.com/googleapis/librarian/blob/main/doc/language-onboarding.md#generate
435-
# We could also consider updating the docs/index.rst template so that the majority of handwritten changes are not required
436454
- paths: [
437455
packages/google-cloud-bigquery-storage/testing/constraints-3.7.txt,
438456
]
@@ -447,6 +465,8 @@ replacements:
447465
pyarrow==0.15.0
448466
google-auth==2.14.1
449467
count: 1
468+
# Given that this file is mostly handwritten, we could omit the file during code generation
469+
# This will require a change to gapic-generator-python to provide the ability to omit files
450470
- paths: [
451471
packages/google-cloud-bigquery-storage/docs/index.rst,
452472
]

.librarian/state.yaml

Lines 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:d7caef319a25d618e20ba798b103434700bfd80015f525802d87621ca2528c90
1+
image: us-central1-docker.pkg.dev/cloud-sdk-librarian-prod/images-prod/python-librarian-generator@sha256:b8058df4c45e9a6e07f6b4d65b458d0d059241dd34c814f151c8bf6b89211209
22
libraries:
33
- id: google-ads-admanager
44
version: 0.7.0

packages/google-cloud-bigquery-storage/google/cloud/bigquery_storage_v1/__init__.py

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,21 @@
1313
# See the License for the specific language governing permissions and
1414
# limitations under the License.
1515
#
16+
import sys
17+
18+
import google.api_core as api_core
19+
1620
from google.cloud.bigquery_storage_v1 import gapic_version as package_version
1721

1822
__version__ = package_version.__version__
1923

24+
if sys.version_info >= (3, 8): # pragma: NO COVER
25+
from importlib import metadata
26+
else: # 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+
2031
from google.cloud.bigquery_storage_v1 import client, types
2132

2233

@@ -28,6 +39,100 @@ class BigQueryWriteClient(client.BigQueryWriteClient):
2839
__doc__ = client.BigQueryWriteClient.__doc__
2940

3041

42+
if hasattr(api_core, "check_python_version") and hasattr(
43+
api_core, "check_dependency_versions"
44+
): # pragma: NO COVER
45+
api_core.check_python_version("google.cloud.bigquery_storage_v1") # type: ignore
46+
api_core.check_dependency_versions("google.cloud.bigquery_storage_v1") # type: ignore
47+
else: # pragma: NO COVER
48+
# An older version of api_core is installed which does not define the
49+
# functions above. We do equivalent checks manually.
50+
try:
51+
import sys
52+
import warnings
53+
54+
_py_version_str = sys.version.split()[0]
55+
_package_label = "google.cloud.bigquery_storage_v1"
56+
if sys.version_info < (3, 9):
57+
warnings.warn(
58+
"You are using a non-supported Python version "
59+
+ f"({_py_version_str}). Google will not post any further "
60+
+ f"updates to {_package_label} supporting this Python version. "
61+
+ "Please upgrade to the latest Python version, or at "
62+
+ f"least to Python 3.9, and then update {_package_label}.",
63+
FutureWarning,
64+
)
65+
if sys.version_info[:2] == (3, 9):
66+
warnings.warn(
67+
f"You are using a Python version ({_py_version_str}) "
68+
+ f"which Google will stop supporting in {_package_label} in "
69+
+ "January 2026. Please "
70+
+ "upgrade to the latest Python version, or at "
71+
+ "least to Python 3.10, before then, and "
72+
+ f"then update {_package_label}.",
73+
FutureWarning,
74+
)
75+
76+
def parse_version_to_tuple(version_string: str):
77+
"""Safely converts a semantic version string to a comparable tuple of integers.
78+
Example: "4.25.8" -> (4, 25, 8)
79+
Ignores non-numeric parts and handles common version formats.
80+
Args:
81+
version_string: Version string in the format "x.y.z" or "x.y.z<suffix>"
82+
Returns:
83+
Tuple of integers for the parsed version string.
84+
"""
85+
parts = []
86+
for part in version_string.split("."):
87+
try:
88+
parts.append(int(part))
89+
except ValueError:
90+
# If it's a non-numeric part (e.g., '1.0.0b1' -> 'b1'), stop here.
91+
# This is a simplification compared to 'packaging.parse_version', but sufficient
92+
# for comparing strictly numeric semantic versions.
93+
break
94+
return tuple(parts)
95+
96+
def _get_version(dependency_name):
97+
try:
98+
version_string: str = metadata.version(dependency_name)
99+
parsed_version = parse_version_to_tuple(version_string)
100+
return (parsed_version, version_string)
101+
except Exception:
102+
# Catch exceptions from metadata.version() (e.g., PackageNotFoundError)
103+
# or errors during parse_version_to_tuple
104+
return (None, "--")
105+
106+
_dependency_package = "google.protobuf"
107+
_next_supported_version = "4.25.8"
108+
_next_supported_version_tuple = (4, 25, 8)
109+
_recommendation = " (we recommend 6.x)"
110+
(_version_used, _version_used_string) = _get_version(_dependency_package)
111+
if _version_used and _version_used < _next_supported_version_tuple:
112+
warnings.warn(
113+
f"Package {_package_label} depends on "
114+
+ f"{_dependency_package}, currently installed at version "
115+
+ f"{_version_used_string}. Future updates to "
116+
+ f"{_package_label} will require {_dependency_package} at "
117+
+ f"version {_next_supported_version} or higher{_recommendation}."
118+
+ " Please ensure "
119+
+ "that either (a) your Python environment doesn't pin the "
120+
+ f"version of {_dependency_package}, so that updates to "
121+
+ f"{_package_label} can require the higher version, or "
122+
+ "(b) you manually update your Python environment to use at "
123+
+ f"least version {_next_supported_version} of "
124+
+ f"{_dependency_package}.",
125+
FutureWarning,
126+
)
127+
except Exception:
128+
warnings.warn(
129+
"Could not determine the version of Python "
130+
+ "currently being used. To continue receiving "
131+
+ "updates for {_package_label}, ensure you are "
132+
+ "using a supported version of Python; see "
133+
+ "https://devguide.python.org/versions/"
134+
)
135+
31136
__all__ = (
32137
# google.cloud.bigquery_storage_v1
33138
"__version__",

packages/google-cloud-bigquery-storage/google/cloud/bigquery_storage_v1/services/big_query_read/client.py

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,34 @@ def _get_default_mtls_endpoint(api_endpoint):
150150
_DEFAULT_ENDPOINT_TEMPLATE = "bigquerystorage.{UNIVERSE_DOMAIN}"
151151
_DEFAULT_UNIVERSE = "googleapis.com"
152152

153+
@staticmethod
154+
def _use_client_cert_effective():
155+
"""Returns whether client certificate should be used for mTLS if the
156+
google-auth version supports should_use_client_cert automatic mTLS enablement.
157+
158+
Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var.
159+
160+
Returns:
161+
bool: whether client certificate should be used for mTLS
162+
Raises:
163+
ValueError: (If using a version of google-auth without should_use_client_cert and
164+
GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.)
165+
"""
166+
# check if google-auth version supports should_use_client_cert for automatic mTLS enablement
167+
if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER
168+
return mtls.should_use_client_cert()
169+
else: # pragma: NO COVER
170+
# if unsupported, fallback to reading from env var
171+
use_client_cert_str = os.getenv(
172+
"GOOGLE_API_USE_CLIENT_CERTIFICATE", "false"
173+
).lower()
174+
if use_client_cert_str not in ("true", "false"):
175+
raise ValueError(
176+
"Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be"
177+
" either `true` or `false`"
178+
)
179+
return use_client_cert_str == "true"
180+
153181
@classmethod
154182
def from_service_account_info(cls, info: dict, *args, **kwargs):
155183
"""Creates an instance of this client using the provided credentials
@@ -383,20 +411,16 @@ def get_mtls_endpoint_and_cert_source(
383411
)
384412
if client_options is None:
385413
client_options = client_options_lib.ClientOptions()
386-
use_client_cert = os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false")
414+
use_client_cert = BigQueryReadClient._use_client_cert_effective()
387415
use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto")
388-
if use_client_cert not in ("true", "false"):
389-
raise ValueError(
390-
"Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`"
391-
)
392416
if use_mtls_endpoint not in ("auto", "never", "always"):
393417
raise MutualTLSChannelError(
394418
"Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`"
395419
)
396420

397421
# Figure out the client cert source to use.
398422
client_cert_source = None
399-
if use_client_cert == "true":
423+
if use_client_cert:
400424
if client_options.client_cert_source:
401425
client_cert_source = client_options.client_cert_source
402426
elif mtls.has_default_client_cert_source():
@@ -428,20 +452,14 @@ def _read_environment_variables():
428452
google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT
429453
is not any of ["auto", "never", "always"].
430454
"""
431-
use_client_cert = os.getenv(
432-
"GOOGLE_API_USE_CLIENT_CERTIFICATE", "false"
433-
).lower()
455+
use_client_cert = BigQueryReadClient._use_client_cert_effective()
434456
use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto").lower()
435457
universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN")
436-
if use_client_cert not in ("true", "false"):
437-
raise ValueError(
438-
"Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`"
439-
)
440458
if use_mtls_endpoint not in ("auto", "never", "always"):
441459
raise MutualTLSChannelError(
442460
"Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`"
443461
)
444-
return use_client_cert == "true", use_mtls_endpoint, universe_domain_env
462+
return use_client_cert, use_mtls_endpoint, universe_domain_env
445463

446464
@staticmethod
447465
def _get_client_cert_source(provided_cert_source, use_cert_flag):

0 commit comments

Comments
 (0)