-
Notifications
You must be signed in to change notification settings - Fork 1.6k
chore: librarian update image pull request: 20251218T225544Z #14984
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…prod/images-prod/python-librarian-generator@sha256:b8058df4c45e9a6e07f6b4d65b458d0d059241dd34c814f151c8bf6b89211209
Summary of ChangesHello @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 core librarian image, which has propagated significant changes across multiple Google Ads and AI client libraries. The primary objective of these changes is to modernize the handling of Mutual TLS (mTLS) client certificates, enhance environment variable parsing for authentication settings, and introduce robust dependency version checks. These updates aim to improve the stability, maintainability, and future compatibility of the affected client libraries. Highlights
🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console. Using Gemini Code AssistThe 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
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 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
|
There was a problem hiding this 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 generator image, which has resulted in widespread changes across client libraries, primarily related to mTLS client certificate handling. A new helper method, _use_client_cert_effective, has been introduced to centralize logic and ensure backward compatibility with different versions of the google-auth library. The changes also include extensive new tests for this functionality.
My review focuses on the correctness and maintainability of the generated code. While the core logic appears sound, I've identified several areas for improvement:
- Redundant test cases in both YAML configuration and Python test files.
- Overly broad exception handling in
__init__.pyfiles which could mask potential bugs. - Repetitive conditional checks in test functions that could be refactored for better readability.
Addressing these points would improve the quality and maintainability of the generated code.
| # Test cases for mTLS enablement when GOOGLE_API_USE_CLIENT_CERTIFICATE is unset\(empty\). | ||
| test_cases = \[ | ||
| \( | ||
| # With workloads present in config, mTLS is enabled. | ||
| { | ||
| "version": 1, | ||
| "cert_configs": { | ||
| "workload": { | ||
| "cert_path": "path/to/cert/file", | ||
| "key_path": "path/to/key/file", | ||
| } | ||
| }, | ||
| }, | ||
| mock_client_cert_source, | ||
| \), | ||
| \( | ||
| # With workloads not present in config, mTLS is disabled. | ||
| { | ||
| "version": 1, | ||
| "cert_configs": {}, | ||
| }, | ||
| None, | ||
| \), | ||
| \] | ||
| if hasattr\(google.auth.transport.mtls, "should_use_client_cert"\): | ||
| for config_data, expected_cert_source in test_cases: | ||
| env = os.environ.copy\(\) | ||
| env.pop\("GOOGLE_API_USE_CLIENT_CERTIFICATE", ""\) | ||
| with mock.patch.dict\(os.environ, env, clear=True\): | ||
| config_filename = "mock_certificate_config.json" | ||
| config_file_content = json.dumps\(config_data\) | ||
| m = mock.mock_open\(read_data=config_file_content\) | ||
| with mock.patch\("builtins.open", m\): | ||
| with mock.patch.dict\( | ||
| os.environ, {"GOOGLE_API_CERTIFICATE_CONFIG": config_filename} | ||
| \): | ||
| mock_api_endpoint = "foo" | ||
| options = client_options.ClientOptions\( | ||
| client_cert_source=mock_client_cert_source, | ||
| api_endpoint=mock_api_endpoint, | ||
| \) | ||
| \( | ||
| api_endpoint, | ||
| cert_source, | ||
| \) = client_class.get_mtls_endpoint_and_cert_source\(options\) | ||
| assert api_endpoint == mock_api_endpoint | ||
| assert cert_source is expected_cert_source |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This block of tests seems to be redundant. The comment says "Test cases for mTLS enablement when GOOGLE_API_USE_CLIENT_CERTIFICATE is unset(empty)", and the code uses env.pop("GOOGLE_API_USE_CLIENT_CERTIFICATE", ""). The preceding block of tests is for when the variable is "unset" and uses env.pop("GOOGLE_API_USE_CLIENT_CERTIFICATE", None). Since the return value of pop is not used, both calls have the same effect: they ensure the environment variable is not present. Therefore, this block of tests is a duplicate of the one from lines 1149-1195. Please consider removing this redundant block.
| except Exception: | ||
| # Catch exceptions from metadata.version() (e.g., PackageNotFoundError) | ||
| # or errors during parse_version_to_tuple | ||
| return (None, "--") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| except Exception: | ||
| warnings.warn( | ||
| "Could not determine the version of Python " | ||
| + "currently being used. To continue receiving " | ||
| + "updates for {_package_label}, ensure you are " | ||
| + "using a supported version of Python; see " | ||
| + "https://devguide.python.org/versions/" | ||
| ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This except Exception is very broad and could mask various unrelated errors within the try block, making debugging harder. If the intention is to handle failures in version checking gracefully, it would be better to either let unexpected exceptions propagate or catch more specific exceptions if known ones are expected. A broad except like this can hide bugs.
| # Test case 3: Test when `should_use_client_cert` is unavailable and the | ||
| # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "true". | ||
| if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): | ||
| with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): | ||
| assert AdBreakServiceClient._use_client_cert_effective() is True | ||
|
|
||
| # Test case 4: Test when `should_use_client_cert` is unavailable and the | ||
| # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "false". | ||
| if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): | ||
| with mock.patch.dict( | ||
| os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"} | ||
| ): | ||
| assert AdBreakServiceClient._use_client_cert_effective() is False | ||
|
|
||
| # Test case 5: Test when `should_use_client_cert` is unavailable and the | ||
| # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "True". | ||
| if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): | ||
| with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "True"}): | ||
| assert AdBreakServiceClient._use_client_cert_effective() is True | ||
|
|
||
| # Test case 6: Test when `should_use_client_cert` is unavailable and the | ||
| # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "False". | ||
| if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): | ||
| with mock.patch.dict( | ||
| os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "False"} | ||
| ): | ||
| assert AdBreakServiceClient._use_client_cert_effective() is False | ||
|
|
||
| # Test case 7: Test when `should_use_client_cert` is unavailable and the | ||
| # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "TRUE". | ||
| if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): | ||
| with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "TRUE"}): | ||
| assert AdBreakServiceClient._use_client_cert_effective() is True | ||
|
|
||
| # Test case 8: Test when `should_use_client_cert` is unavailable and the | ||
| # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "FALSE". | ||
| if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): | ||
| with mock.patch.dict( | ||
| os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "FALSE"} | ||
| ): | ||
| assert AdBreakServiceClient._use_client_cert_effective() is False | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): check is repeated for multiple test cases (3 through 8). This makes the code verbose and harder to maintain. Consider grouping these test cases under a single if block to improve readability and reduce redundancy.
For example:
if not hasattr(google.auth.transport.mtls, "should_use_client_cert"):
# Test case 3
with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}):
assert AdBreakServiceClient._use_client_cert_effective() is True
# Test case 4
with mock.patch.dict(
os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}
):
assert AdBreakServiceClient._use_client_cert_effective() is False
# ... and so on for cases 5-8| # Test cases for mTLS enablement when GOOGLE_API_USE_CLIENT_CERTIFICATE is unset(empty). | ||
| test_cases = [ | ||
| ( | ||
| # With workloads present in config, mTLS is enabled. | ||
| { | ||
| "version": 1, | ||
| "cert_configs": { | ||
| "workload": { | ||
| "cert_path": "path/to/cert/file", | ||
| "key_path": "path/to/key/file", | ||
| } | ||
| }, | ||
| }, | ||
| mock_client_cert_source, | ||
| ), | ||
| ( | ||
| # With workloads not present in config, mTLS is disabled. | ||
| { | ||
| "version": 1, | ||
| "cert_configs": {}, | ||
| }, | ||
| None, | ||
| ), | ||
| ] | ||
| if hasattr(google.auth.transport.mtls, "should_use_client_cert"): | ||
| for config_data, expected_cert_source in test_cases: | ||
| env = os.environ.copy() | ||
| env.pop("GOOGLE_API_USE_CLIENT_CERTIFICATE", "") | ||
| with mock.patch.dict(os.environ, env, clear=True): | ||
| config_filename = "mock_certificate_config.json" | ||
| config_file_content = json.dumps(config_data) | ||
| m = mock.mock_open(read_data=config_file_content) | ||
| with mock.patch("builtins.open", m): | ||
| with mock.patch.dict( | ||
| os.environ, {"GOOGLE_API_CERTIFICATE_CONFIG": config_filename} | ||
| ): | ||
| mock_api_endpoint = "foo" | ||
| options = client_options.ClientOptions( | ||
| client_cert_source=mock_client_cert_source, | ||
| api_endpoint=mock_api_endpoint, | ||
| ) | ||
| ( | ||
| api_endpoint, | ||
| cert_source, | ||
| ) = client_class.get_mtls_endpoint_and_cert_source(options) | ||
| assert api_endpoint == mock_api_endpoint | ||
| assert cert_source is expected_cert_source |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This block of tests appears to be a duplicate of the preceding block (lines 869-915). The comment mentions testing for "unset(empty)", but the code env.pop("GOOGLE_API_USE_CLIENT_CERTIFICATE", "") has the same effect as env.pop("GOOGLE_API_USE_CLIENT_CERTIFICATE", None) from the previous block, as the return value of pop is not used. Both ensure the environment variable is not set. This makes this test block redundant. Please consider removing it to avoid duplicated tests.
feat: update image to us-central1-docker.pkg.dev/cloud-sdk-librarian-prod/images-prod/python-librarian-generator@sha256:b8058df4c45e9a6e07f6b4d65b458d0d059241dd34c814f151c8bf6b89211209