Repository navigation
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #40674 +/- ##
=============================================
+ Coverage 56.16% 80.02% +23.85%
=============================================
Files 1124 490 -634
Lines 178336 82818 -95518
Branches 1489 0 -1489
=============================================
- Hits 100170 66275 -33895
+ Misses 75645 16543 -59102
+ Partials 2521 0 -2521
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
storage.Client ignores GOOGLE_CLOUD_UNIVERSE_DOMAIN and only reads client_options.universe_domain. Beam passes no client_options, so with TPC credentials, create_storage_client() and the soft-delete check in GoogleCloudOptions fail with a universe domain mismatch ValueError. The soft-delete check also ignores the user's pipeline options, and any failure in it blocks pipeline submission. 4 of the new tests fail until the fix lands.
storage.Client only reads the universe domain from client_options. create_storage_client() now passes it in, taking it from GOOGLE_CLOUD_UNIVERSE_DOMAIN or the credentials. Default-universe behavior is unchanged. The soft-delete check now uses the user's pipeline options and only logs a warning if it fails, so it no longer blocks submission.
There was a problem hiding this comment.
📋 Review Summary
This PR adds support for non-default Google Cloud universe domains (such as Trusted Partner Cloud) when creating Python GCS storage clients and ensures GoogleCloudOptions._warn_if_soft_delete_policy_enabled honors user pipeline options without blocking job submission on error. The implementation is clean and well-tested, with one minor test environment leakage issue in gcsio_test.py.
🔍 General Feedback
- The fallback resolution of
universe_domainfromGOOGLE_CLOUD_UNIVERSE_DOMAINand credentials ingcsio.create_storage_clientis straightforward and preserves existing behavior for the defaultgoogleapis.comuniverse. - Passing
pipeline_options=selfintoGcsIOand catching broad exceptions in_warn_if_soft_delete_policy_enabledproperly ensures pipeline validation does not fail when checking soft-delete policies.
💡 Tip: Comment /gemini review on this pull request to trigger a new Gemini code review.
|
|
||
| @mock.patch('apache_beam.internal.gcp.auth.get_service_credentials') | ||
| def test_universe_domain_from_env_var(self, mock_get_service_credentials): | ||
| os.environ["GOOGLE_CLOUD_UNIVERSE_DOMAIN"] = _TPC_UNIVERSE_DOMAIN |
There was a problem hiding this comment.
🟡 Medium: test_universe_domain_from_env_var mutates os.environ["GOOGLE_CLOUD_UNIVERSE_DOMAIN"] directly, and the class-level @mock.patch.dict(os.environ, ...) only snapshots/restores os.environ at the method level if applied to the test method or if clear=False is used per-method (when decorating a unittest.TestCase class, mock.patch.dict wraps each test_* method individually, which does restore os.environ after each test, unless other code or sub-hooks run before/after). However, mutating os.environ directly in test_default_universe_domain, test_universe_domain_from_env_var, and test_universe_domain_from_credentials is brittle and inconsistent with pipeline_options_test.py. Consider using @mock.patch.dict(os.environ, {"GOOGLE_CLOUD_UNIVERSE_DOMAIN": _TPC_UNIVERSE_DOMAIN}) (or with mock.patch.dict(...)) for clarity and guaranteed isolation.
|
Assigning reviewers: R: @damccorm for label python. This pull request likely touches a core component ("core" label). Please review with scrutiny. Note: If you would like to opt out of this review, comment Available commands:
The PR bot will only process comments in the main thread (not review comments). |
Part of #40569
Problem
The Python GCS client library (
storage.Client) only reads the universe domain fromclient_options.universe_domain. It ignoresGOOGLE_CLOUD_UNIVERSE_DOMAINand the universe domain on the credentials.Beam creates the client without
client_options, so it always assumesgoogleapis.com. With Trusted Partner Cloud (TPC) credentials, client creation fails with:This breaks:
gcsio.create_storage_client(), which every GCS read and write uses.GoogleCloudOptions. This fails during pipelinevalidation, so the job can't even be submitted.
Changes
gcsio.create_storage_client: passesclient_options={"universe_domain": ...}, taking the value fromGOOGLE_CLOUD_UNIVERSE_DOMAINor, if that's unset, the credentials. Nothing changes for the default universe.GoogleCloudOptions._warn_if_soft_delete_policy_enabled:GcsIOfrom the user's pipeline options instead of empty defaults, so--project,--impersonate_service_accountand the universe domain are respected.