Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions protos/feast/core/FeatureService.proto
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ message FeatureServiceSpec {

// Description of the feature service.
string description = 5;

// Owner of the feature service.
string owner = 6;
}


Expand Down
82 changes: 49 additions & 33 deletions sdk/python/feast/feature_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,25 @@

class FeatureService:
"""
A feature service is a logical grouping of features for retrieval (training or serving).
The features grouped by a feature service may come from any number of feature views.

Args:
name: Unique name of the feature service.
features: A list of Features that are grouped as part of this FeatureService.
The list may contain Feature Views, Feature Tables, or a subset of either.
tags (optional): A dictionary of key-value pairs used for organizing Feature
Services.
A feature service defines a logical group of features from one or more feature views.
This group of features can be retrieved together during training or serving.

Attributes:
name: The unique name of the feature service.
feature_view_projections: A list containing feature views and feature view
projections, representing the features in the feature service.
description: A human-readable description.
tags: A dictionary of key-value pairs to store arbitrary metadata.
owner: The owner of the feature service.
created_timestamp: The time when the feature service was created.
last_updated_timestamp: The time when the feature service was last updated.
"""

_name: str
_feature_view_projections: List[FeatureViewProjection]
_description: str
_tags: Dict[str, str]
_description: Optional[str] = None
_owner: str
_created_timestamp: Optional[datetime] = None
_last_updated_timestamp: Optional[datetime] = None

Expand All @@ -42,8 +46,9 @@ def __init__(
self,
name: str,
features: List[Union[FeatureView, OnDemandFeatureView]],
tags: Optional[Dict[str, str]] = None,
description: Optional[str] = None,
tags: Dict[str, str] = None,
description: str = "",
owner: str = "",
):
"""
Creates a FeatureService object.
Expand All @@ -59,12 +64,13 @@ def __init__(
self._feature_view_projections.append(feature_grouping.projection)
else:
raise ValueError(
"The FeatureService {fs_name} has been provided with an invalid type"
f"The feature service {name} has been provided with an invalid type "
f'{type(feature_grouping)} as part of the "features" argument.)'
)

self._tags = tags or {}
self._description = description
self._tags = tags or {}
self._owner = owner
self._created_timestamp = None
self._last_updated_timestamp = None

Expand All @@ -83,7 +89,13 @@ def __eq__(self, other):
raise TypeError(
"Comparisons should only involve FeatureService class objects."
)
if self.tags != other.tags or self.name != other.name:

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

if sorted(self.feature_view_projections) != sorted(
Expand Down Expand Up @@ -111,6 +123,14 @@ def feature_view_projections(
):
self._feature_view_projections = feature_view_projections

@property
def description(self) -> str:
return self._description

@description.setter
def description(self, description: str):
self._description = description

@property
def tags(self) -> Dict[str, str]:
return self._tags
Expand All @@ -120,12 +140,12 @@ def tags(self, tags: Dict[str, str]):
self._tags = tags

@property
def description(self) -> Optional[str]:
return self._description
def owner(self) -> str:
return self._owner

@description.setter
def description(self, description: str):
self._description = description
@owner.setter
def owner(self, owner: str):
self._owner = owner

@property
def created_timestamp(self) -> Optional[datetime]:
Expand Down Expand Up @@ -155,11 +175,8 @@ def from_proto(feature_service_proto: FeatureServiceProto):
name=feature_service_proto.spec.name,
features=[],
tags=dict(feature_service_proto.spec.tags),
description=(
feature_service_proto.spec.description
if feature_service_proto.spec.description != ""
else None
),
description=feature_service_proto.spec.description,
owner=feature_service_proto.spec.owner,
)
fs.feature_view_projections.extend(
[
Expand All @@ -181,29 +198,28 @@ def from_proto(feature_service_proto: FeatureServiceProto):

def to_proto(self) -> FeatureServiceProto:
"""
Converts a FeatureService to its protobuf representation.
Converts a feature service to its protobuf representation.

Returns:
A FeatureServiceProto protobuf.
"""
meta = FeatureServiceMeta()
if self.created_timestamp:
meta.created_timestamp.FromDatetime(self.created_timestamp)
if self.last_updated_timestamp:
meta.last_updated_timestamp.FromDatetime(self.last_updated_timestamp)

spec = FeatureServiceSpec(
name=self.name,
features=[
projection.to_proto() for projection in self.feature_view_projections
],
tags=self.tags,
description=self.description,
owner=self.owner,
)

if self.tags:
spec.tags.update(self.tags)
if self.description:
spec.description = self.description

feature_service_proto = FeatureServiceProto(spec=spec, meta=meta)
return feature_service_proto
return FeatureServiceProto(spec=spec, meta=meta)

def validate(self):
pass
29 changes: 19 additions & 10 deletions sdk/python/feast/feature_view_projection.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import Dict, List, Optional
from typing import Dict, List

from attr import dataclass

Expand All @@ -10,15 +10,26 @@

@dataclass
class FeatureViewProjection:
"""
A feature view projection represents a set of features from a single feature view.

Attributes:
name: The unique name of the feature view projection.
name_alias: An optional alias for the name.
features: The list of features represented by the feature view projection.
join_key_map: A map to modify join key columns during retrieval of this feature
view projection.
"""

name: str
name_alias: Optional[str]
features: List[Feature]
name_alias: str = ""
features: List[Feature] = []
join_key_map: Dict[str, str] = {}

def name_to_use(self):
return self.name_alias or self.name

def to_proto(self):
def to_proto(self) -> FeatureViewProjectionProto:
feature_reference_proto = FeatureViewProjectionProto(
feature_view_name=self.name,
feature_view_name_alias=self.name_alias,
Expand All @@ -31,21 +42,19 @@ def to_proto(self):

@staticmethod
def from_proto(proto: FeatureViewProjectionProto):
ref = FeatureViewProjection(
feature_view_projection = FeatureViewProjection(
name=proto.feature_view_name,
name_alias=proto.feature_view_name_alias,
features=[],
join_key_map=dict(proto.join_key_map),
)
for feature_column in proto.feature_columns:
ref.features.append(Feature.from_proto(feature_column))
feature_view_projection.features.append(Feature.from_proto(feature_column))

return ref
return feature_view_projection

@staticmethod
def from_definition(feature_grouping):
return FeatureViewProjection(
name=feature_grouping.name,
name_alias=None,
features=feature_grouping.features,
name=feature_grouping.name, features=feature_grouping.features,
)