Skip to content

Commit 8715ae8

Browse files
HaoXuAIhao-xu5
andauthored
feat: Add aggregation in OnDemandFeatureView (#5629)
* add aggregation in OnDemandFeatureView Signed-off-by: hao-xu5 <hxu44@apple.com> * udpate proto Signed-off-by: hao-xu5 <hxu44@apple.com> * fix lint Signed-off-by: hao-xu5 <hxu44@apple.com> * fix lint Signed-off-by: hao-xu5 <hxu44@apple.com> --------- Signed-off-by: hao-xu5 <hxu44@apple.com> Co-authored-by: hao-xu5 <hxu44@apple.com>
1 parent 7128024 commit 8715ae8

File tree

5 files changed

+45
-19
lines changed

5 files changed

+45
-19
lines changed

protos/feast/core/OnDemandFeatureView.proto

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import "feast/core/FeatureViewProjection.proto";
2828
import "feast/core/Feature.proto";
2929
import "feast/core/DataSource.proto";
3030
import "feast/core/Transformation.proto";
31+
import "feast/core/Aggregation.proto";
3132

3233
message OnDemandFeatureView {
3334
// User-specified specifications of this feature view.
@@ -70,6 +71,10 @@ message OnDemandFeatureViewSpec {
7071
// List of specifications for each entity defined as part of this feature view.
7172
repeated FeatureSpecV2 entity_columns = 14;
7273
bool singleton = 15;
74+
75+
// Aggregation definitions
76+
repeated Aggregation aggregations = 16;
77+
7378
}
7479

7580
message OnDemandFeatureViewMeta {

sdk/python/feast/on_demand_feature_view.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import pyarrow
99
from typeguard import typechecked
1010

11+
from feast.aggregation import Aggregation
1112
from feast.base_feature_view import BaseFeatureView
1213
from feast.data_source import RequestSource
1314
from feast.entity import Entity
@@ -76,6 +77,7 @@ class OnDemandFeatureView(BaseFeatureView):
7677
singleton: bool
7778
udf: Optional[FunctionType]
7879
udf_string: Optional[str]
80+
aggregations: List[Aggregation]
7981

8082
def __init__( # noqa: C901
8183
self,
@@ -93,6 +95,7 @@ def __init__( # noqa: C901
9395
owner: str = "",
9496
write_to_online_store: bool = False,
9597
singleton: bool = False,
98+
aggregations: Optional[List[Aggregation]] = None,
9699
):
97100
"""
98101
Creates an OnDemandFeatureView object.
@@ -118,6 +121,7 @@ def __init__( # noqa: C901
118121
the online store for faster retrieval.
119122
singleton (optional): A boolean that indicates whether the transformation is executed on a singleton
120123
(only applicable when mode="python").
124+
aggregations (optional): List of aggregations to apply before transformation.
121125
"""
122126
super().__init__(
123127
name=name,
@@ -187,6 +191,7 @@ def __init__( # noqa: C901
187191
self.singleton = singleton
188192
if self.singleton and self.mode != "python":
189193
raise ValueError("Singleton is only supported for Python mode.")
194+
self.aggregations = aggregations or []
190195

191196
def get_feature_transformation(self) -> Transformation:
192197
if not self.udf:
@@ -251,6 +256,7 @@ def __eq__(self, other):
251256
or self.write_to_online_store != other.write_to_online_store
252257
or sorted(self.entity_columns) != sorted(other.entity_columns)
253258
or self.singleton != other.singleton
259+
or self.aggregations != other.aggregations
254260
):
255261
return False
256262

@@ -342,6 +348,7 @@ def to_proto(self) -> OnDemandFeatureViewProto:
342348
owner=self.owner,
343349
write_to_online_store=self.write_to_online_store,
344350
singleton=self.singleton if self.singleton else False,
351+
aggregations=self.aggregations,
345352
)
346353
return OnDemandFeatureViewProto(spec=spec, meta=meta)
347354

@@ -451,6 +458,12 @@ def from_proto(
451458
if hasattr(on_demand_feature_view_proto.spec, "singleton"):
452459
singleton = on_demand_feature_view_proto.spec.singleton
453460

461+
aggregations = []
462+
if hasattr(on_demand_feature_view_proto.spec, "aggregations"):
463+
aggregations = [
464+
Aggregation.from_proto(aggregation_proto)
465+
for aggregation_proto in on_demand_feature_view_proto.spec.aggregations
466+
]
454467
on_demand_feature_view_obj = cls(
455468
name=on_demand_feature_view_proto.spec.name,
456469
schema=[
@@ -471,6 +484,7 @@ def from_proto(
471484
owner=on_demand_feature_view_proto.spec.owner,
472485
write_to_online_store=write_to_online_store,
473486
singleton=singleton,
487+
aggregations=aggregations,
474488
)
475489

476490
on_demand_feature_view_obj.entities = entities

sdk/python/feast/protos/feast/core/FeatureService_pb2.pyi

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ class FeatureServiceSpec(google.protobuf.message.Message):
7171
"""Name of Feast project that this Feature Service belongs to."""
7272
@property
7373
def features(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[feast.core.FeatureViewProjection_pb2.FeatureViewProjection]:
74-
"""Represents a projection that's to be applied on top of the FeatureView.
74+
"""Represents a projection that's to be applied on top of the FeatureView.
7575
Contains data such as the features to use from a FeatureView.
7676
"""
7777
@property

sdk/python/feast/protos/feast/core/OnDemandFeatureView_pb2.py

Lines changed: 18 additions & 17 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

sdk/python/feast/protos/feast/core/OnDemandFeatureView_pb2.pyi

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ limitations under the License.
1818
"""
1919
import builtins
2020
import collections.abc
21+
import feast.core.Aggregation_pb2
2122
import feast.core.DataSource_pb2
2223
import feast.core.FeatureViewProjection_pb2
2324
import feast.core.FeatureView_pb2
@@ -108,6 +109,7 @@ class OnDemandFeatureViewSpec(google.protobuf.message.Message):
108109
ENTITIES_FIELD_NUMBER: builtins.int
109110
ENTITY_COLUMNS_FIELD_NUMBER: builtins.int
110111
SINGLETON_FIELD_NUMBER: builtins.int
112+
AGGREGATIONS_FIELD_NUMBER: builtins.int
111113
name: builtins.str
112114
"""Name of the feature view. Must be unique. Not updated."""
113115
project: builtins.str
@@ -139,6 +141,9 @@ class OnDemandFeatureViewSpec(google.protobuf.message.Message):
139141
def entity_columns(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[feast.core.Feature_pb2.FeatureSpecV2]:
140142
"""List of specifications for each entity defined as part of this feature view."""
141143
singleton: builtins.bool
144+
@property
145+
def aggregations(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[feast.core.Aggregation_pb2.Aggregation]:
146+
"""Aggregation definitions"""
142147
def __init__(
143148
self,
144149
*,
@@ -156,9 +161,10 @@ class OnDemandFeatureViewSpec(google.protobuf.message.Message):
156161
entities: collections.abc.Iterable[builtins.str] | None = ...,
157162
entity_columns: collections.abc.Iterable[feast.core.Feature_pb2.FeatureSpecV2] | None = ...,
158163
singleton: builtins.bool = ...,
164+
aggregations: collections.abc.Iterable[feast.core.Aggregation_pb2.Aggregation] | None = ...,
159165
) -> None: ...
160166
def HasField(self, field_name: typing_extensions.Literal["feature_transformation", b"feature_transformation", "user_defined_function", b"user_defined_function"]) -> builtins.bool: ...
161-
def ClearField(self, field_name: typing_extensions.Literal["description", b"description", "entities", b"entities", "entity_columns", b"entity_columns", "feature_transformation", b"feature_transformation", "features", b"features", "mode", b"mode", "name", b"name", "owner", b"owner", "project", b"project", "singleton", b"singleton", "sources", b"sources", "tags", b"tags", "user_defined_function", b"user_defined_function", "write_to_online_store", b"write_to_online_store"]) -> None: ...
167+
def ClearField(self, field_name: typing_extensions.Literal["aggregations", b"aggregations", "description", b"description", "entities", b"entities", "entity_columns", b"entity_columns", "feature_transformation", b"feature_transformation", "features", b"features", "mode", b"mode", "name", b"name", "owner", b"owner", "project", b"project", "singleton", b"singleton", "sources", b"sources", "tags", b"tags", "user_defined_function", b"user_defined_function", "write_to_online_store", b"write_to_online_store"]) -> None: ...
162168

163169
global___OnDemandFeatureViewSpec = OnDemandFeatureViewSpec
164170

0 commit comments

Comments
 (0)