From 8e10875eab0bbfa47d09ca807c13cbfa42f7e10a Mon Sep 17 00:00:00 2001 From: Kevin Zhang Date: Mon, 25 Apr 2022 14:16:28 -0700 Subject: [PATCH 01/12] Fix tags Signed-off-by: Kevin Zhang --- protos/feast/types/Field.proto | 3 +++ sdk/python/feast/field.py | 22 +++++++++++++++------- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/protos/feast/types/Field.proto b/protos/feast/types/Field.proto index 8349263cc60..0c3f4fc487d 100644 --- a/protos/feast/types/Field.proto +++ b/protos/feast/types/Field.proto @@ -27,4 +27,7 @@ option go_package = "github.com/feast-dev/feast/go/protos/feast/types"; message Field { string name = 1; feast.types.ValueType.Enum value = 2; + + // User defined metadata + map tags = 3; } diff --git a/sdk/python/feast/field.py b/sdk/python/feast/field.py index f6c88f1850d..ae37bd07922 100644 --- a/sdk/python/feast/field.py +++ b/sdk/python/feast/field.py @@ -12,6 +12,10 @@ # See the License for the specific language governing permissions and # limitations under the License. +from typing import Dict, Optional + +from attr import field + from feast.feature import Feature from feast.protos.feast.core.Feature_pb2 import FeatureSpecV2 as FieldProto from feast.types import FeastType, from_value_type @@ -25,13 +29,15 @@ class Field: Attributes: name: The name of the field. dtype: The type of the field, such as string or float. + tags: User-defined metadata in dictionary form. """ name: str dtype: FeastType + tags: Dict[str, str] def __init__( - self, *, name: str, dtype: FeastType, + self, *, name: str, dtype: FeastType, tags: Optional[Dict[str, str]] = None, ): """ Creates a Field object. @@ -39,17 +45,19 @@ def __init__( Args: name: The name of the field. dtype: The type of the field, such as string or float. + tags (optional): User-defined metadata in dictionary form. """ self.name = name self.dtype = dtype + self.tags = tags or {} def __eq__(self, other): - if self.name != other.name or self.dtype != other.dtype: + if self.name != other.name or self.dtype != other.dtype or self.tags != other.tags: return False return True def __hash__(self): - return hash((self.name, hash(self.dtype))) + return hash((self.name, hash(self.dtype), hash(self.tags))) def __lt__(self, other): return self.name < other.name @@ -58,12 +66,12 @@ def __repr__(self): return f"{self.name}-{self.dtype}" def __str__(self): - return f"Field(name={self.name}, dtype={self.dtype})" + return f"Field(name={self.name}, dtype={self.dtype}, tags={self.tags})" def to_proto(self) -> FieldProto: """Converts a Field object to its protobuf representation.""" value_type = self.dtype.to_value_type() - return FieldProto(name=self.name, value_type=value_type.value) + return FieldProto(name=self.name, value_type=value_type.value, tags=self.tags) @classmethod def from_proto(cls, field_proto: FieldProto): @@ -74,7 +82,7 @@ def from_proto(cls, field_proto: FieldProto): field_proto: FieldProto protobuf object """ value_type = ValueType(field_proto.value_type) - return cls(name=field_proto.name, dtype=from_value_type(value_type=value_type)) + return cls(name=field_proto.name, dtype=from_value_type(value_type=value_type), tags=field_proto.tags) @classmethod def from_feature(cls, feature: Feature): @@ -84,4 +92,4 @@ def from_feature(cls, feature: Feature): Args: feature: Feature object to convert. """ - return cls(name=feature.name, dtype=from_value_type(feature.dtype)) + return cls(name=feature.name, dtype=from_value_type(feature.dtype), tags=feature.labels) From 3b8c38d1cd36d2207b35530d846b627b018cd866 Mon Sep 17 00:00:00 2001 From: Kevin Zhang Date: Mon, 25 Apr 2022 14:17:16 -0700 Subject: [PATCH 02/12] Fix lint Signed-off-by: Kevin Zhang --- sdk/python/feast/field.py | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/sdk/python/feast/field.py b/sdk/python/feast/field.py index ae37bd07922..fa8f969d6a1 100644 --- a/sdk/python/feast/field.py +++ b/sdk/python/feast/field.py @@ -52,7 +52,11 @@ def __init__( self.tags = tags or {} def __eq__(self, other): - if self.name != other.name or self.dtype != other.dtype or self.tags != other.tags: + if ( + self.name != other.name + or self.dtype != other.dtype + or self.tags != other.tags + ): return False return True @@ -82,7 +86,11 @@ def from_proto(cls, field_proto: FieldProto): field_proto: FieldProto protobuf object """ value_type = ValueType(field_proto.value_type) - return cls(name=field_proto.name, dtype=from_value_type(value_type=value_type), tags=field_proto.tags) + return cls( + name=field_proto.name, + dtype=from_value_type(value_type=value_type), + tags=field_proto.tags, + ) @classmethod def from_feature(cls, feature: Feature): @@ -92,4 +100,6 @@ def from_feature(cls, feature: Feature): Args: feature: Feature object to convert. """ - return cls(name=feature.name, dtype=from_value_type(feature.dtype), tags=feature.labels) + return cls( + name=feature.name, dtype=from_value_type(feature.dtype), tags=feature.spec.labels + ) From b9b6bbb38013dc3919a38f3b8ba0d640f79dd872 Mon Sep 17 00:00:00 2001 From: Kevin Zhang Date: Mon, 25 Apr 2022 14:20:30 -0700 Subject: [PATCH 03/12] Fix lint Signed-off-by: Kevin Zhang --- sdk/python/feast/field.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sdk/python/feast/field.py b/sdk/python/feast/field.py index fa8f969d6a1..925c3a8c7a3 100644 --- a/sdk/python/feast/field.py +++ b/sdk/python/feast/field.py @@ -75,7 +75,7 @@ def __str__(self): def to_proto(self) -> FieldProto: """Converts a Field object to its protobuf representation.""" value_type = self.dtype.to_value_type() - return FieldProto(name=self.name, value_type=value_type.value, tags=self.tags) + return FieldProto(name=self.name, value_type=value_type.value, labels=self.tags) @classmethod def from_proto(cls, field_proto: FieldProto): @@ -89,7 +89,7 @@ def from_proto(cls, field_proto: FieldProto): return cls( name=field_proto.name, dtype=from_value_type(value_type=value_type), - tags=field_proto.tags, + tags=dict(field_proto.labels), ) @classmethod @@ -101,5 +101,5 @@ def from_feature(cls, feature: Feature): feature: Feature object to convert. """ return cls( - name=feature.name, dtype=from_value_type(feature.dtype), tags=feature.spec.labels + name=feature.name, dtype=from_value_type(feature.dtype), tags=feature.labels ) From ce5753e61e78a218f20cff94edf12160de4cf561 Mon Sep 17 00:00:00 2001 From: Kevin Zhang Date: Mon, 25 Apr 2022 14:21:47 -0700 Subject: [PATCH 04/12] Fix lint Signed-off-by: Kevin Zhang --- sdk/python/feast/field.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/sdk/python/feast/field.py b/sdk/python/feast/field.py index 925c3a8c7a3..202f5d71d1c 100644 --- a/sdk/python/feast/field.py +++ b/sdk/python/feast/field.py @@ -14,8 +14,6 @@ from typing import Dict, Optional -from attr import field - from feast.feature import Feature from feast.protos.feast.core.Feature_pb2 import FeatureSpecV2 as FieldProto from feast.types import FeastType, from_value_type From 4a83454400d7385a9c3616df811d2d19e3262a29 Mon Sep 17 00:00:00 2001 From: Kevin Zhang Date: Mon, 25 Apr 2022 14:25:20 -0700 Subject: [PATCH 05/12] Convert field to use optional kw args Signed-off-by: Kevin Zhang --- sdk/python/feast/field.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sdk/python/feast/field.py b/sdk/python/feast/field.py index 202f5d71d1c..7ca73f3a878 100644 --- a/sdk/python/feast/field.py +++ b/sdk/python/feast/field.py @@ -35,7 +35,7 @@ class Field: tags: Dict[str, str] def __init__( - self, *, name: str, dtype: FeastType, tags: Optional[Dict[str, str]] = None, + self, *, name: Optional[str] = None, dtype: Optional[FeastType] = None, tags: Optional[Dict[str, str]] = None, ): """ Creates a Field object. @@ -45,8 +45,8 @@ def __init__( dtype: The type of the field, such as string or float. tags (optional): User-defined metadata in dictionary form. """ - self.name = name - self.dtype = dtype + self.name = name or "" + self.dtype = dtype or FeastType.INVALID self.tags = tags or {} def __eq__(self, other): From 0a0e4209ac9799869631b18e90ed82ebfdf328e4 Mon Sep 17 00:00:00 2001 From: Kevin Zhang Date: Mon, 25 Apr 2022 14:26:10 -0700 Subject: [PATCH 06/12] fix Signed-off-by: Kevin Zhang --- sdk/python/feast/field.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/sdk/python/feast/field.py b/sdk/python/feast/field.py index 7ca73f3a878..3eae1f93519 100644 --- a/sdk/python/feast/field.py +++ b/sdk/python/feast/field.py @@ -18,6 +18,7 @@ from feast.protos.feast.core.Feature_pb2 import FeatureSpecV2 as FieldProto from feast.types import FeastType, from_value_type from feast.value_type import ValueType +from feast.types import PrimitiveFeastType class Field: @@ -35,7 +36,11 @@ class Field: tags: Dict[str, str] def __init__( - self, *, name: Optional[str] = None, dtype: Optional[FeastType] = None, tags: Optional[Dict[str, str]] = None, + self, + *, + name: Optional[str] = None, + dtype: Optional[FeastType] = None, + tags: Optional[Dict[str, str]] = None, ): """ Creates a Field object. @@ -46,7 +51,7 @@ def __init__( tags (optional): User-defined metadata in dictionary form. """ self.name = name or "" - self.dtype = dtype or FeastType.INVALID + self.dtype = dtype or PrimitiveFeastType.INVALID self.tags = tags or {} def __eq__(self, other): From 5eeb0d46f5ad41ddb79d15f20a39d0186479f76f Mon Sep 17 00:00:00 2001 From: Kevin Zhang Date: Mon, 25 Apr 2022 14:26:59 -0700 Subject: [PATCH 07/12] Fix Signed-off-by: Kevin Zhang --- sdk/python/feast/field.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sdk/python/feast/field.py b/sdk/python/feast/field.py index 3eae1f93519..2a4ce61850f 100644 --- a/sdk/python/feast/field.py +++ b/sdk/python/feast/field.py @@ -16,9 +16,8 @@ from feast.feature import Feature from feast.protos.feast.core.Feature_pb2 import FeatureSpecV2 as FieldProto -from feast.types import FeastType, from_value_type +from feast.types import FeastType, PrimitiveFeastType, from_value_type from feast.value_type import ValueType -from feast.types import PrimitiveFeastType class Field: From ccf6e9b377c79863a45c09bf681cd9f8ed0b6ea4 Mon Sep 17 00:00:00 2001 From: Kevin Zhang Date: Mon, 25 Apr 2022 14:58:10 -0700 Subject: [PATCH 08/12] Fix Signed-off-by: Kevin Zhang --- protos/feast/types/Field.proto | 3 +++ sdk/python/feast/field.py | 20 ++++++++------------ 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/protos/feast/types/Field.proto b/protos/feast/types/Field.proto index 0c3f4fc487d..af6f1213e2b 100644 --- a/protos/feast/types/Field.proto +++ b/protos/feast/types/Field.proto @@ -25,7 +25,10 @@ option java_outer_classname = "FieldProto"; option go_package = "github.com/feast-dev/feast/go/protos/feast/types"; message Field { + // Name of the feature. Not updatable. string name = 1; + + // Value type of the feature. Not updatable. feast.types.ValueType.Enum value = 2; // User defined metadata diff --git a/sdk/python/feast/field.py b/sdk/python/feast/field.py index 2a4ce61850f..5f25c738209 100644 --- a/sdk/python/feast/field.py +++ b/sdk/python/feast/field.py @@ -15,8 +15,8 @@ from typing import Dict, Optional from feast.feature import Feature -from feast.protos.feast.core.Feature_pb2 import FeatureSpecV2 as FieldProto -from feast.types import FeastType, PrimitiveFeastType, from_value_type +from feast.protos.feast.types.Field_pb2 import Field as FieldProto +from feast.types import FeastType, from_value_type from feast.value_type import ValueType @@ -35,11 +35,7 @@ class Field: tags: Dict[str, str] def __init__( - self, - *, - name: Optional[str] = None, - dtype: Optional[FeastType] = None, - tags: Optional[Dict[str, str]] = None, + self, *, name: str, dtype: FeastType, tags: Optional[Dict[str, str]] = None, ): """ Creates a Field object. @@ -49,8 +45,8 @@ def __init__( dtype: The type of the field, such as string or float. tags (optional): User-defined metadata in dictionary form. """ - self.name = name or "" - self.dtype = dtype or PrimitiveFeastType.INVALID + self.name = name + self.dtype = dtype self.tags = tags or {} def __eq__(self, other): @@ -63,7 +59,7 @@ def __eq__(self, other): return True def __hash__(self): - return hash((self.name, hash(self.dtype), hash(self.tags))) + return hash((self.name, hash(self.dtype))) def __lt__(self, other): return self.name < other.name @@ -77,7 +73,7 @@ def __str__(self): def to_proto(self) -> FieldProto: """Converts a Field object to its protobuf representation.""" value_type = self.dtype.to_value_type() - return FieldProto(name=self.name, value_type=value_type.value, labels=self.tags) + return FieldProto(name=self.name, value_type=value_type.value, tags=self.tags) @classmethod def from_proto(cls, field_proto: FieldProto): @@ -91,7 +87,7 @@ def from_proto(cls, field_proto: FieldProto): return cls( name=field_proto.name, dtype=from_value_type(value_type=value_type), - tags=dict(field_proto.labels), + tags=dict(field_proto.tags), ) @classmethod From fab96ec589fb9bd199abeb74dea2805bb3a41d02 Mon Sep 17 00:00:00 2001 From: Kevin Zhang Date: Tue, 26 Apr 2022 10:09:50 -0700 Subject: [PATCH 09/12] Fix Signed-off-by: Kevin Zhang --- protos/feast/types/Field.proto | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/protos/feast/types/Field.proto b/protos/feast/types/Field.proto index af6f1213e2b..eb0ee80b83d 100644 --- a/protos/feast/types/Field.proto +++ b/protos/feast/types/Field.proto @@ -29,7 +29,7 @@ message Field { string name = 1; // Value type of the feature. Not updatable. - feast.types.ValueType.Enum value = 2; + feast.types.ValueType.Enum value_type = 2; // User defined metadata map tags = 3; From 3654ebb1e960970c7b4e2eca3a21bd20934616cd Mon Sep 17 00:00:00 2001 From: Kevin Zhang Date: Tue, 26 Apr 2022 10:32:33 -0700 Subject: [PATCH 10/12] Fix Signed-off-by: Kevin Zhang --- protos/feast/core/Feature.proto | 4 ++-- protos/feast/types/Field.proto | 8 +------- sdk/python/feast/field.py | 2 +- 3 files changed, 4 insertions(+), 10 deletions(-) diff --git a/protos/feast/core/Feature.proto b/protos/feast/core/Feature.proto index a96423bfbde..f6826bef810 100644 --- a/protos/feast/core/Feature.proto +++ b/protos/feast/core/Feature.proto @@ -31,6 +31,6 @@ message FeatureSpecV2 { // Value type of the feature. Not updatable. feast.types.ValueType.Enum value_type = 2; - // Labels for user defined metadata on a feature - map labels = 3; + // Tags for user defined metadata on a feature + map tags = 3; } diff --git a/protos/feast/types/Field.proto b/protos/feast/types/Field.proto index eb0ee80b83d..8349263cc60 100644 --- a/protos/feast/types/Field.proto +++ b/protos/feast/types/Field.proto @@ -25,12 +25,6 @@ option java_outer_classname = "FieldProto"; option go_package = "github.com/feast-dev/feast/go/protos/feast/types"; message Field { - // Name of the feature. Not updatable. string name = 1; - - // Value type of the feature. Not updatable. - feast.types.ValueType.Enum value_type = 2; - - // User defined metadata - map tags = 3; + feast.types.ValueType.Enum value = 2; } diff --git a/sdk/python/feast/field.py b/sdk/python/feast/field.py index 5f25c738209..77011e6758c 100644 --- a/sdk/python/feast/field.py +++ b/sdk/python/feast/field.py @@ -15,7 +15,7 @@ from typing import Dict, Optional from feast.feature import Feature -from feast.protos.feast.types.Field_pb2 import Field as FieldProto +from feast.protos.feast.core.Feature_pb2 import FeatureSpecV2 as FieldProto from feast.types import FeastType, from_value_type from feast.value_type import ValueType From 7d3975ff379730a91b4e95ea7b42565878dec95a Mon Sep 17 00:00:00 2001 From: Kevin Zhang Date: Tue, 26 Apr 2022 10:37:02 -0700 Subject: [PATCH 11/12] Fix lint Signed-off-by: Kevin Zhang --- sdk/python/feast/feature.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sdk/python/feast/feature.py b/sdk/python/feast/feature.py index 57f75c90d76..d1f96c302ae 100644 --- a/sdk/python/feast/feature.py +++ b/sdk/python/feast/feature.py @@ -91,7 +91,7 @@ def to_proto(self) -> FeatureSpecProto: value_type = ValueTypeProto.Enum.Value(self.dtype.name) return FeatureSpecProto( - name=self.name, value_type=value_type, labels=self.labels, + name=self.name, value_type=value_type, tags=self.labels, ) @classmethod @@ -106,7 +106,7 @@ def from_proto(cls, feature_proto: FeatureSpecProto): feature = cls( name=feature_proto.name, dtype=ValueType(feature_proto.value_type), - labels=dict(feature_proto.labels), + labels=dict(feature_proto.tags), ) return feature From fbf27be363f12ff4044c3da12383cddbb2959e7e Mon Sep 17 00:00:00 2001 From: Kevin Zhang Date: Tue, 26 Apr 2022 10:47:34 -0700 Subject: [PATCH 12/12] Fix java tests Signed-off-by: Kevin Zhang --- .../java/feast/serving/util/DataGenerator.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/java/serving/src/test/java/feast/serving/util/DataGenerator.java b/java/serving/src/test/java/feast/serving/util/DataGenerator.java index e38d1ce4596..7a310828d2e 100644 --- a/java/serving/src/test/java/feast/serving/util/DataGenerator.java +++ b/java/serving/src/test/java/feast/serving/util/DataGenerator.java @@ -126,11 +126,11 @@ public static EntityProto.EntitySpecV2 createEntitySpecV2( } public static FeatureProto.FeatureSpecV2 createFeatureSpecV2( - String name, ValueProto.ValueType.Enum valueType, Map labels) { + String name, ValueProto.ValueType.Enum valueType, Map tags) { return FeatureProto.FeatureSpecV2.newBuilder() .setName(name) .setValueType(valueType) - .putAllLabels(labels) + .putAllTags(tags) .build(); } @@ -140,7 +140,7 @@ public static FeatureTableSpec createFeatureTableSpec( List entities, Map features, int maxAgeSecs, - Map labels) { + Map tags) { return FeatureTableSpec.newBuilder() .setName(name) @@ -152,7 +152,7 @@ public static FeatureTableSpec createFeatureTableSpec( FeatureSpecV2.newBuilder() .setName(entry.getKey()) .setValueType(entry.getValue()) - .putAllLabels(labels) + .putAllTags(tags) .build()) .collect(Collectors.toList())) .setMaxAge(Duration.newBuilder().setSeconds(3600).build()) @@ -169,7 +169,7 @@ public static FeatureTableSpec createFeatureTableSpec( .setUri("/dev/null") .build()) .build()) - .putAllLabels(labels) + .putAllLabels(tags) .build(); } @@ -178,7 +178,7 @@ public static FeatureTableSpec createFeatureTableSpec( List entities, ImmutableMap features, int maxAgeSecs, - Map labels) { + Map tags) { return FeatureTableSpec.newBuilder() .setName(name) @@ -190,11 +190,11 @@ public static FeatureTableSpec createFeatureTableSpec( FeatureSpecV2.newBuilder() .setName(entry.getKey()) .setValueType(entry.getValue()) - .putAllLabels(labels) + .putAllTags(tags) .build()) .collect(Collectors.toList())) .setMaxAge(Duration.newBuilder().setSeconds(maxAgeSecs).build()) - .putAllLabels(labels) + .putAllLabels(tags) .build(); }