Skip to content

Conversation

@parthea
Copy link
Contributor

@parthea parthea commented Dec 16, 2025

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

…prod/images-prod/python-librarian-generator@sha256:b8058df4c45e9a6e07f6b4d65b458d0d059241dd34c814f151c8bf6b89211209
@parthea parthea requested review from a team as code owners December 16, 2025 23:20
@parthea parthea requested a review from suzmue December 16, 2025 23:20
@gemini-code-assist
Copy link

Summary of Changes

Hello @parthea, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request updates the underlying librarian image used for generating Python client libraries. This update brings significant changes to how Python version and dependency compatibility are enforced at runtime, and refactors the logic for handling mTLS client certificates across multiple BigQuery Storage and Discovery Engine services. The removal of several keyword fixup scripts indicates an improvement in the code generation process, making these manual adjustments obsolete.

Highlights

  • Librarian Image Update: The core change involves updating the python-librarian-generator image to a new SHA256 hash in .librarian/state.yaml. This update triggers subsequent code generation changes across the client libraries.
  • Python Version and Dependency Checks: New runtime checks for Python versions (specifically for 3.9 and 3.10 support) and google.protobuf dependency versions have been added to the __init__.py files of various BigQuery Storage and Discovery Engine client libraries. These checks include a fallback mechanism for older api_core versions.
  • mTLS Client Certificate Handling Refactor: A new static method _use_client_cert_effective() has been introduced in numerous client service files (e.g., big_query_read/client.py, assistant_service/client.py). This method centralizes the logic for determining whether mTLS client certificates should be used, either by checking google-auth's should_use_client_cert or falling back to environment variables. Related environment variable parsing logic has been updated to use this new method.
  • Removal of Keyword Fixup Scripts: Several fixup_*.py scripts related to BigQuery Storage and Discovery Engine, which were likely used to address specific keyword-related issues in generated code, have been removed. This suggests that the underlying code generation process or the issues themselves have been resolved by the updated librarian image.
  • Test Updates: Unit tests for various client services have been updated to accommodate the new mTLS client certificate handling logic and the _use_client_cert_effective() method, ensuring proper functionality and error handling.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates the librarian generator image and applies the resulting code changes. The changes primarily involve:

  • Adding Python and dependency version checks in __init__.py files.
  • Refactoring mTLS client certificate handling for consistency and to support automatic mTLS enablement from google-auth.
  • Removing obsolete fixup scripts.

The changes are mostly automated and look good. I've identified a couple of minor issues in the newly generated version-checking code that are present across multiple packages. I've added comments on each occurrence for completeness, but the issues are the same:

  1. The _package_label variable is defined within a try block but used in the corresponding except block, which could lead to a NameError and mask the original exception.
  2. The custom parse_version_to_tuple function does not correctly handle pre-release versions, which could result in missed warnings for users.

Addressing these in the generator would prevent them from propagating to other libraries. Otherwise, the refactoring of mTLS logic and test updates are solid improvements.

Comment on lines +50 to +55
try:
import sys
import warnings

_py_version_str = sys.version.split()[0]
_package_label = "google.cloud.bigquery_storage_v1"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The _package_label variable is defined inside the try block but is also used in the except block. If an exception occurs before _package_label is assigned (e.g., during an import), a NameError will be raised within the except block, which can hide the original error. To make the error handling more robust, it's better to define _package_label before the try block. This issue is present in other __init__.py files in this PR.

Suggested change
try:
import sys
import warnings
_py_version_str = sys.version.split()[0]
_package_label = "google.cloud.bigquery_storage_v1"
_package_label = "google.cloud.bigquery_storage_v1"
try:
import sys
import warnings
_py_version_str = sys.version.split()[0]

Comment on lines +76 to +94
def parse_version_to_tuple(version_string: str):
"""Safely converts a semantic version string to a comparable tuple of integers.
Example: "4.25.8" -> (4, 25, 8)
Ignores non-numeric parts and handles common version formats.
Args:
version_string: Version string in the format "x.y.z" or "x.y.z<suffix>"
Returns:
Tuple of integers for the parsed version string.
"""
parts = []
for part in version_string.split("."):
try:
parts.append(int(part))
except ValueError:
# If it's a non-numeric part (e.g., '1.0.0b1' -> 'b1'), stop here.
# This is a simplification compared to 'packaging.parse_version', but sufficient
# for comparing strictly numeric semantic versions.
break
return tuple(parts)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The parse_version_to_tuple function is a simplification that doesn't handle pre-release identifiers correctly. For example, a version like "4.25.8b1" would be parsed as (4, 25, 8), which is not less than (4, 25, 8). However, 4.25.8b1 is a pre-release of 4.25.8 and should be considered older. This could lead to missing warnings for users on pre-release versions. Consider using packaging.version.parse for a more robust version comparison. While this might add a dependency, packaging is a standard library for this purpose and is often available in environments with setuptools.

Comment on lines +39 to +44
try:
import sys
import warnings

_py_version_str = sys.version.split()[0]
_package_label = "google.cloud.bigquery_storage_v1alpha"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The _package_label variable is defined inside the try block but is also used in the except block. If an exception occurs before _package_label is assigned, a NameError will be raised within the except block. To make the error handling more robust, _package_label should be defined before the try block.

Suggested change
try:
import sys
import warnings
_py_version_str = sys.version.split()[0]
_package_label = "google.cloud.bigquery_storage_v1alpha"
_package_label = "google.cloud.bigquery_storage_v1alpha"
try:
import sys
import warnings
_py_version_str = sys.version.split()[0]

Comment on lines +65 to +83
def parse_version_to_tuple(version_string: str):
"""Safely converts a semantic version string to a comparable tuple of integers.
Example: "4.25.8" -> (4, 25, 8)
Ignores non-numeric parts and handles common version formats.
Args:
version_string: Version string in the format "x.y.z" or "x.y.z<suffix>"
Returns:
Tuple of integers for the parsed version string.
"""
parts = []
for part in version_string.split("."):
try:
parts.append(int(part))
except ValueError:
# If it's a non-numeric part (e.g., '1.0.0b1' -> 'b1'), stop here.
# This is a simplification compared to 'packaging.parse_version', but sufficient
# for comparing strictly numeric semantic versions.
break
return tuple(parts)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The parse_version_to_tuple function is a simplification that doesn't handle pre-release identifiers correctly. For example, a version like "4.25.8b1" would be parsed as (4, 25, 8), which is not less than (4, 25, 8). However, 4.25.8b1 is a pre-release of 4.25.8 and should be considered older. This could lead to missing warnings for users on pre-release versions. Consider using packaging.version.parse for a more robust version comparison. While this might add a dependency, packaging is a standard library for this purpose and is often available in environments with setuptools.

Comment on lines +39 to +44
try:
import sys
import warnings

_py_version_str = sys.version.split()[0]
_package_label = "google.cloud.bigquery_storage_v1beta"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The _package_label variable is defined inside the try block but is also used in the except block. If an exception occurs before _package_label is assigned, a NameError will be raised within the except block. To make the error handling more robust, _package_label should be defined before the try block.

Suggested change
try:
import sys
import warnings
_py_version_str = sys.version.split()[0]
_package_label = "google.cloud.bigquery_storage_v1beta"
_package_label = "google.cloud.bigquery_storage_v1beta"
try:
import sys
import warnings
_py_version_str = sys.version.split()[0]

Comment on lines +387 to +405
def parse_version_to_tuple(version_string: str):
"""Safely converts a semantic version string to a comparable tuple of integers.
Example: "4.25.8" -> (4, 25, 8)
Ignores non-numeric parts and handles common version formats.
Args:
version_string: Version string in the format "x.y.z" or "x.y.z<suffix>"
Returns:
Tuple of integers for the parsed version string.
"""
parts = []
for part in version_string.split("."):
try:
parts.append(int(part))
except ValueError:
# If it's a non-numeric part (e.g., '1.0.0b1' -> 'b1'), stop here.
# This is a simplification compared to 'packaging.parse_version', but sufficient
# for comparing strictly numeric semantic versions.
break
return tuple(parts)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The parse_version_to_tuple function is a simplification that doesn't handle pre-release identifiers correctly. For example, a version like "4.25.8b1" would be parsed as (4, 25, 8), which is not less than (4, 25, 8). However, 4.25.8b1 is a pre-release of 4.25.8 and should be considered older. This could lead to missing warnings for users on pre-release versions. Consider using packaging.version.parse for a more robust version comparison. While this might add a dependency, packaging is a standard library for this purpose and is often available in environments with setuptools.

Comment on lines +381 to +386
try:
import sys
import warnings

_py_version_str = sys.version.split()[0]
_package_label = "google.cloud.discoveryengine_v1alpha"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The _package_label variable is defined inside the try block but is also used in the except block. If an exception occurs before _package_label is assigned, a NameError will be raised within the except block. To make the error handling more robust, _package_label should be defined before the try block.

Suggested change
try:
import sys
import warnings
_py_version_str = sys.version.split()[0]
_package_label = "google.cloud.discoveryengine_v1alpha"
_package_label = "google.cloud.discoveryengine_v1alpha"
try:
import sys
import warnings
_py_version_str = sys.version.split()[0]

Comment on lines +407 to +425
def parse_version_to_tuple(version_string: str):
"""Safely converts a semantic version string to a comparable tuple of integers.
Example: "4.25.8" -> (4, 25, 8)
Ignores non-numeric parts and handles common version formats.
Args:
version_string: Version string in the format "x.y.z" or "x.y.z<suffix>"
Returns:
Tuple of integers for the parsed version string.
"""
parts = []
for part in version_string.split("."):
try:
parts.append(int(part))
except ValueError:
# If it's a non-numeric part (e.g., '1.0.0b1' -> 'b1'), stop here.
# This is a simplification compared to 'packaging.parse_version', but sufficient
# for comparing strictly numeric semantic versions.
break
return tuple(parts)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The parse_version_to_tuple function is a simplification that doesn't handle pre-release identifiers correctly. For example, a version like "4.25.8b1" would be parsed as (4, 25, 8), which is not less than (4, 25, 8). However, 4.25.8b1 is a pre-release of 4.25.8 and should be considered older. This could lead to missing warnings for users on pre-release versions. Consider using packaging.version.parse for a more robust version comparison. While this might add a dependency, packaging is a standard library for this purpose and is often available in environments with setuptools.

Comment on lines +361 to +366
import sys
import warnings

_py_version_str = sys.version.split()[0]
_package_label = "google.cloud.discoveryengine_v1beta"
if sys.version_info < (3, 9):

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The _package_label variable is defined inside the try block but is also used in the except block. If an exception occurs before _package_label is assigned, a NameError will be raised within the except block. To make the error handling more robust, _package_label should be defined before the try block.

    _package_label = "google.cloud.discoveryengine_v1beta"
    try:
        import sys
        import warnings

        _py_version_str = sys.version.split()[0]

Comment on lines +387 to +405
"""Safely converts a semantic version string to a comparable tuple of integers.
Example: "4.25.8" -> (4, 25, 8)
Ignores non-numeric parts and handles common version formats.
Args:
version_string: Version string in the format "x.y.z" or "x.y.z<suffix>"
Returns:
Tuple of integers for the parsed version string.
"""
parts = []
for part in version_string.split("."):
try:
parts.append(int(part))
except ValueError:
# If it's a non-numeric part (e.g., '1.0.0b1' -> 'b1'), stop here.
# This is a simplification compared to 'packaging.parse_version', but sufficient
# for comparing strictly numeric semantic versions.
break
return tuple(parts)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The parse_version_to_tuple function is a simplification that doesn't handle pre-release identifiers correctly. For example, a version like "4.25.8b1" would be parsed as (4, 25, 8), which is not less than (4, 25, 8). However, 4.25.8b1 is a pre-release of 4.25.8 and should be considered older. This could lead to missing warnings for users on pre-release versions. Consider using packaging.version.parse for a more robust version comparison. While this might add a dependency, packaging is a standard library for this purpose and is often available in environments with setuptools.

@parthea parthea merged commit d2b35b2 into main Dec 17, 2025
25 checks passed
@parthea parthea deleted the librarian-20251216T231917Z branch December 17, 2025 00:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants