Skip to content

Commit

Permalink
feat: Add description, tags, owner fields to all feature view classes (
Browse files Browse the repository at this point in the history
…#2440)

* Fix Entity docstring

Signed-off-by: Felix Wang <wangfelix98@gmail.com>

* Adding description, tags, owner fields for all feature view classes

Signed-off-by: Felix Wang <wangfelix98@gmail.com>

* Add docstrings for all feature view __init__ methods

Signed-off-by: Felix Wang <wangfelix98@gmail.com>
  • Loading branch information
felixwang9817 authored Mar 23, 2022
1 parent 702ec49 commit ed5e928
Show file tree
Hide file tree
Showing 8 changed files with 217 additions and 54 deletions.
7 changes: 7 additions & 0 deletions protos/feast/core/FeatureView.proto
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ message FeatureView {
FeatureViewMeta meta = 2;
}

// Next available id: 12
// TODO(adchia): refactor common fields from this and ODFV into separate metadata proto
message FeatureViewSpec {
// Name of the feature view. Must be unique. Not updated.
Expand All @@ -50,9 +51,15 @@ message FeatureViewSpec {
// List of features specifications for each feature defined with this feature view.
repeated FeatureSpecV2 features = 4;

// Description of the feature view.
string description = 10;

// User defined metadata
map<string,string> tags = 5;

// Owner of the feature view.
string owner = 11;

// Features in this feature view can only be retrieved from online serving
// younger than ttl. Ttl is measured as the duration of time between
// the feature's event timestamp and when the feature is retrieved
Expand Down
10 changes: 10 additions & 0 deletions protos/feast/core/OnDemandFeatureView.proto
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ message OnDemandFeatureView {
OnDemandFeatureViewMeta meta = 2;
}

// Next available id: 9
message OnDemandFeatureViewSpec {
// Name of the feature view. Must be unique. Not updated.
string name = 1;
Expand All @@ -48,6 +49,15 @@ message OnDemandFeatureViewSpec {
map<string, OnDemandInput> inputs = 4;

UserDefinedFunction user_defined_function = 5;

// Description of the on demand feature view.
string description = 6;

// User defined metadata.
map<string,string> tags = 7;

// Owner of the on demand feature view.
string owner = 8;
}

message OnDemandFeatureViewMeta {
Expand Down
10 changes: 10 additions & 0 deletions protos/feast/core/RequestFeatureView.proto
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ message RequestFeatureView {
RequestFeatureViewSpec spec = 1;
}

// Next available id: 7
message RequestFeatureViewSpec {
// Name of the feature view. Must be unique. Not updated.
string name = 1;
Expand All @@ -38,4 +39,13 @@ message RequestFeatureViewSpec {

// Request data which contains the underlying data schema and list of associated features
DataSource request_data_source = 3;

// Description of the request feature view.
string description = 4;

// User defined metadata.
map<string,string> tags = 5;

// Owner of the request feature view.
string owner = 6;
}
78 changes: 59 additions & 19 deletions sdk/python/feast/base_feature_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,33 +11,75 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import warnings
from abc import ABC, abstractmethod
from datetime import datetime
from typing import List, Optional, Type
from typing import Dict, List, Optional, Type

from google.protobuf.json_format import MessageToJson
from proto import Message

from feast.feature import Feature
from feast.feature_view_projection import FeatureViewProjection

warnings.simplefilter("once", DeprecationWarning)


class BaseFeatureView(ABC):
"""A FeatureView defines a logical grouping of features to be served."""

"""
A BaseFeatureView defines a logical group of features.
Attributes:
name: The unique name of the base feature view.
features: The list of features defined as part of this base feature view.
description: A human-readable description.
tags: A dictionary of key-value pairs to store arbitrary metadata.
owner: The owner of the base feature view, typically the email of the primary
maintainer.
projection: The feature view projection to be applied to this base feature view
at retrieval time.
created_timestamp (optional): The time when the base feature view was created.
last_updated_timestamp (optional): The time when the base feature view was last
updated.
"""

name: str
features: List[Feature]
description: str
tags: Dict[str, str]
owner: str
projection: FeatureViewProjection
created_timestamp: Optional[datetime]
last_updated_timestamp: Optional[datetime]

@abstractmethod
def __init__(self, name: str, features: List[Feature]):
def __init__(
self,
name: str,
features: List[Feature],
description: str = "",
tags: Optional[Dict[str, str]] = None,
owner: str = "",
):
"""
Creates a BaseFeatureView object.
Args:
name: The unique name of the base feature view.
features: The list of features defined as part of this base feature view.
description (optional): A human-readable description.
tags (optional): A dictionary of key-value pairs to store arbitrary metadata.
owner (optional): The owner of the base feature view, typically the email of the
primary maintainer.
Raises:
ValueError: A field mapping conflicts with an Entity or a Feature.
"""
self.name = name
self.features = features
self.description = description
self.tags = tags or {}
self.owner = owner
self.projection = FeatureViewProjection.from_definition(self)
self.created_timestamp: Optional[datetime] = None
self.last_updated_timestamp: Optional[datetime] = None
self.created_timestamp = None
self.last_updated_timestamp = None

@property
@abstractmethod
Expand All @@ -55,12 +97,7 @@ def from_proto(cls, feature_view_proto):

@abstractmethod
def __copy__(self):
"""
Generates a deep copy of this feature view
Returns:
A copy of this FeatureView
"""
"""Returns a deep copy of this base feature view."""
pass

def __repr__(self):
Expand Down Expand Up @@ -92,10 +129,13 @@ def __eq__(self, other):
"Comparisons should only involve BaseFeatureView class objects."
)

if self.name != other.name:
return False

if sorted(self.features) != sorted(other.features):
if (
self.name != other.name
or sorted(self.features) != sorted(other.features)
or self.description != other.description
or self.tags != other.tags
or self.owner != other.owner
):
return False

return True
Expand Down
3 changes: 1 addition & 2 deletions sdk/python/feast/entity.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,7 @@ class Entity:
with their associated features. If not specified, defaults to the name.
description: A human-readable description.
tags: A dictionary of key-value pairs to store arbitrary metadata.
owner: The owner of the feature service, typically the email of the primary
maintainer.
owner: The owner of the entity, typically the email of the primary maintainer.
created_timestamp: The time when the entity was created.
last_updated_timestamp: The time when the entity was last updated.
"""
Expand Down
57 changes: 43 additions & 14 deletions sdk/python/feast/feature_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,28 +50,36 @@

class FeatureView(BaseFeatureView):
"""
A FeatureView defines a logical grouping of serveable features.
A FeatureView defines a logical group of features.
Args:
name: Name of the group of features.
entities: The entities to which this group of features is associated.
Attributes:
name: The unique name of the feature view.
entities: The list of entities with which this group of features is associated.
ttl: The amount of time this group of features lives. A ttl of 0 indicates that
this group of features lives forever. Note that large ttl's or a ttl of 0
can result in extremely computationally intensive queries.
batch_source: The batch source of data where this group of features is stored.
stream_source (optional): The stream source of data where this group of features
is stored.
features (optional): The set of features defined as part of this FeatureView.
tags (optional): A dictionary of key-value pairs used for organizing
FeatureViews.
features: The list of features defined as part of this feature view.
online: A boolean indicating whether online retrieval is enabled for this feature
view.
description: A human-readable description.
tags: A dictionary of key-value pairs to store arbitrary metadata.
owner: The owner of the feature view, typically the email of the primary
maintainer.
"""

name: str
entities: List[str]
tags: Optional[Dict[str, str]]
ttl: timedelta
online: bool
batch_source: DataSource
stream_source: Optional[DataSource]
features: List[Feature]
online: bool
description: str
tags: Dict[str, str]
owner: str
materialization_intervals: List[Tuple[datetime, datetime]]

@log_exceptions
Expand All @@ -83,12 +91,31 @@ def __init__(
batch_source: DataSource,
stream_source: Optional[DataSource] = None,
features: Optional[List[Feature]] = None,
tags: Optional[Dict[str, str]] = None,
online: bool = True,
description: str = "",
tags: Optional[Dict[str, str]] = None,
owner: str = "",
):
"""
Creates a FeatureView object.
Args:
name: The unique name of the feature view.
entities: The list of entities with which this group of features is associated.
ttl: The amount of time this group of features lives. A ttl of 0 indicates that
this group of features lives forever. Note that large ttl's or a ttl of 0
can result in extremely computationally intensive queries.
batch_source: The batch source of data where this group of features is stored.
stream_source (optional): The stream source of data where this group of features
is stored.
features (optional): The list of features defined as part of this feature view.
online (optional): A boolean indicating whether online retrieval is enabled for
this feature view.
description (optional): A human-readable description.
tags (optional): A dictionary of key-value pairs to store arbitrary metadata.
owner (optional): The owner of the feature view, typically the email of the
primary maintainer.
Raises:
ValueError: A field mapping conflicts with an Entity or a Feature.
"""
Expand All @@ -106,9 +133,8 @@ def __init__(
f"Entity or Feature name."
)

super().__init__(name, _features)
super().__init__(name, _features, description, tags, owner)
self.entities = entities if entities else [DUMMY_ENTITY_NAME]
self.tags = tags if tags is not None else {}

if isinstance(ttl, Duration):
self.ttl = timedelta(seconds=int(ttl.seconds))
Expand All @@ -123,10 +149,9 @@ def __init__(
else:
self.ttl = ttl

self.online = online
self.batch_source = batch_source
self.stream_source = stream_source

self.online = online
self.materialization_intervals = []

# Note: Python requires redefining hash in child classes that override __eq__
Expand Down Expand Up @@ -312,7 +337,9 @@ def to_proto(self) -> FeatureViewProto:
name=self.name,
entities=self.entities,
features=[feature.to_proto() for feature in self.features],
description=self.description,
tags=self.tags,
owner=self.owner,
ttl=(ttl_duration if ttl_duration is not None else None),
online=self.online,
batch_source=batch_source_proto,
Expand Down Expand Up @@ -349,7 +376,9 @@ def from_proto(cls, feature_view_proto: FeatureViewProto):
)
for feature in feature_view_proto.spec.features
],
description=feature_view_proto.spec.description,
tags=dict(feature_view_proto.spec.tags),
owner=feature_view_proto.spec.owner,
online=feature_view_proto.spec.online,
ttl=(
None
Expand Down
Loading

0 comments on commit ed5e928

Please sign in to comment.