Skip to content

Commit e47d436

Browse files
vertex-sdk-botcopybara-github
authored andcommitted
feat: add FeatureGroup init/get
PiperOrigin-RevId: 631486385
1 parent bae8429 commit e47d436

File tree

12 files changed

+261
-11
lines changed

12 files changed

+261
-11
lines changed

google/cloud/aiplatform/compat/__init__.py

+8
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@
3636
services.feature_online_store_service_client = (
3737
services.feature_online_store_service_client_v1beta1
3838
)
39+
services.feature_registry_service_client = (
40+
services.feature_registry_service_client_v1beta1
41+
)
3942
services.featurestore_online_serving_service_client = (
4043
services.featurestore_online_serving_service_client_v1beta1
4144
)
@@ -91,6 +94,7 @@
9194
types.feature_online_store_admin_service = (
9295
types.feature_online_store_admin_service_v1beta1
9396
)
97+
types.feature_registry_service = types.feature_registry_service_v1beta1
9498
types.feature_online_store_service = types.feature_online_store_service_v1beta1
9599
types.feature_selector = types.feature_selector_v1beta1
96100
types.feature_view = types.feature_view_v1beta1
@@ -157,6 +161,9 @@
157161
services.feature_online_store_admin_service_client = (
158162
services.feature_online_store_admin_service_client_v1
159163
)
164+
services.feature_registry_service_client = (
165+
services.feature_registry_service_client_v1
166+
)
160167
services.feature_online_store_service_client = (
161168
services.feature_online_store_service_client_v1
162169
)
@@ -208,6 +215,7 @@
208215
types.feature_online_store_admin_service = (
209216
types.feature_online_store_admin_service_v1
210217
)
218+
types.feature_registry_service = types.feature_registry_service_v1
211219
types.feature_online_store_service = types.feature_online_store_service_v1
212220
types.feature_selector = types.feature_selector_v1
213221
types.feature_view = types.feature_view_v1

google/cloud/aiplatform/compat/services/__init__.py

+8
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@
3636
from google.cloud.aiplatform_v1beta1.services.feature_online_store_admin_service import (
3737
client as feature_online_store_admin_service_client_v1beta1,
3838
)
39+
from google.cloud.aiplatform_v1beta1.services.feature_registry_service import (
40+
client as feature_registry_service_client_v1beta1,
41+
)
3942
from google.cloud.aiplatform_v1beta1.services.featurestore_online_serving_service import (
4043
client as featurestore_online_serving_service_client_v1beta1,
4144
)
@@ -119,6 +122,9 @@
119122
from google.cloud.aiplatform_v1.services.feature_online_store_admin_service import (
120123
client as feature_online_store_admin_service_client_v1,
121124
)
125+
from google.cloud.aiplatform_v1.services.feature_registry_service import (
126+
client as feature_registry_service_client_v1,
127+
)
122128
from google.cloud.aiplatform_v1.services.featurestore_online_serving_service import (
123129
client as featurestore_online_serving_service_client_v1,
124130
)
@@ -174,6 +180,7 @@
174180
endpoint_service_client_v1,
175181
feature_online_store_service_client_v1,
176182
feature_online_store_admin_service_client_v1,
183+
feature_registry_service_client_v1,
177184
featurestore_online_serving_service_client_v1,
178185
featurestore_service_client_v1,
179186
index_service_client_v1,
@@ -196,6 +203,7 @@
196203
endpoint_service_client_v1beta1,
197204
feature_online_store_service_client_v1beta1,
198205
feature_online_store_admin_service_client_v1beta1,
206+
feature_registry_service_client_v1beta1,
199207
featurestore_online_serving_service_client_v1beta1,
200208
featurestore_service_client_v1beta1,
201209
index_service_client_v1beta1,

google/cloud/aiplatform/compat/types/__init__.py

+2
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
feature_online_store as feature_online_store_v1beta1,
4848
feature_online_store_admin_service as feature_online_store_admin_service_v1beta1,
4949
feature_online_store_service as feature_online_store_service_v1beta1,
50+
feature_registry_service as feature_registry_service_v1beta1,
5051
feature_selector as feature_selector_v1beta1,
5152
feature_view as feature_view_v1beta1,
5253
feature_view_sync as feature_view_sync_v1beta1,
@@ -136,6 +137,7 @@
136137
feature_online_store as feature_online_store_v1,
137138
feature_online_store_admin_service as feature_online_store_admin_service_v1,
138139
feature_online_store_service as feature_online_store_service_v1,
140+
feature_registry_service as feature_registry_service_v1,
139141
feature_selector as feature_selector_v1,
140142
feature_view as feature_view_v1,
141143
feature_view_sync as feature_view_sync_v1,

google/cloud/aiplatform/utils/__init__.py

+19
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
extension_registry_service_client_v1beta1,
4444
feature_online_store_admin_service_client_v1beta1,
4545
feature_online_store_service_client_v1beta1,
46+
feature_registry_service_client_v1beta1,
4647
featurestore_online_serving_service_client_v1beta1,
4748
featurestore_service_client_v1beta1,
4849
index_service_client_v1beta1,
@@ -71,6 +72,7 @@
7172
endpoint_service_client_v1,
7273
feature_online_store_admin_service_client_v1,
7374
feature_online_store_service_client_v1,
75+
feature_registry_service_client_v1,
7476
featurestore_online_serving_service_client_v1,
7577
featurestore_service_client_v1,
7678
index_service_client_v1,
@@ -100,6 +102,7 @@
100102
endpoint_service_client_v1beta1.EndpointServiceClient,
101103
feature_online_store_admin_service_client_v1beta1.FeatureOnlineStoreAdminServiceClient,
102104
feature_online_store_service_client_v1beta1.FeatureOnlineStoreServiceClient,
105+
feature_registry_service_client_v1beta1.FeatureRegistryServiceClient,
103106
featurestore_online_serving_service_client_v1beta1.FeaturestoreOnlineServingServiceClient,
104107
featurestore_service_client_v1beta1.FeaturestoreServiceClient,
105108
index_service_client_v1beta1.IndexServiceClient,
@@ -120,6 +123,7 @@
120123
endpoint_service_client_v1.EndpointServiceClient,
121124
feature_online_store_admin_service_client_v1.FeatureOnlineStoreAdminServiceClient,
122125
feature_online_store_service_client_v1.FeatureOnlineStoreServiceClient,
126+
feature_registry_service_client_v1.FeatureRegistryServiceClient,
123127
featurestore_online_serving_service_client_v1.FeaturestoreOnlineServingServiceClient,
124128
featurestore_service_client_v1.FeaturestoreServiceClient,
125129
metadata_service_client_v1.MetadataServiceClient,
@@ -635,6 +639,21 @@ class FeatureOnlineStoreClientWithOverride(ClientWithOverride):
635639
)
636640

637641

642+
class FeatureRegistryClientWithOverride(ClientWithOverride):
643+
_is_temporary = True
644+
_default_version = compat.DEFAULT_VERSION
645+
_version_map = (
646+
(
647+
compat.V1,
648+
feature_registry_service_client_v1.FeatureRegistryServiceClient,
649+
),
650+
(
651+
compat.V1BETA1,
652+
feature_registry_service_client_v1beta1.FeatureRegistryServiceClient,
653+
),
654+
)
655+
656+
638657
class FeaturestoreClientWithOverride(ClientWithOverride):
639658
_is_temporary = True
640659
_default_version = compat.DEFAULT_VERSION

tests/unit/vertexai/feature_store_constants.py

+16
Original file line numberDiff line numberDiff line change
@@ -262,3 +262,19 @@
262262
]
263263
)
264264
)
265+
266+
_TEST_FG1_ID = "my_fg1"
267+
_TEST_FG1_PATH = f"{_TEST_PARENT}/featureGroups/{_TEST_FG1_ID}"
268+
_TEST_FG1_BQ_URI = f"bq://{_TEST_PROJECT}.my_dataset.my_table_for_fg1"
269+
_TEST_FG1_ENTITY_ID_COLUMNS = ["entity_id"]
270+
_TEST_FG1_LABELS = {"my_key": "my_fg1"}
271+
_TEST_FG1 = types.feature_group.FeatureGroup(
272+
name=_TEST_FG1_PATH,
273+
big_query=types.feature_group.FeatureGroup.BigQuery(
274+
big_query_source=types.io.BigQuerySource(
275+
input_uri=_TEST_FG1_BQ_URI,
276+
),
277+
entity_id_columns=_TEST_FG1_ENTITY_ID_COLUMNS,
278+
),
279+
labels=_TEST_FG1_LABELS,
280+
)
+103
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
# -*- coding: utf-8 -*-
2+
3+
# Copyright 2024 Google LLC
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
#
17+
18+
from typing import Dict, List
19+
from unittest.mock import patch
20+
21+
from google.cloud import aiplatform
22+
from google.cloud.aiplatform import base
23+
from vertexai.resources.preview import (
24+
FeatureGroup,
25+
)
26+
import vertexai.resources.preview.feature_store.utils as fs_utils
27+
import pytest
28+
from google.cloud.aiplatform.compat.services import (
29+
feature_registry_service_client,
30+
)
31+
32+
33+
from feature_store_constants import (
34+
_TEST_PROJECT,
35+
_TEST_LOCATION,
36+
_TEST_FG1,
37+
_TEST_FG1_ID,
38+
_TEST_FG1_PATH,
39+
_TEST_FG1_BQ_URI,
40+
_TEST_FG1_ENTITY_ID_COLUMNS,
41+
_TEST_FG1_LABELS,
42+
)
43+
44+
45+
pytestmark = pytest.mark.usefixtures("google_auth_mock")
46+
47+
48+
@pytest.fixture
49+
def get_fg_mock():
50+
with patch.object(
51+
feature_registry_service_client.FeatureRegistryServiceClient,
52+
"get_feature_group",
53+
) as get_fg_mock:
54+
get_fg_mock.return_value = _TEST_FG1
55+
yield get_fg_mock
56+
57+
58+
def fg_eq(
59+
fg_to_check: FeatureGroup,
60+
name: str,
61+
resource_name: str,
62+
source_uri: str,
63+
entity_id_columns: List[str],
64+
project: str,
65+
location: str,
66+
labels: Dict[str, str],
67+
):
68+
"""Check if a FeatureGroup has the appropriate values set."""
69+
assert fg_to_check.name == name
70+
assert fg_to_check.resource_name == resource_name
71+
assert fg_to_check.source == fs_utils.FeatureGroupBigQuerySource(
72+
uri=source_uri,
73+
entity_id_columns=entity_id_columns,
74+
)
75+
assert fg_to_check.project == project
76+
assert fg_to_check.location == location
77+
assert fg_to_check.labels == labels
78+
79+
80+
@pytest.mark.parametrize(
81+
"feature_group_name",
82+
[_TEST_FG1_ID, _TEST_FG1_PATH],
83+
)
84+
def test_init(feature_group_name, get_fg_mock):
85+
aiplatform.init(project=_TEST_PROJECT, location=_TEST_LOCATION)
86+
87+
fg = FeatureGroup(feature_group_name)
88+
89+
get_fg_mock.assert_called_once_with(
90+
name=_TEST_FG1_PATH,
91+
retry=base._DEFAULT_RETRY,
92+
)
93+
94+
fg_eq(
95+
fg,
96+
name=_TEST_FG1_ID,
97+
resource_name=_TEST_FG1_PATH,
98+
source_uri=_TEST_FG1_BQ_URI,
99+
entity_id_columns=_TEST_FG1_ENTITY_ID_COLUMNS,
100+
project=_TEST_PROJECT,
101+
location=_TEST_LOCATION,
102+
labels=_TEST_FG1_LABELS,
103+
)

tests/unit/vertexai/test_feature_view.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
from vertexai.resources.preview import (
2727
FeatureView,
2828
)
29-
import vertexai.resources.preview.feature_store.utils as fv_utils
29+
import vertexai.resources.preview.feature_store.utils as fs_utils
3030
import pytest
3131
from google.cloud.aiplatform.compat.services import (
3232
feature_online_store_admin_service_client,
@@ -418,7 +418,7 @@ def test_fetch_feature_values_optimized_no_endpoint(
418418
):
419419
"""Tests that the public endpoint is not created for the optimized online store."""
420420
with pytest.raises(
421-
fv_utils.PublicEndpointNotFoundError,
421+
fs_utils.PublicEndpointNotFoundError,
422422
match=re.escape(
423423
"Public endpoint is not created yet for the optimized online "
424424
"store:my_esf_optimised_fos2. Please run sync and wait for it "
@@ -498,8 +498,8 @@ def test_search_nearest_entities_no_endpoint(
498498
try:
499499
FeatureView(_TEST_OPTIMIZED_FV2_PATH).search(entity_id="key1").to_dict()
500500
assert not fetch_feature_values_mock.called
501-
except fv_utils.PublicEndpointNotFoundError as e:
502-
assert isinstance(e, fv_utils.PublicEndpointNotFoundError)
501+
except fs_utils.PublicEndpointNotFoundError as e:
502+
assert isinstance(e, fs_utils.PublicEndpointNotFoundError)
503503
error_msg = (
504504
"Public endpoint is not created yet for the optimized online "
505505
"store:my_esf_optimised_fos2. Please run sync and wait for it "

vertexai/resources/preview/__init__.py

+2
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
)
3636

3737
from vertexai.resources.preview.feature_store import (
38+
FeatureGroup,
3839
FeatureOnlineStore,
3940
FeatureOnlineStoreType,
4041
FeatureView,
@@ -62,6 +63,7 @@
6263
"PersistentResource",
6364
"EntityType",
6465
"PipelineJobSchedule",
66+
"FeatureGroup",
6567
"FeatureOnlineStoreType",
6668
"FeatureOnlineStore",
6769
"FeatureView",

vertexai/resources/preview/feature_store/__init__.py

+5
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@
1616
#
1717
"""The vertexai resources preview module."""
1818

19+
from vertexai.resources.preview.feature_store.feature_group import (
20+
FeatureGroup,
21+
)
22+
1923
from vertexai.resources.preview.feature_store.feature_online_store import (
2024
FeatureOnlineStore,
2125
FeatureOnlineStoreType,
@@ -36,6 +40,7 @@
3640
)
3741

3842
__all__ = (
43+
FeatureGroup,
3944
FeatureOnlineStoreType,
4045
FeatureOnlineStore,
4146
FeatureView,

0 commit comments

Comments
 (0)