Skip to content

Commit 31a0ad5

Browse files
chore: Add conversion from ValueTypeProto.Enum to new Feast type system (#2489)
* Add conversion from ValueTypeProto.Enum to new Feast type system Signed-off-by: Felix Wang <wangfelix98@gmail.com> * Fix conversion method Signed-off-by: Felix Wang <wangfelix98@gmail.com>
1 parent 4e82bee commit 31a0ad5

File tree

2 files changed

+74
-13
lines changed

2 files changed

+74
-13
lines changed

sdk/python/feast/types.py

Lines changed: 57 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
# limitations under the License.
1414
from abc import ABC, abstractmethod
1515
from enum import Enum
16-
from typing import Union
16+
from typing import Dict, Union
1717

1818
from feast.protos.feast.types.Value_pb2 import ValueType as ValueTypeProto
1919

@@ -40,30 +40,38 @@ def __init__(self):
4040
pass
4141

4242
@abstractmethod
43-
def to_int(self) -> int:
43+
def to_value_type(self) -> ValueTypeProto.Enum:
4444
"""
45-
Converts a ComplexFeastType object to the appropriate int value corresponding to
46-
the correct ValueTypeProto.Enum value.
45+
Converts a ComplexFeastType object to the corresponding ValueTypeProto.Enum value.
4746
"""
4847
raise NotImplementedError
4948

49+
def __eq__(self, other):
50+
return self.to_value_type() == other.to_value_type()
51+
5052

5153
class PrimitiveFeastType(Enum):
5254
"""
5355
A PrimitiveFeastType represents a primitive type in Feast.
56+
57+
Note that these values must match the values in ValueTypeProto.Enum. See
58+
/feast/protos/types/Value.proto for the exact values.
5459
"""
5560

5661
INVALID = 0
5762
BYTES = 1
5863
STRING = 2
5964
INT32 = 3
6065
INT64 = 4
61-
FLOAT32 = 5
62-
FLOAT64 = 6
66+
FLOAT64 = 5
67+
FLOAT32 = 6
6368
BOOL = 7
6469
UNIX_TIMESTAMP = 8
6570

66-
def to_int(self) -> int:
71+
def to_value_type(self) -> ValueTypeProto.Enum:
72+
"""
73+
Converts a PrimitiveFeastType object to the corresponding ValueTypeProto.Enum value.
74+
"""
6775
value_type_name = PRIMITIVE_FEAST_TYPES_TO_VALUE_TYPES[self.name]
6876
return ValueTypeProto.Enum.Value(value_type_name)
6977

@@ -110,8 +118,49 @@ def __init__(self, base_type: Union[PrimitiveFeastType, ComplexFeastType]):
110118

111119
self.base_type = base_type
112120

113-
def to_int(self) -> int:
121+
def to_value_type(self) -> int:
114122
assert isinstance(self.base_type, PrimitiveFeastType)
115123
value_type_name = PRIMITIVE_FEAST_TYPES_TO_VALUE_TYPES[self.base_type.name]
116124
value_type_list_name = value_type_name + "_LIST"
117125
return ValueTypeProto.Enum.Value(value_type_list_name)
126+
127+
128+
VALUE_TYPES_TO_FEAST_TYPES: Dict[
129+
"ValueTypeProto.Enum", Union[ComplexFeastType, PrimitiveFeastType]
130+
] = {
131+
ValueTypeProto.Enum.INVALID: Invalid,
132+
ValueTypeProto.Enum.BYTES: Bytes,
133+
ValueTypeProto.Enum.STRING: String,
134+
ValueTypeProto.Enum.INT32: Int32,
135+
ValueTypeProto.Enum.INT64: Int64,
136+
ValueTypeProto.Enum.DOUBLE: Float64,
137+
ValueTypeProto.Enum.FLOAT: Float32,
138+
ValueTypeProto.Enum.BOOL: Bool,
139+
ValueTypeProto.Enum.UNIX_TIMESTAMP: UnixTimestamp,
140+
ValueTypeProto.Enum.BYTES_LIST: Array(Bytes),
141+
ValueTypeProto.Enum.STRING_LIST: Array(String),
142+
ValueTypeProto.Enum.INT32_LIST: Array(Int32),
143+
ValueTypeProto.Enum.INT64_LIST: Array(Int64),
144+
ValueTypeProto.Enum.DOUBLE_LIST: Array(Float64),
145+
ValueTypeProto.Enum.FLOAT_LIST: Array(Float32),
146+
ValueTypeProto.Enum.BOOL_LIST: Array(Bool),
147+
ValueTypeProto.Enum.UNIX_TIMESTAMP_LIST: Array(UnixTimestamp),
148+
}
149+
150+
151+
def from_value_type(
152+
value_type: ValueTypeProto.Enum,
153+
) -> Union[ComplexFeastType, PrimitiveFeastType]:
154+
"""
155+
Converts a ValueTypeProto.Enum to a Feast type.
156+
157+
Args:
158+
value_type: The ValueTypeProto.Enum to be converted.
159+
160+
Raises:
161+
ValueError: The conversion could not be performed.
162+
"""
163+
if value_type in VALUE_TYPES_TO_FEAST_TYPES:
164+
return VALUE_TYPES_TO_FEAST_TYPES[value_type]
165+
166+
raise ValueError(f"Could not convert value type {value_type} to FeastType.")
Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,35 @@
11
import pytest
22

33
from feast.protos.feast.types.Value_pb2 import ValueType as ValueTypeProto
4-
from feast.types import Array, Float32, String
4+
from feast.types import Array, Float32, String, from_value_type
55

66

77
def test_primitive_feast_type():
8-
assert String.to_int() == ValueTypeProto.Enum.Value("STRING")
9-
assert Float32.to_int() == ValueTypeProto.Enum.Value("FLOAT")
8+
assert String.to_value_type() == ValueTypeProto.Enum.Value("STRING")
9+
assert from_value_type(String.to_value_type()) == String
10+
assert Float32.to_value_type() == ValueTypeProto.Enum.Value("FLOAT")
11+
assert from_value_type(Float32.to_value_type()) == Float32
1012

1113

1214
def test_array_feast_type():
1315
array_float_32 = Array(Float32)
14-
assert array_float_32.to_int() == ValueTypeProto.Enum.Value("FLOAT_LIST")
16+
assert array_float_32.to_value_type() == ValueTypeProto.Enum.Value("FLOAT_LIST")
17+
assert from_value_type(array_float_32.to_value_type()) == array_float_32
1518

1619
array_string = Array(String)
17-
assert array_string.to_int() == ValueTypeProto.Enum.Value("STRING_LIST")
20+
assert array_string.to_value_type() == ValueTypeProto.Enum.Value("STRING_LIST")
21+
assert from_value_type(array_string.to_value_type()) == array_string
1822

1923
with pytest.raises(ValueError):
2024
_ = Array(Array)
2125

2226
with pytest.raises(ValueError):
2327
_ = Array(Array(String))
28+
29+
30+
def test_all_value_types():
31+
values = ValueTypeProto.Enum.values()
32+
for value in values:
33+
# We do not support the NULL type.
34+
if value != ValueTypeProto.Enum.Value("NULL"):
35+
assert from_value_type(value).to_value_type() == value

0 commit comments

Comments
 (0)