Skip to content

Commit 21bc83b

Browse files
vertex-sdk-botcopybara-github
authored andcommitted
feat: Add List FeatureMonitor function to FeatureGroup in Vertex AI SDK
PiperOrigin-RevId: 698239121
1 parent d68a913 commit 21bc83b

File tree

3 files changed

+103
-0
lines changed

3 files changed

+103
-0
lines changed

tests/unit/vertexai/feature_store_constants.py

+23
Original file line numberDiff line numberDiff line change
@@ -393,3 +393,26 @@
393393
)
394394
_TEST_FG1_FM1_FEATURE_SELECTION_CONFIGS = [("my_fg1_f1", 0.3), ("my_fg1_f2", 0.4)]
395395
_TEST_FG1_FM1_SCHEDULE_CONFIG = "0 0 * * *"
396+
_TEST_FG1_FM2_ID = "my_fg1_fm2"
397+
_TEST_FG1_FM2_PATH = (
398+
f"{_TEST_PARENT}/featureGroups/{_TEST_FG1_ID}/featureMonitors/{_TEST_FG1_FM2_ID}"
399+
)
400+
_TEST_FG1_FM2_DESCRIPTION = "My feature monitor 2 in feature group 1"
401+
_TEST_FG1_FM2_LABELS = {"my_fg1_feature_monitor": "fm2"}
402+
_TEST_FG1_FM2_FEATURE_SELECTION_CONFIGS = [("my_fg1_f2", 0.5)]
403+
_TEST_FG1_FM2_SCHEDULE_CONFIG = "8 0 * * *"
404+
_TEST_FG1_FM2 = types.feature_monitor.FeatureMonitor(
405+
name=_TEST_FG1_FM2_PATH,
406+
description=_TEST_FG1_FM2_DESCRIPTION,
407+
labels=_TEST_FG1_FM2_LABELS,
408+
schedule_config=types.feature_monitor.ScheduleConfig(cron="8 0 * * *"),
409+
feature_selection_config=types.feature_monitor.FeatureSelectionConfig(
410+
feature_configs=[
411+
types.feature_monitor.FeatureSelectionConfig.FeatureConfig(
412+
feature_id="my_fg1_f2",
413+
drift_threshold=0.5,
414+
),
415+
]
416+
),
417+
)
418+
_TEST_FG1_FM_LIST = [_TEST_FG1_FM1, _TEST_FG1_FM2]

tests/unit/vertexai/test_feature_group.py

+50
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,13 @@
8585
_TEST_FG1_FM1_LABELS,
8686
_TEST_FG1_FM1_FEATURE_SELECTION_CONFIGS,
8787
_TEST_FG1_FM1_SCHEDULE_CONFIG,
88+
_TEST_FG1_FM2_ID,
89+
_TEST_FG1_FM2_PATH,
90+
_TEST_FG1_FM2_DESCRIPTION,
91+
_TEST_FG1_FM2_LABELS,
92+
_TEST_FG1_FM2_FEATURE_SELECTION_CONFIGS,
93+
_TEST_FG1_FM2_SCHEDULE_CONFIG,
94+
_TEST_FG1_FM_LIST,
8895
)
8996
from test_feature import feature_eq
9097
from test_feature_monitor import feature_monitor_eq
@@ -182,6 +189,16 @@ def list_features_mock():
182189
yield list_features_mock
183190

184191

192+
@pytest.fixture
193+
def list_feature_monitors_mock():
194+
with patch.object(
195+
FeatureRegistryServiceClient,
196+
"list_feature_monitors",
197+
) as list_feature_monitors_mock:
198+
list_feature_monitors_mock.return_value = _TEST_FG1_FM_LIST
199+
yield list_feature_monitors_mock
200+
201+
185202
@pytest.fixture()
186203
def mock_base_instantiate_client():
187204
with patch.object(
@@ -929,3 +946,36 @@ def test_create_feature_monitor(
929946
),
930947
]
931948
)
949+
950+
951+
def test_list_feature_monitors(get_fg_mock, list_feature_monitors_mock):
952+
aiplatform.init(project=_TEST_PROJECT, location=_TEST_LOCATION)
953+
954+
feature_monitors = FeatureGroup(_TEST_FG1_ID).list_feature_monitors()
955+
956+
list_feature_monitors_mock.assert_called_once_with(
957+
request={"parent": _TEST_FG1_PATH}
958+
)
959+
assert len(feature_monitors) == len(_TEST_FG1_FM_LIST)
960+
feature_monitor_eq(
961+
feature_monitors[0],
962+
name=_TEST_FG1_FM1_ID,
963+
resource_name=_TEST_FG1_FM1_PATH,
964+
project=_TEST_PROJECT,
965+
location=_TEST_LOCATION,
966+
description=_TEST_FG1_FM1_DESCRIPTION,
967+
labels=_TEST_FG1_FM1_LABELS,
968+
schedule_config=_TEST_FG1_FM1_SCHEDULE_CONFIG,
969+
feature_selection_configs=_TEST_FG1_FM1_FEATURE_SELECTION_CONFIGS,
970+
)
971+
feature_monitor_eq(
972+
feature_monitors[1],
973+
name=_TEST_FG1_FM2_ID,
974+
resource_name=_TEST_FG1_FM2_PATH,
975+
project=_TEST_PROJECT,
976+
location=_TEST_LOCATION,
977+
description=_TEST_FG1_FM2_DESCRIPTION,
978+
labels=_TEST_FG1_FM2_LABELS,
979+
schedule_config=_TEST_FG1_FM2_SCHEDULE_CONFIG,
980+
feature_selection_configs=_TEST_FG1_FM2_FEATURE_SELECTION_CONFIGS,
981+
)

vertexai/resources/preview/feature_store/feature_group.py

+30
Original file line numberDiff line numberDiff line change
@@ -544,6 +544,36 @@ def create_feature_monitor(
544544

545545
return feature_monitor_obj
546546

547+
def list_feature_monitors(
548+
self,
549+
project: Optional[str] = None,
550+
location: Optional[str] = None,
551+
credentials: Optional[auth_credentials.Credentials] = None,
552+
) -> List[FeatureMonitor]:
553+
"""Lists features monitors under this feature group.
554+
555+
Args:
556+
project:
557+
Project to list feature monitors in. If unset, the project set in
558+
aiplatform.init will be used.
559+
location:
560+
Location to list feature monitors in. If not set, location set in
561+
aiplatform.init will be used.
562+
credentials:
563+
Custom credentials to use to list feature monitors. Overrides
564+
credentials set in aiplatform.init.
565+
566+
Returns:
567+
List of feature monitors under this feature group.
568+
"""
569+
570+
return FeatureMonitor.list(
571+
parent=self.resource_name,
572+
project=project,
573+
location=location,
574+
credentials=credentials,
575+
)
576+
547577
@property
548578
def source(self) -> FeatureGroupBigQuerySource:
549579
return FeatureGroupBigQuerySource(

0 commit comments

Comments
 (0)