Skip to content

Commit 1279612

Browse files
feat: Add Field class (#2500)
* Add Field class Signed-off-by: Felix Wang <[email protected]> * Add __hash__ Signed-off-by: Felix Wang <[email protected]> * Fix __hash__ Signed-off-by: Felix Wang <[email protected]>
1 parent 7bc06d0 commit 1279612

File tree

2 files changed

+110
-6
lines changed

2 files changed

+110
-6
lines changed

sdk/python/feast/field.py

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
# Copyright 2022 The Feast Authors
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# https://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
from feast.feature import Feature
16+
from feast.protos.feast.core.Feature_pb2 import FeatureSpecV2 as FieldProto
17+
from feast.types import FeastType, from_value_type
18+
19+
20+
class Field:
21+
"""
22+
A Field represents a set of values with the same structure.
23+
24+
Attributes:
25+
name: The name of the field.
26+
dtype: The type of the field, such as string or float.
27+
"""
28+
29+
name: str
30+
dtype: FeastType
31+
32+
def __init__(
33+
self, *, name: str, dtype: FeastType,
34+
):
35+
"""
36+
Creates a Field object.
37+
38+
Args:
39+
name: The name of the field.
40+
dtype: The type of the field, such as string or float.
41+
"""
42+
self.name = name
43+
self.dtype = dtype
44+
45+
def __eq__(self, other):
46+
if self.name != other.name or self.dtype != other.dtype:
47+
return False
48+
return True
49+
50+
def __hash__(self):
51+
return hash((self.name, hash(self.dtype)))
52+
53+
def __lt__(self, other):
54+
return self.name < other.name
55+
56+
def __repr__(self):
57+
return f"{self.name}-{self.dtype}"
58+
59+
def __str__(self):
60+
return f"Field(name={self.name}, dtype={self.dtype})"
61+
62+
def to_proto(self) -> FieldProto:
63+
"""Converts a Field object to its protobuf representation."""
64+
return FieldProto(name=self.name, value_type=self.dtype.to_value_type())
65+
66+
@classmethod
67+
def from_proto(cls, field_proto: FieldProto):
68+
"""
69+
Creates a Field object from a protobuf representation.
70+
71+
Args:
72+
field_proto: FieldProto protobuf object
73+
"""
74+
return cls(name=field_proto.name, dtype=from_value_type(field_proto.value_type))
75+
76+
@classmethod
77+
def from_feature(cls, feature: Feature):
78+
"""
79+
Creates a Field object from a Feature object.
80+
81+
Args:
82+
feature: Feature object to convert.
83+
"""
84+
return cls(name=feature.name, dtype=from_value_type(feature.dtype.value))

sdk/python/feast/types.py

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ def to_value_type(self) -> ValueTypeProto.Enum:
4646
"""
4747
raise NotImplementedError
4848

49+
def __hash__(self):
50+
return hash(self.to_value_type())
51+
4952
def __eq__(self, other):
5053
return self.to_value_type() == other.to_value_type()
5154

@@ -75,6 +78,9 @@ def to_value_type(self) -> ValueTypeProto.Enum:
7578
value_type_name = PRIMITIVE_FEAST_TYPES_TO_VALUE_TYPES[self.name]
7679
return ValueTypeProto.Enum.Value(value_type_name)
7780

81+
def __str__(self):
82+
return PRIMITIVE_FEAST_TYPES_TO_STRING[self.name]
83+
7884

7985
Invalid = PrimitiveFeastType.INVALID
8086
Bytes = PrimitiveFeastType.BYTES
@@ -99,6 +105,18 @@ def to_value_type(self) -> ValueTypeProto.Enum:
99105
UnixTimestamp,
100106
]
101107

108+
PRIMITIVE_FEAST_TYPES_TO_STRING = {
109+
"INVALID": "Invalid",
110+
"STRING": "String",
111+
"BYTES": "Bytes",
112+
"BOOL": "Bool",
113+
"INT32": "Int32",
114+
"INT64": "Int64",
115+
"FLOAT32": "Float32",
116+
"FLOAT64": "Float64",
117+
"UNIX_TIMESTAMP": "UnixTimestamp",
118+
}
119+
102120

103121
class Array(ComplexFeastType):
104122
"""
@@ -124,10 +142,14 @@ def to_value_type(self) -> int:
124142
value_type_list_name = value_type_name + "_LIST"
125143
return ValueTypeProto.Enum.Value(value_type_list_name)
126144

145+
def __str__(self):
146+
return f"Array({self.base_type})"
147+
148+
149+
FeastType = Union[ComplexFeastType, PrimitiveFeastType]
150+
127151

128-
VALUE_TYPES_TO_FEAST_TYPES: Dict[
129-
"ValueTypeProto.Enum", Union[ComplexFeastType, PrimitiveFeastType]
130-
] = {
152+
VALUE_TYPES_TO_FEAST_TYPES: Dict["ValueTypeProto.Enum", FeastType] = {
131153
ValueTypeProto.Enum.INVALID: Invalid,
132154
ValueTypeProto.Enum.BYTES: Bytes,
133155
ValueTypeProto.Enum.STRING: String,
@@ -148,9 +170,7 @@ def to_value_type(self) -> int:
148170
}
149171

150172

151-
def from_value_type(
152-
value_type: ValueTypeProto.Enum,
153-
) -> Union[ComplexFeastType, PrimitiveFeastType]:
173+
def from_value_type(value_type: ValueTypeProto.Enum,) -> FeastType:
154174
"""
155175
Converts a ValueTypeProto.Enum to a Feast type.
156176

0 commit comments

Comments
 (0)