From 8c8d87d1dc58418ab9dcaedaa94310f6ff8b3122 Mon Sep 17 00:00:00 2001 From: Nick Quinn Date: Fri, 24 Apr 2026 13:09:44 -0700 Subject: [PATCH 1/6] feat: Make udf optional if agg defined (#5689) Signed-off-by: Nick Quinn --- sdk/python/feast/on_demand_feature_view.py | 4 +++ .../tests/unit/test_on_demand_feature_view.py | 28 +++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/sdk/python/feast/on_demand_feature_view.py b/sdk/python/feast/on_demand_feature_view.py index 198c33675fa..36f6541f619 100644 --- a/sdk/python/feast/on_demand_feature_view.py +++ b/sdk/python/feast/on_demand_feature_view.py @@ -527,6 +527,10 @@ def _validate_sources_config(self) -> None: def _validate_transformation_config(self) -> None: """Validate transformation configuration.""" + # Aggregations provide their own transformation; no udf/feature_transformation required. + if self.aggregations: + return + if not self.feature_transformation: raise ValueError(ODFVErrorMessages.no_transformation_provided()) diff --git a/sdk/python/tests/unit/test_on_demand_feature_view.py b/sdk/python/tests/unit/test_on_demand_feature_view.py index 07e9e6a0b94..d587d44c3f2 100644 --- a/sdk/python/tests/unit/test_on_demand_feature_view.py +++ b/sdk/python/tests/unit/test_on_demand_feature_view.py @@ -26,6 +26,7 @@ PythonTransformation, on_demand_feature_view, ) +from feast.aggregation import Aggregation from feast.types import Float32 @@ -590,3 +591,30 @@ def test_eq_considers_track_metrics(): odfv_untracked = OnDemandFeatureView(**common, track_metrics=False) assert odfv_tracked != odfv_untracked + + +def test_aggregations_valid_without_udf(): + """An ODFV with aggregations must pass ensure_valid() without a udf or feature_transformation.""" + from datetime import timedelta + + file_source = FileSource(name="my-file-source", path="test.parquet") + feature_view = FeatureView( + name="my-feature-view", + entities=[], + schema=[Field(name="purchase_count", dtype=Float32)], + source=file_source, + ) + odfv = OnDemandFeatureView( + name="agg-odfv", + sources=[feature_view], + schema=[Field(name="purchase_sum_30d", dtype=Float32)], + aggregations=[ + Aggregation( + column="purchase_count", + function="sum", + time_window=timedelta(days=30), + ) + ], + ) + # Must not raise + odfv.ensure_valid() From f64c1cb47d624967bf05d4fbc34f8739f47c0e58 Mon Sep 17 00:00:00 2001 From: Nick Quinn Date: Fri, 24 Apr 2026 14:10:52 -0700 Subject: [PATCH 2/6] fix: sort Aggregation import in test_on_demand_feature_view.py Fixes ruff I001 import ordering violation introduced with the aggregations-without-udf test. Co-Authored-By: Claude Sonnet 4.6 Signed-off-by: Nick Quinn --- sdk/python/tests/unit/test_on_demand_feature_view.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/python/tests/unit/test_on_demand_feature_view.py b/sdk/python/tests/unit/test_on_demand_feature_view.py index d587d44c3f2..78ddd851c70 100644 --- a/sdk/python/tests/unit/test_on_demand_feature_view.py +++ b/sdk/python/tests/unit/test_on_demand_feature_view.py @@ -17,6 +17,7 @@ import pandas as pd import pytest +from feast.aggregation import Aggregation from feast.feature_view import FeatureView from feast.field import Field from feast.infra.offline_stores.file_source import FileSource @@ -26,7 +27,6 @@ PythonTransformation, on_demand_feature_view, ) -from feast.aggregation import Aggregation from feast.types import Float32 From be9a625e755e561ad7d3460e2c4d04134426f393 Mon Sep 17 00:00:00 2001 From: Nick Quinn Date: Fri, 24 Apr 2026 14:13:00 -0700 Subject: [PATCH 3/6] fix: skip backward-compat UDF fallback for aggregation-only ODFVs _parse_transformation_from_proto fell through to _handle_backward_compatible_udf when feature_transformation was absent, crashing on dill.loads(b"") for ODFVs that have no transformation but do have aggregations. Return None early when transformation_type is None and proto.spec.aggregations is non-empty. Co-Authored-By: Claude Sonnet 4.6 Signed-off-by: Nick Quinn --- sdk/python/feast/on_demand_feature_view.py | 2 ++ .../tests/unit/test_on_demand_feature_view.py | 30 +++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/sdk/python/feast/on_demand_feature_view.py b/sdk/python/feast/on_demand_feature_view.py index 36f6541f619..0cb0d032c94 100644 --- a/sdk/python/feast/on_demand_feature_view.py +++ b/sdk/python/feast/on_demand_feature_view.py @@ -787,6 +787,8 @@ def _parse_transformation_from_proto( feature_transformation.substrait_transformation ) elif transformation_type is None: + if proto.spec.aggregations: + return None # Handle backward compatibility case where feature_transformation is cleared return cls._handle_backward_compatible_udf(proto) else: diff --git a/sdk/python/tests/unit/test_on_demand_feature_view.py b/sdk/python/tests/unit/test_on_demand_feature_view.py index 78ddd851c70..c27b8365561 100644 --- a/sdk/python/tests/unit/test_on_demand_feature_view.py +++ b/sdk/python/tests/unit/test_on_demand_feature_view.py @@ -618,3 +618,33 @@ def test_aggregations_valid_without_udf(): ) # Must not raise odfv.ensure_valid() + + +def test_aggregations_only_odfv_proto_roundtrip(): + """Aggregation-only ODFV must survive a proto round-trip without crashing on dill.loads(b'').""" + from datetime import timedelta + + file_source = FileSource(name="my-file-source", path="test.parquet") + feature_view = FeatureView( + name="my-feature-view", + entities=[], + schema=[Field(name="purchase_count", dtype=Float32)], + source=file_source, + ) + odfv = OnDemandFeatureView( + name="agg-odfv", + sources=[feature_view], + schema=[Field(name="purchase_sum_30d", dtype=Float32)], + aggregations=[ + Aggregation( + column="purchase_count", + function="sum", + time_window=timedelta(days=30), + ) + ], + ) + proto = odfv.to_proto() + restored = OnDemandFeatureView.from_proto(proto) + assert restored.feature_transformation is None + assert len(restored.aggregations) == 1 + assert restored.aggregations[0].column == "purchase_count" From 9fcf772e32bd51f91de74108351db9e29e1277f2 Mon Sep 17 00:00:00 2001 From: Nick Quinn Date: Fri, 24 Apr 2026 14:13:41 -0700 Subject: [PATCH 4/6] fix: skip transformation inference for aggregation-only ODFVs infer_features() unconditionally asserted feature_transformation is not None, crashing during apply() for aggregation-only ODFVs. Add an early return when aggregations are present and feature_transformation is None; features are explicitly declared via schema so inference via transformation execution is not needed. Co-Authored-By: Claude Sonnet 4.6 Signed-off-by: Nick Quinn --- sdk/python/feast/on_demand_feature_view.py | 7 +++++ .../tests/unit/test_on_demand_feature_view.py | 27 +++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/sdk/python/feast/on_demand_feature_view.py b/sdk/python/feast/on_demand_feature_view.py index 0cb0d032c94..57c51fccd8a 100644 --- a/sdk/python/feast/on_demand_feature_view.py +++ b/sdk/python/feast/on_demand_feature_view.py @@ -1119,6 +1119,13 @@ def _preprocess_feature_dict( return preprocessed_dict, columns_to_cleanup def infer_features(self) -> None: + if self.aggregations and not self.feature_transformation: + if not self.features: + raise RegistryInferenceFailure( + "OnDemandFeatureView", + f"Could not infer Features for the feature view '{self.name}'.", + ) + return assert self.feature_transformation is not None random_input = self._construct_random_input(singleton=self.singleton) inferred_features = self.feature_transformation.infer_features( diff --git a/sdk/python/tests/unit/test_on_demand_feature_view.py b/sdk/python/tests/unit/test_on_demand_feature_view.py index c27b8365561..c33d119e8b0 100644 --- a/sdk/python/tests/unit/test_on_demand_feature_view.py +++ b/sdk/python/tests/unit/test_on_demand_feature_view.py @@ -648,3 +648,30 @@ def test_aggregations_only_odfv_proto_roundtrip(): assert restored.feature_transformation is None assert len(restored.aggregations) == 1 assert restored.aggregations[0].column == "purchase_count" + + +def test_aggregations_only_odfv_infer_features(): + """infer_features must not crash for aggregation-only ODFVs with explicit schema.""" + from datetime import timedelta + + file_source = FileSource(name="my-file-source", path="test.parquet") + feature_view = FeatureView( + name="my-feature-view", + entities=[], + schema=[Field(name="purchase_count", dtype=Float32)], + source=file_source, + ) + odfv = OnDemandFeatureView( + name="agg-odfv", + sources=[feature_view], + schema=[Field(name="purchase_sum_30d", dtype=Float32)], + aggregations=[ + Aggregation( + column="purchase_count", + function="sum", + time_window=timedelta(days=30), + ) + ], + ) + # Must not raise; features are taken from schema, no transformation execution needed + odfv.infer_features() From fe285e02cc85241e71f14bd3bd6702ec723f4bb8 Mon Sep 17 00:00:00 2001 From: Nick Quinn Date: Fri, 24 Apr 2026 14:16:24 -0700 Subject: [PATCH 5/6] test: add input_schema + aggregation + no-udf ODFV round-trip test Co-Authored-By: Claude Sonnet 4.6 Signed-off-by: Nick Quinn --- .../tests/unit/test_on_demand_feature_view.py | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/sdk/python/tests/unit/test_on_demand_feature_view.py b/sdk/python/tests/unit/test_on_demand_feature_view.py index c33d119e8b0..7afde5c8946 100644 --- a/sdk/python/tests/unit/test_on_demand_feature_view.py +++ b/sdk/python/tests/unit/test_on_demand_feature_view.py @@ -675,3 +675,31 @@ def test_aggregations_only_odfv_infer_features(): ) # Must not raise; features are taken from schema, no transformation execution needed odfv.infer_features() + + +def test_input_schema_aggregation_no_udf(): + """ODFV with input_schema, no sources, aggregations, and no udf must validate and round-trip.""" + from datetime import timedelta + + odfv = OnDemandFeatureView( + name="input-schema-agg-odfv", + sources=None, + input_schema=[Field(name="purchase_count", dtype=Float32)], + schema=[Field(name="purchase_sum_30d", dtype=Float32)], + aggregations=[ + Aggregation( + column="purchase_count", + function="sum", + time_window=timedelta(days=30), + ) + ], + ) + + odfv.ensure_valid() + odfv.infer_features() + + proto = odfv.to_proto() + restored = OnDemandFeatureView.from_proto(proto) + assert restored.feature_transformation is None + assert len(restored.aggregations) == 1 + assert restored.input_schema == [Field(name="purchase_count", dtype=Float32)] From c7838e6d6106148e58a3a1f1954321782f666472 Mon Sep 17 00:00:00 2001 From: Nick Quinn Date: Fri, 24 Apr 2026 16:54:29 -0700 Subject: [PATCH 6/6] fix: resolve mypy errors in field.py, entity.py, and remote.py - Redirect feast.types.Value_pb2 stub imports to feast.protos.feast.types.Value_pb2 where typed .pyi stubs live - Add # type: ignore[arg-type] where .value (int) is passed to a proto field typed as NewType("ValueType", int) - Add # type: ignore[arg-type] for getattr call with Optional[str] from WhichOneof in remote.py Co-Authored-By: Claude Sonnet 4.6 Signed-off-by: Nick Quinn --- sdk/python/feast/entity.py | 2 +- sdk/python/feast/field.py | 2 +- .../feast/infra/online_stores/remote.py | 2 +- .../protos/feast/core/DataSource_pb2.pyi | 10 +++---- .../feast/protos/feast/core/Entity_pb2.pyi | 6 ++-- .../feast/protos/feast/core/Feature_pb2.pyi | 6 ++-- .../protos/feast/serving/Connector_pb2.pyi | 6 ++-- .../protos/feast/serving/GrpcServer_pb2.pyi | 18 +++++------ .../feast/serving/ServingService_pb2.pyi | 30 +++++++++---------- .../feast/protos/feast/storage/Redis_pb2.pyi | 6 ++-- .../protos/feast/types/EntityKey_pb2.pyi | 6 ++-- .../feast/protos/feast/types/Field_pb2.pyi | 6 ++-- 12 files changed, 50 insertions(+), 50 deletions(-) diff --git a/sdk/python/feast/entity.py b/sdk/python/feast/entity.py index 7f4eadc6352..bcfa170a96d 100644 --- a/sdk/python/feast/entity.py +++ b/sdk/python/feast/entity.py @@ -203,7 +203,7 @@ def to_proto(self) -> EntityProto: spec = EntitySpecProto( name=self.name, - value_type=self.value_type.value, + value_type=self.value_type.value, # type: ignore[arg-type] join_key=self.join_key, description=self.description, tags=self.tags, diff --git a/sdk/python/feast/field.py b/sdk/python/feast/field.py index e155836467b..3055bd70830 100644 --- a/sdk/python/feast/field.py +++ b/sdk/python/feast/field.py @@ -136,7 +136,7 @@ def to_proto(self) -> FieldProto: tags[NESTED_COLLECTION_INNER_TYPE_TAG] = _feast_type_to_str(self.dtype) return FieldProto( name=self.name, - value_type=value_type.value, + value_type=value_type.value, # type: ignore[arg-type] description=self.description, tags=tags, vector_index=self.vector_index, diff --git a/sdk/python/feast/infra/online_stores/remote.py b/sdk/python/feast/infra/online_stores/remote.py index 9bead1fcb9d..ac3cc2b4b13 100644 --- a/sdk/python/feast/infra/online_stores/remote.py +++ b/sdk/python/feast/infra/online_stores/remote.py @@ -501,7 +501,7 @@ def _construct_online_read_api_json_request( for row in entity_keys: entity_key = row.join_keys[0] entity_values.append( - getattr(row.entity_values[0], row.entity_values[0].WhichOneof("val")) + getattr(row.entity_values[0], row.entity_values[0].WhichOneof("val")) # type: ignore[arg-type] ) return { diff --git a/sdk/python/feast/protos/feast/core/DataSource_pb2.pyi b/sdk/python/feast/protos/feast/core/DataSource_pb2.pyi index 7876e1adc98..e603c8551d0 100644 --- a/sdk/python/feast/protos/feast/core/DataSource_pb2.pyi +++ b/sdk/python/feast/protos/feast/core/DataSource_pb2.pyi @@ -20,7 +20,7 @@ import builtins import collections.abc import feast.core.DataFormat_pb2 import feast.core.Feature_pb2 -import feast.types.Value_pb2 +from feast.protos.feast.types import Value_pb2 as _feast_types_Value_pb2 import google.protobuf.descriptor import google.protobuf.duration_pb2 import google.protobuf.internal.containers @@ -424,26 +424,26 @@ class DataSource(google.protobuf.message.Message): KEY_FIELD_NUMBER: builtins.int VALUE_FIELD_NUMBER: builtins.int key: builtins.str - value: feast.types.Value_pb2.ValueType.Enum.ValueType + value: _feast_types_Value_pb2.ValueType.Enum.ValueType def __init__( self, *, key: builtins.str = ..., - value: feast.types.Value_pb2.ValueType.Enum.ValueType = ..., + value: _feast_types_Value_pb2.ValueType.Enum.ValueType = ..., ) -> None: ... def ClearField(self, field_name: typing_extensions.Literal["key", b"key", "value", b"value"]) -> None: ... DEPRECATED_SCHEMA_FIELD_NUMBER: builtins.int SCHEMA_FIELD_NUMBER: builtins.int @property - def deprecated_schema(self) -> google.protobuf.internal.containers.ScalarMap[builtins.str, feast.types.Value_pb2.ValueType.Enum.ValueType]: + def deprecated_schema(self) -> google.protobuf.internal.containers.ScalarMap[builtins.str, _feast_types_Value_pb2.ValueType.Enum.ValueType]: """Mapping of feature name to type""" @property def schema(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[feast.core.Feature_pb2.FeatureSpecV2]: ... def __init__( self, *, - deprecated_schema: collections.abc.Mapping[builtins.str, feast.types.Value_pb2.ValueType.Enum.ValueType] | None = ..., + deprecated_schema: collections.abc.Mapping[builtins.str, _feast_types_Value_pb2.ValueType.Enum.ValueType] | None = ..., schema: collections.abc.Iterable[feast.core.Feature_pb2.FeatureSpecV2] | None = ..., ) -> None: ... def ClearField(self, field_name: typing_extensions.Literal["deprecated_schema", b"deprecated_schema", "schema", b"schema"]) -> None: ... diff --git a/sdk/python/feast/protos/feast/core/Entity_pb2.pyi b/sdk/python/feast/protos/feast/core/Entity_pb2.pyi index 025817edfee..d2e1418a2aa 100644 --- a/sdk/python/feast/protos/feast/core/Entity_pb2.pyi +++ b/sdk/python/feast/protos/feast/core/Entity_pb2.pyi @@ -18,7 +18,7 @@ isort:skip_file """ import builtins import collections.abc -import feast.types.Value_pb2 +from feast.protos.feast.types import Value_pb2 as _feast_types_Value_pb2 import google.protobuf.descriptor import google.protobuf.internal.containers import google.protobuf.message @@ -83,7 +83,7 @@ class EntitySpecV2(google.protobuf.message.Message): """Name of the entity.""" project: builtins.str """Name of Feast project that this feature table belongs to.""" - value_type: feast.types.Value_pb2.ValueType.Enum.ValueType + value_type: _feast_types_Value_pb2.ValueType.Enum.ValueType """Type of the entity.""" description: builtins.str """Description of the entity.""" @@ -99,7 +99,7 @@ class EntitySpecV2(google.protobuf.message.Message): *, name: builtins.str = ..., project: builtins.str = ..., - value_type: feast.types.Value_pb2.ValueType.Enum.ValueType = ..., + value_type: _feast_types_Value_pb2.ValueType.Enum.ValueType = ..., description: builtins.str = ..., join_key: builtins.str = ..., tags: collections.abc.Mapping[builtins.str, builtins.str] | None = ..., diff --git a/sdk/python/feast/protos/feast/core/Feature_pb2.pyi b/sdk/python/feast/protos/feast/core/Feature_pb2.pyi index aa56630424f..f2e8d57c2e4 100644 --- a/sdk/python/feast/protos/feast/core/Feature_pb2.pyi +++ b/sdk/python/feast/protos/feast/core/Feature_pb2.pyi @@ -18,7 +18,7 @@ limitations under the License. """ import builtins import collections.abc -import feast.types.Value_pb2 +from feast.protos.feast.types import Value_pb2 as _feast_types_Value_pb2 import google.protobuf.descriptor import google.protobuf.internal.containers import google.protobuf.message @@ -58,7 +58,7 @@ class FeatureSpecV2(google.protobuf.message.Message): VECTOR_LENGTH_FIELD_NUMBER: builtins.int name: builtins.str """Name of the feature. Not updatable.""" - value_type: feast.types.Value_pb2.ValueType.Enum.ValueType + value_type: _feast_types_Value_pb2.ValueType.Enum.ValueType """Value type of the feature. Not updatable.""" @property def tags(self) -> google.protobuf.internal.containers.ScalarMap[builtins.str, builtins.str]: @@ -75,7 +75,7 @@ class FeatureSpecV2(google.protobuf.message.Message): self, *, name: builtins.str = ..., - value_type: feast.types.Value_pb2.ValueType.Enum.ValueType = ..., + value_type: _feast_types_Value_pb2.ValueType.Enum.ValueType = ..., tags: collections.abc.Mapping[builtins.str, builtins.str] | None = ..., description: builtins.str = ..., vector_index: builtins.bool = ..., diff --git a/sdk/python/feast/protos/feast/serving/Connector_pb2.pyi b/sdk/python/feast/protos/feast/serving/Connector_pb2.pyi index f87109e0fa5..2e4dcc7ab18 100644 --- a/sdk/python/feast/protos/feast/serving/Connector_pb2.pyi +++ b/sdk/python/feast/protos/feast/serving/Connector_pb2.pyi @@ -6,7 +6,7 @@ import builtins import collections.abc import feast.serving.ServingService_pb2 import feast.types.EntityKey_pb2 -import feast.types.Value_pb2 +from feast.protos.feast.types import Value_pb2 as _feast_types_Value_pb2 import google.protobuf.descriptor import google.protobuf.internal.containers import google.protobuf.message @@ -31,13 +31,13 @@ class ConnectorFeature(google.protobuf.message.Message): @property def timestamp(self) -> google.protobuf.timestamp_pb2.Timestamp: ... @property - def value(self) -> feast.types.Value_pb2.Value: ... + def value(self) -> _feast_types_Value_pb2.Value: ... def __init__( self, *, reference: feast.serving.ServingService_pb2.FeatureReferenceV2 | None = ..., timestamp: google.protobuf.timestamp_pb2.Timestamp | None = ..., - value: feast.types.Value_pb2.Value | None = ..., + value: _feast_types_Value_pb2.Value | None = ..., ) -> None: ... def HasField(self, field_name: typing_extensions.Literal["reference", b"reference", "timestamp", b"timestamp", "value", b"value"]) -> builtins.bool: ... def ClearField(self, field_name: typing_extensions.Literal["reference", b"reference", "timestamp", b"timestamp", "value", b"value"]) -> None: ... diff --git a/sdk/python/feast/protos/feast/serving/GrpcServer_pb2.pyi b/sdk/python/feast/protos/feast/serving/GrpcServer_pb2.pyi index a83cd87a16e..a028d96aeae 100644 --- a/sdk/python/feast/protos/feast/serving/GrpcServer_pb2.pyi +++ b/sdk/python/feast/protos/feast/serving/GrpcServer_pb2.pyi @@ -4,7 +4,7 @@ isort:skip_file """ import builtins import collections.abc -import feast.types.Value_pb2 +from feast.protos.feast.types import Value_pb2 as _feast_types_Value_pb2 import google.protobuf.descriptor import google.protobuf.internal.containers import google.protobuf.message @@ -42,12 +42,12 @@ class PushRequest(google.protobuf.message.Message): VALUE_FIELD_NUMBER: builtins.int key: builtins.str @property - def value(self) -> feast.types.Value_pb2.Value: ... + def value(self) -> _feast_types_Value_pb2.Value: ... def __init__( self, *, key: builtins.str = ..., - value: feast.types.Value_pb2.Value | None = ..., + value: _feast_types_Value_pb2.Value | None = ..., ) -> None: ... def HasField(self, field_name: typing_extensions.Literal["value", b"value"]) -> builtins.bool: ... def ClearField(self, field_name: typing_extensions.Literal["key", b"key", "value", b"value"]) -> None: ... @@ -63,7 +63,7 @@ class PushRequest(google.protobuf.message.Message): allow_registry_cache: builtins.bool to: builtins.str @property - def typed_features(self) -> google.protobuf.internal.containers.MessageMap[builtins.str, feast.types.Value_pb2.Value]: ... + def typed_features(self) -> google.protobuf.internal.containers.MessageMap[builtins.str, _feast_types_Value_pb2.Value]: ... def __init__( self, *, @@ -71,7 +71,7 @@ class PushRequest(google.protobuf.message.Message): stream_feature_view: builtins.str = ..., allow_registry_cache: builtins.bool = ..., to: builtins.str = ..., - typed_features: collections.abc.Mapping[builtins.str, feast.types.Value_pb2.Value] | None = ..., + typed_features: collections.abc.Mapping[builtins.str, _feast_types_Value_pb2.Value] | None = ..., ) -> None: ... def ClearField(self, field_name: typing_extensions.Literal["allow_registry_cache", b"allow_registry_cache", "features", b"features", "stream_feature_view", b"stream_feature_view", "to", b"to", "typed_features", b"typed_features"]) -> None: ... @@ -116,12 +116,12 @@ class WriteToOnlineStoreRequest(google.protobuf.message.Message): VALUE_FIELD_NUMBER: builtins.int key: builtins.str @property - def value(self) -> feast.types.Value_pb2.Value: ... + def value(self) -> _feast_types_Value_pb2.Value: ... def __init__( self, *, key: builtins.str = ..., - value: feast.types.Value_pb2.Value | None = ..., + value: _feast_types_Value_pb2.Value | None = ..., ) -> None: ... def HasField(self, field_name: typing_extensions.Literal["value", b"value"]) -> builtins.bool: ... def ClearField(self, field_name: typing_extensions.Literal["key", b"key", "value", b"value"]) -> None: ... @@ -135,14 +135,14 @@ class WriteToOnlineStoreRequest(google.protobuf.message.Message): feature_view_name: builtins.str allow_registry_cache: builtins.bool @property - def typed_features(self) -> google.protobuf.internal.containers.MessageMap[builtins.str, feast.types.Value_pb2.Value]: ... + def typed_features(self) -> google.protobuf.internal.containers.MessageMap[builtins.str, _feast_types_Value_pb2.Value]: ... def __init__( self, *, features: collections.abc.Mapping[builtins.str, builtins.str] | None = ..., feature_view_name: builtins.str = ..., allow_registry_cache: builtins.bool = ..., - typed_features: collections.abc.Mapping[builtins.str, feast.types.Value_pb2.Value] | None = ..., + typed_features: collections.abc.Mapping[builtins.str, _feast_types_Value_pb2.Value] | None = ..., ) -> None: ... def ClearField(self, field_name: typing_extensions.Literal["allow_registry_cache", b"allow_registry_cache", "feature_view_name", b"feature_view_name", "features", b"features", "typed_features", b"typed_features"]) -> None: ... diff --git a/sdk/python/feast/protos/feast/serving/ServingService_pb2.pyi b/sdk/python/feast/protos/feast/serving/ServingService_pb2.pyi index 1804ce0428e..bc65222ee3a 100644 --- a/sdk/python/feast/protos/feast/serving/ServingService_pb2.pyi +++ b/sdk/python/feast/protos/feast/serving/ServingService_pb2.pyi @@ -18,7 +18,7 @@ limitations under the License. """ import builtins import collections.abc -import feast.types.Value_pb2 +from feast.protos.feast.types import Value_pb2 as _feast_types_Value_pb2 import google.protobuf.descriptor import google.protobuf.internal.containers import google.protobuf.internal.enum_type_wrapper @@ -137,12 +137,12 @@ class GetOnlineFeaturesRequestV2(google.protobuf.message.Message): VALUE_FIELD_NUMBER: builtins.int key: builtins.str @property - def value(self) -> feast.types.Value_pb2.Value: ... + def value(self) -> _feast_types_Value_pb2.Value: ... def __init__( self, *, key: builtins.str = ..., - value: feast.types.Value_pb2.Value | None = ..., + value: _feast_types_Value_pb2.Value | None = ..., ) -> None: ... def HasField(self, field_name: typing_extensions.Literal["value", b"value"]) -> builtins.bool: ... def ClearField(self, field_name: typing_extensions.Literal["key", b"key", "value", b"value"]) -> None: ... @@ -155,13 +155,13 @@ class GetOnlineFeaturesRequestV2(google.protobuf.message.Message): together with maxAge, to determine feature staleness. """ @property - def fields(self) -> google.protobuf.internal.containers.MessageMap[builtins.str, feast.types.Value_pb2.Value]: + def fields(self) -> google.protobuf.internal.containers.MessageMap[builtins.str, _feast_types_Value_pb2.Value]: """Map containing mapping of entity name to entity value.""" def __init__( self, *, timestamp: google.protobuf.timestamp_pb2.Timestamp | None = ..., - fields: collections.abc.Mapping[builtins.str, feast.types.Value_pb2.Value] | None = ..., + fields: collections.abc.Mapping[builtins.str, _feast_types_Value_pb2.Value] | None = ..., ) -> None: ... def HasField(self, field_name: typing_extensions.Literal["timestamp", b"timestamp"]) -> builtins.bool: ... def ClearField(self, field_name: typing_extensions.Literal["fields", b"fields", "timestamp", b"timestamp"]) -> None: ... @@ -221,12 +221,12 @@ class GetOnlineFeaturesRequest(google.protobuf.message.Message): VALUE_FIELD_NUMBER: builtins.int key: builtins.str @property - def value(self) -> feast.types.Value_pb2.RepeatedValue: ... + def value(self) -> _feast_types_Value_pb2.RepeatedValue: ... def __init__( self, *, key: builtins.str = ..., - value: feast.types.Value_pb2.RepeatedValue | None = ..., + value: _feast_types_Value_pb2.RepeatedValue | None = ..., ) -> None: ... def HasField(self, field_name: typing_extensions.Literal["value", b"value"]) -> builtins.bool: ... def ClearField(self, field_name: typing_extensions.Literal["key", b"key", "value", b"value"]) -> None: ... @@ -238,12 +238,12 @@ class GetOnlineFeaturesRequest(google.protobuf.message.Message): VALUE_FIELD_NUMBER: builtins.int key: builtins.str @property - def value(self) -> feast.types.Value_pb2.RepeatedValue: ... + def value(self) -> _feast_types_Value_pb2.RepeatedValue: ... def __init__( self, *, key: builtins.str = ..., - value: feast.types.Value_pb2.RepeatedValue | None = ..., + value: _feast_types_Value_pb2.RepeatedValue | None = ..., ) -> None: ... def HasField(self, field_name: typing_extensions.Literal["value", b"value"]) -> builtins.bool: ... def ClearField(self, field_name: typing_extensions.Literal["key", b"key", "value", b"value"]) -> None: ... @@ -258,13 +258,13 @@ class GetOnlineFeaturesRequest(google.protobuf.message.Message): @property def features(self) -> global___FeatureList: ... @property - def entities(self) -> google.protobuf.internal.containers.MessageMap[builtins.str, feast.types.Value_pb2.RepeatedValue]: + def entities(self) -> google.protobuf.internal.containers.MessageMap[builtins.str, _feast_types_Value_pb2.RepeatedValue]: """The entity data is specified in a columnar format A map of entity name -> list of values """ full_feature_names: builtins.bool @property - def request_context(self) -> google.protobuf.internal.containers.MessageMap[builtins.str, feast.types.Value_pb2.RepeatedValue]: + def request_context(self) -> google.protobuf.internal.containers.MessageMap[builtins.str, _feast_types_Value_pb2.RepeatedValue]: """Context for OnDemand Feature Transformation (was moved to dedicated parameter to avoid unnecessary separation logic on serving side) A map of variable name -> list of values @@ -276,9 +276,9 @@ class GetOnlineFeaturesRequest(google.protobuf.message.Message): *, feature_service: builtins.str = ..., features: global___FeatureList | None = ..., - entities: collections.abc.Mapping[builtins.str, feast.types.Value_pb2.RepeatedValue] | None = ..., + entities: collections.abc.Mapping[builtins.str, _feast_types_Value_pb2.RepeatedValue] | None = ..., full_feature_names: builtins.bool = ..., - request_context: collections.abc.Mapping[builtins.str, feast.types.Value_pb2.RepeatedValue] | None = ..., + request_context: collections.abc.Mapping[builtins.str, _feast_types_Value_pb2.RepeatedValue] | None = ..., include_feature_view_version_metadata: builtins.bool = ..., ) -> None: ... def HasField(self, field_name: typing_extensions.Literal["feature_service", b"feature_service", "features", b"features", "kind", b"kind"]) -> builtins.bool: ... @@ -297,7 +297,7 @@ class GetOnlineFeaturesResponse(google.protobuf.message.Message): STATUSES_FIELD_NUMBER: builtins.int EVENT_TIMESTAMPS_FIELD_NUMBER: builtins.int @property - def values(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[feast.types.Value_pb2.Value]: ... + def values(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[_feast_types_Value_pb2.Value]: ... @property def statuses(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[global___FieldStatus.ValueType]: ... @property @@ -305,7 +305,7 @@ class GetOnlineFeaturesResponse(google.protobuf.message.Message): def __init__( self, *, - values: collections.abc.Iterable[feast.types.Value_pb2.Value] | None = ..., + values: collections.abc.Iterable[_feast_types_Value_pb2.Value] | None = ..., statuses: collections.abc.Iterable[global___FieldStatus.ValueType] | None = ..., event_timestamps: collections.abc.Iterable[google.protobuf.timestamp_pb2.Timestamp] | None = ..., ) -> None: ... diff --git a/sdk/python/feast/protos/feast/storage/Redis_pb2.pyi b/sdk/python/feast/protos/feast/storage/Redis_pb2.pyi index 74cc2b07f0a..faa8d358817 100644 --- a/sdk/python/feast/protos/feast/storage/Redis_pb2.pyi +++ b/sdk/python/feast/protos/feast/storage/Redis_pb2.pyi @@ -18,7 +18,7 @@ limitations under the License. """ import builtins import collections.abc -import feast.types.Value_pb2 +from feast.protos.feast.types import Value_pb2 as _feast_types_Value_pb2 import google.protobuf.descriptor import google.protobuf.internal.containers import google.protobuf.message @@ -41,13 +41,13 @@ class RedisKeyV2(google.protobuf.message.Message): @property def entity_names(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]: ... @property - def entity_values(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[feast.types.Value_pb2.Value]: ... + def entity_values(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[_feast_types_Value_pb2.Value]: ... def __init__( self, *, project: builtins.str = ..., entity_names: collections.abc.Iterable[builtins.str] | None = ..., - entity_values: collections.abc.Iterable[feast.types.Value_pb2.Value] | None = ..., + entity_values: collections.abc.Iterable[_feast_types_Value_pb2.Value] | None = ..., ) -> None: ... def ClearField(self, field_name: typing_extensions.Literal["entity_names", b"entity_names", "entity_values", b"entity_values", "project", b"project"]) -> None: ... diff --git a/sdk/python/feast/protos/feast/types/EntityKey_pb2.pyi b/sdk/python/feast/protos/feast/types/EntityKey_pb2.pyi index fe65e0c1b32..d2b831ce452 100644 --- a/sdk/python/feast/protos/feast/types/EntityKey_pb2.pyi +++ b/sdk/python/feast/protos/feast/types/EntityKey_pb2.pyi @@ -18,7 +18,7 @@ limitations under the License. """ import builtins import collections.abc -import feast.types.Value_pb2 +from feast.protos.feast.types import Value_pb2 as _feast_types_Value_pb2 import google.protobuf.descriptor import google.protobuf.internal.containers import google.protobuf.message @@ -39,12 +39,12 @@ class EntityKey(google.protobuf.message.Message): @property def join_keys(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]: ... @property - def entity_values(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[feast.types.Value_pb2.Value]: ... + def entity_values(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[_feast_types_Value_pb2.Value]: ... def __init__( self, *, join_keys: collections.abc.Iterable[builtins.str] | None = ..., - entity_values: collections.abc.Iterable[feast.types.Value_pb2.Value] | None = ..., + entity_values: collections.abc.Iterable[_feast_types_Value_pb2.Value] | None = ..., ) -> None: ... def ClearField(self, field_name: typing_extensions.Literal["entity_values", b"entity_values", "join_keys", b"join_keys"]) -> None: ... diff --git a/sdk/python/feast/protos/feast/types/Field_pb2.pyi b/sdk/python/feast/protos/feast/types/Field_pb2.pyi index 28a21942378..cbe83bf1847 100644 --- a/sdk/python/feast/protos/feast/types/Field_pb2.pyi +++ b/sdk/python/feast/protos/feast/types/Field_pb2.pyi @@ -18,7 +18,7 @@ limitations under the License. """ import builtins import collections.abc -import feast.types.Value_pb2 +from feast.protos.feast.types import Value_pb2 as _feast_types_Value_pb2 import google.protobuf.descriptor import google.protobuf.internal.containers import google.protobuf.message @@ -54,7 +54,7 @@ class Field(google.protobuf.message.Message): TAGS_FIELD_NUMBER: builtins.int DESCRIPTION_FIELD_NUMBER: builtins.int name: builtins.str - value: feast.types.Value_pb2.ValueType.Enum.ValueType + value: _feast_types_Value_pb2.ValueType.Enum.ValueType @property def tags(self) -> google.protobuf.internal.containers.ScalarMap[builtins.str, builtins.str]: """Tags for user defined metadata on a field""" @@ -64,7 +64,7 @@ class Field(google.protobuf.message.Message): self, *, name: builtins.str = ..., - value: feast.types.Value_pb2.ValueType.Enum.ValueType = ..., + value: _feast_types_Value_pb2.ValueType.Enum.ValueType = ..., tags: collections.abc.Mapping[builtins.str, builtins.str] | None = ..., description: builtins.str = ..., ) -> None: ...