Skip to content

Commit

Permalink
feat: Adds description attribute for features/fields (feast-dev#3425)
Browse files Browse the repository at this point in the history
* Adding description as a first-class attribute for features/fields

Signed-off-by: Amom Mendes <[email protected]>

* Formatting

Signed-off-by: Amom Mendes <[email protected]>

Signed-off-by: Amom Mendes <[email protected]>
  • Loading branch information
amommendes authored Jan 1, 2023
1 parent 41c0537 commit 26f4881
Show file tree
Hide file tree
Showing 7 changed files with 69 additions and 4 deletions.
4 changes: 4 additions & 0 deletions protos/feast/core/Feature.proto
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,8 @@ message FeatureSpecV2 {

// Tags for user defined metadata on a feature
map<string,string> tags = 3;

// Description of the feature.

string description = 4;
}
6 changes: 6 additions & 0 deletions protos/feast/types/Field.proto
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,10 @@ option go_package = "github.com/feast-dev/feast/go/protos/feast/types";
message Field {
string name = 1;
feast.types.ValueType.Enum value = 2;

// Tags for user defined metadata on a field
map<string,string> tags = 3;

// Description of the field.
string description = 4;
}
11 changes: 11 additions & 0 deletions sdk/python/feast/feature.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ def __init__(
self,
name: str,
dtype: ValueType,
description: str = "",
labels: Optional[Dict[str, str]] = None,
):
"""Creates a Feature object."""
Expand All @@ -42,6 +43,7 @@ def __init__(
if dtype is ValueType.UNKNOWN:
raise ValueError(f"dtype cannot be {dtype}")
self._dtype = dtype
self._description = description
if labels is None:
self._labels = dict()
else:
Expand Down Expand Up @@ -77,6 +79,13 @@ def dtype(self) -> ValueType:
"""
return self._dtype

@property
def description(self) -> str:
"""
Gets the description of the feature
"""
return self._description

@property
def labels(self) -> Dict[str, str]:
"""
Expand All @@ -96,6 +105,7 @@ def to_proto(self) -> FeatureSpecProto:
return FeatureSpecProto(
name=self.name,
value_type=value_type,
description=self.description,
tags=self.labels,
)

Expand All @@ -111,6 +121,7 @@ def from_proto(cls, feature_proto: FeatureSpecProto):
feature = cls(
name=feature_proto.name,
dtype=ValueType(feature_proto.value_type),
description=feature_proto.description,
labels=dict(feature_proto.tags),
)

Expand Down
16 changes: 13 additions & 3 deletions sdk/python/feast/field.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ 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.
tags (optional): User-defined metadata in dictionary form.
"""

name: str
Expand All @@ -42,6 +42,7 @@ def __init__(
*,
name: str,
dtype: FeastType,
description: str = "",
tags: Optional[Dict[str, str]] = None,
):
"""
Expand All @@ -54,6 +55,7 @@ def __init__(
"""
self.name = name
self.dtype = dtype
self.description = description
self.tags = tags or {}

def __eq__(self, other):
Expand Down Expand Up @@ -83,7 +85,12 @@ 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,
description=self.description,
tags=self.tags,
)

@classmethod
def from_proto(cls, field_proto: FieldProto):
Expand All @@ -109,5 +116,8 @@ def from_feature(cls, feature: Feature):
feature: Feature object to convert.
"""
return cls(
name=feature.name, dtype=from_value_type(feature.dtype), tags=feature.labels
name=feature.name,
dtype=from_value_type(feature.dtype),
description=feature.description,
tags=feature.labels,
)
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
schema=[
Field(name="conv_rate", dtype=Float32),
Field(name="acc_rate", dtype=Float32),
Field(name="avg_daily_trips", dtype=Int64),
Field(name="avg_daily_trips", dtype=Int64, description="Average daily trips"),
],
online=True,
source=driver_stats_source,
Expand Down
29 changes: 29 additions & 0 deletions sdk/python/tests/unit/test_feature.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
from feast.field import Feature, Field
from feast.types import Float32
from feast.value_type import ValueType


def test_feature_serialization_with_description():
expected_description = "Average daily trips"
feature = Feature(
name="avg_daily_trips", dtype=ValueType.FLOAT, description=expected_description
)
serialized_feature = feature.to_proto()

assert serialized_feature.description == expected_description


def test_field_serialization_with_description():
expected_description = "Average daily trips"
field = Field(
name="avg_daily_trips", dtype=Float32, description=expected_description
)
feature = Feature(
name="avg_daily_trips", dtype=ValueType.FLOAT, description=expected_description
)

serialized_field = field.to_proto()
field_from_feature = Field.from_feature(feature)

assert serialized_field.description == expected_description
assert field_from_feature.description == expected_description
5 changes: 5 additions & 0 deletions ui/src/pages/features/FeatureOverviewTab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,11 @@ const FeatureOverviewTab = () => {
{feast.types.ValueType.Enum[featureData?.valueType!]}
</EuiDescriptionListDescription>

<EuiDescriptionListTitle>Description</EuiDescriptionListTitle>
<EuiDescriptionListDescription>
{featureData?.description}
</EuiDescriptionListDescription>

<EuiDescriptionListTitle>FeatureView</EuiDescriptionListTitle>
<EuiDescriptionListDescription>
<EuiCustomLink
Expand Down

0 comments on commit 26f4881

Please sign in to comment.