This is an automated email from the ASF dual-hosted git repository.
claudevdm pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/beam.git
The following commit(s) were added to refs/heads/master by this push:
new c31bbe9e209 [Python] Catch PermissionDenied when checking the feature
store in VertexAIFeatureStoreEnrichmentHandler (#40463)
c31bbe9e209 is described below
commit c31bbe9e2092367545f4f48f2e8c245c283e8962
Author: Divyansh Yadav <[email protected]>
AuthorDate: Wed Oct 14 23:56:51 2026 +0530
[Python] Catch PermissionDenied when checking the feature store in
VertexAIFeatureStoreEnrichmentHandler (#40463)
* [Python] Catch PermissionDenied when checking the feature store in
VertexAIFeatureStoreEnrichmentHandler
* Move CHANGES.md entry to avoid merge conflict with master
---
CHANGES.md | 1 +
.../enrichment_handlers/vertex_ai_feature_store.py | 19 +++++-----
.../vertex_ai_feature_store_test.py | 40 ++++++++++++++++++++++
3 files changed, 51 insertions(+), 9 deletions(-)
diff --git a/CHANGES.md b/CHANGES.md
index 7693e65d78a..02f3818b1a8 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -99,6 +99,7 @@
* (Go) Fixed a deadlock recreating a data channel while holding the channel
lock ([#40414](https://github.com/apache/beam/issues/40414)).
* (Java) Fixed the declared schema of the error output of the Kafka write
SchemaTransform, which wrapped the error schema a second time and did not match
the rows it emits ([#39760](https://github.com/apache/beam/issues/39760)).
* (Go) Fixed pubsubio importing a `google.golang.org/genproto` package removed
in recent releases, which broke builds of Go modules depending on a current
`genproto` version ([#40018](https://github.com/apache/beam/issues/40018)).
+* (Python) `VertexAIFeatureStoreEnrichmentHandler` now logs a warning instead
of failing when the caller lacks permission to read the feature store metadata
([#40442](https://github.com/apache/beam/issues/40442)).
* (Java) BigQueryIO now treats a 404 when deleting a temporary table or
dataset as success, so a replayed work item whose earlier attempt already
deleted it no longer retries forever
([#24997](https://github.com/apache/beam/issues/24997)).
* (Java) IcebergIO now writes rows containing `EnumerationType` (proto enum)
fields as strings, instead of throwing `Unsupported Beam logical type Enum`
([#40299](https://github.com/apache/beam/issues/40299)).
* (Python) Fixed stateful DoFns with side inputs sometimes taking the timer
key coder from a side input instead of the main input, which could make the
worker fail to decode timer keys with `Unknown type tag`
([#40374](https://github.com/apache/beam/issues/40374)).
diff --git
a/sdks/python/apache_beam/transforms/enrichment_handlers/vertex_ai_feature_store.py
b/sdks/python/apache_beam/transforms/enrichment_handlers/vertex_ai_feature_store.py
index c364378ea8a..88d2f3cc6ae 100644
---
a/sdks/python/apache_beam/transforms/enrichment_handlers/vertex_ai_feature_store.py
+++
b/sdks/python/apache_beam/transforms/enrichment_handlers/vertex_ai_feature_store.py
@@ -18,6 +18,7 @@ import logging
import proto
from google.api_core.exceptions import NotFound
+from google.api_core.exceptions import PermissionDenied
from google.cloud import aiplatform
import apache_beam as beam
@@ -113,23 +114,23 @@ class
VertexAIFeatureStoreEnrichmentHandler(EnrichmentSourceHandler[beam.Row,
try:
admin_client = aiplatform.gapic.FeatureOnlineStoreAdminServiceClient(
**self.kwargs)
- except Exception:
- _LOGGER.warning(
- 'Due to insufficient admin permission, could not verify '
- 'the existence of feature store. If the `exception_level` '
- 'is set to WARN then make sure the feature store exists '
- 'otherwise the data enrichment will not happen without '
- 'throwing an error.')
- else:
location_path = admin_client.common_location_path(
project=self.project, location=self.location)
feature_store_path = admin_client.feature_online_store_path(
project=self.project,
location=self.location,
feature_online_store=self.feature_store_name)
+ # creating the client doesn't check permissions, this RPC does.
feature_store = admin_client.get_feature_online_store(
name=feature_store_path)
-
+ except PermissionDenied:
+ _LOGGER.warning(
+ 'Due to insufficient admin permission, could not verify '
+ 'the existence of feature store. If the `exception_level` '
+ 'is set to WARN then make sure the feature store exists '
+ 'otherwise the data enrichment will not happen without '
+ 'throwing an error.')
+ else:
if not feature_store:
raise NotFound(
'Vertex AI Feature Store %s does not exists in %s' %
diff --git
a/sdks/python/apache_beam/transforms/enrichment_handlers/vertex_ai_feature_store_test.py
b/sdks/python/apache_beam/transforms/enrichment_handlers/vertex_ai_feature_store_test.py
index 211529be4dc..233f0e11da6 100644
---
a/sdks/python/apache_beam/transforms/enrichment_handlers/vertex_ai_feature_store_test.py
+++
b/sdks/python/apache_beam/transforms/enrichment_handlers/vertex_ai_feature_store_test.py
@@ -15,8 +15,12 @@
# limitations under the License.
#
import unittest
+from unittest import mock
try:
+ from google.api_core.exceptions import NotFound
+ from google.api_core.exceptions import PermissionDenied
+
from apache_beam.transforms.enrichment_handlers.vertex_ai_feature_store
import VertexAIFeatureStoreEnrichmentHandler
from apache_beam.transforms.enrichment_handlers.vertex_ai_feature_store
import \
VertexAIFeatureStoreLegacyEnrichmentHandler
@@ -39,6 +43,42 @@ class TestVertexAIFeatureStoreHandlerInit(unittest.TestCase):
client_options={'api_endpoint': '[email protected]'},
)
+ @mock.patch(
+ 'apache_beam.transforms.enrichment_handlers.vertex_ai_feature_store.'
+ 'aiplatform.gapic.FeatureOnlineStoreAdminServiceClient')
+ def test_permission_denied_online_store(self, mock_admin_client):
+ mock_admin_client.return_value.get_feature_online_store.side_effect = (
+ PermissionDenied('permission denied'))
+ with self.assertLogs(
+ 'apache_beam.transforms.enrichment_handlers.vertex_ai_feature_store',
+ level='WARNING') as logs:
+ _ = VertexAIFeatureStoreEnrichmentHandler(
+ project='project',
+ location='location',
+ api_endpoint='[email protected]',
+ feature_store_name='feature_store',
+ feature_view_name='feature_view',
+ row_key='row_key',
+ )
+ self.assertIn('insufficient admin permission', logs.output[0])
+
+ @mock.patch(
+ 'apache_beam.transforms.enrichment_handlers.vertex_ai_feature_store.'
+ 'aiplatform.gapic.FeatureOnlineStoreAdminServiceClient')
+ def test_raise_error_feature_store_not_found_online_store(
+ self, mock_admin_client):
+ mock_admin_client.return_value.get_feature_online_store.side_effect = (
+ NotFound('not found'))
+ with self.assertRaises(NotFound):
+ _ = VertexAIFeatureStoreEnrichmentHandler(
+ project='project',
+ location='location',
+ api_endpoint='[email protected]',
+ feature_store_name='feature_store',
+ feature_view_name='feature_view',
+ row_key='row_key',
+ )
+
def test_raise_error_duplicate_api_endpoint_legacy_store(self):
with self.assertRaises(ValueError):
_ = VertexAIFeatureStoreLegacyEnrichmentHandler(