@@ -61,12 +61,12 @@ class OnDemandFeatureView(BaseFeatureView):
61
61
maintainer.
62
62
"""
63
63
64
- # TODO(adchia): remove inputs from proto and declaration
65
64
name : str
66
65
features : List [Field ]
67
66
source_feature_view_projections : Dict [str , FeatureViewProjection ]
68
67
source_request_sources : Dict [str , RequestSource ]
69
68
udf : FunctionType
69
+ udf_string : str
70
70
description : str
71
71
tags : Dict [str , str ]
72
72
owner : str
@@ -81,6 +81,7 @@ def __init__( # noqa: C901
81
81
List [Any ]
82
82
] = None , # Typed as Any because @typechecked can't deal with the List[Union]
83
83
udf : Optional [FunctionType ] = None ,
84
+ udf_string : str = "" ,
84
85
inputs : Optional [
85
86
Dict [str , Union [FeatureView , FeatureViewProjection , RequestSource ]]
86
87
] = None ,
@@ -99,8 +100,9 @@ def __init__( # noqa: C901
99
100
sources (optional): A map from input source names to the actual input sources,
100
101
which may be feature views, or request data sources.
101
102
These sources serve as inputs to the udf, which will refer to them by name.
102
- udf (optional) : The user defined transformation function, which must take pandas
103
+ udf: The user defined transformation function, which must take pandas
103
104
dataframes as inputs.
105
+ udf_string: The source code version of the udf (for diffing and displaying in Web UI)
104
106
inputs (optional): (Deprecated) A map from input source names to the actual input sources,
105
107
which may be feature views, feature view projections, or request data sources.
106
108
These sources serve as inputs to the udf, which will refer to them by name.
@@ -233,9 +235,8 @@ def __init__( # noqa: C901
233
235
odfv_source .name
234
236
] = odfv_source .projection
235
237
236
- if _udf is None :
237
- raise ValueError ("The `udf` parameter must be specified." )
238
- self .udf = _udf # type: ignore
238
+ self .udf = udf # type: ignore
239
+ self .udf_string = udf_string
239
240
240
241
@property
241
242
def proto_class (self ) -> Type [OnDemandFeatureViewProto ]:
@@ -249,6 +250,7 @@ def __copy__(self):
249
250
sources = list (self .source_feature_view_projections .values ())
250
251
+ list (self .source_request_sources .values ()),
251
252
udf = self .udf ,
253
+ udf_string = self .udf_string ,
252
254
description = self .description ,
253
255
tags = self .tags ,
254
256
owner = self .owner ,
@@ -269,6 +271,7 @@ def __eq__(self, other):
269
271
self .source_feature_view_projections
270
272
!= other .source_feature_view_projections
271
273
or self .source_request_sources != other .source_request_sources
274
+ or self .udf_string != other .udf_string
272
275
or self .udf .__code__ .co_code != other .udf .__code__ .co_code
273
276
):
274
277
return False
@@ -305,7 +308,9 @@ def to_proto(self) -> OnDemandFeatureViewProto:
305
308
features = [feature .to_proto () for feature in self .features ],
306
309
sources = sources ,
307
310
user_defined_function = UserDefinedFunctionProto (
308
- name = self .udf .__name__ , body = dill .dumps (self .udf , recurse = True ),
311
+ name = self .udf .__name__ ,
312
+ body = dill .dumps (self .udf , recurse = True ),
313
+ body_text = self .udf_string ,
309
314
),
310
315
description = self .description ,
311
316
tags = self .tags ,
@@ -354,6 +359,7 @@ def from_proto(cls, on_demand_feature_view_proto: OnDemandFeatureViewProto):
354
359
udf = dill .loads (
355
360
on_demand_feature_view_proto .spec .user_defined_function .body
356
361
),
362
+ udf_string = on_demand_feature_view_proto .spec .user_defined_function .body_text ,
357
363
description = on_demand_feature_view_proto .spec .description ,
358
364
tags = dict (on_demand_feature_view_proto .spec .tags ),
359
365
owner = on_demand_feature_view_proto .spec .owner ,
@@ -641,6 +647,7 @@ def mainify(obj):
641
647
obj .__module__ = "__main__"
642
648
643
649
def decorator (user_function ):
650
+ udf_string = dill .source .getsource (user_function )
644
651
mainify (user_function )
645
652
on_demand_feature_view_obj = OnDemandFeatureView (
646
653
name = user_function .__name__ ,
@@ -650,6 +657,7 @@ def decorator(user_function):
650
657
description = description ,
651
658
tags = tags ,
652
659
owner = owner ,
660
+ udf_string = udf_string ,
653
661
)
654
662
functools .update_wrapper (
655
663
wrapper = on_demand_feature_view_obj , wrapped = user_function
0 commit comments