feat: Add enabled/disabled toggle for feature views#6401
Conversation
f74306c to
4685564
Compare
| if hasattr(existing_proto.meta, "state") and hasattr(updated_fv, "state"): | ||
| state_val = getattr(updated_fv, "state") | ||
| if isinstance(state_val, FeatureViewState): | ||
| existing_proto.meta.state = state_val.to_proto() |
There was a problem hiding this comment.
Every feast apply resets all feature views back to CREATED, even if they were already AVAILABLE_ONLINE
There was a problem hiding this comment.
both feast apply paths now preserve the existing state from the registry instead of overwriting it with the default STATE_UNSPECIFIED. Works across all registry backends.
| print(f"Feature view '{name}' is already in state {new_state.name}.") | ||
| return | ||
|
|
||
| fv.state = new_state |
There was a problem hiding this comment.
I think this needs validation, It's better to add Valid transitions maps so that user is not able to bypass or skip some state
There was a problem hiding this comment.
Added _VALID_STATE_TRANSITIONS map and can_transition_to() validation in the set-state command. Invalid transitions are now rejected with a message showing allowed transitions.
| (start_date, end_date) | ||
| ) | ||
| existing_feature_view.last_updated_timestamp = _utc_now() | ||
| # Transition state to AVAILABLE_ONLINE after materialization. |
There was a problem hiding this comment.
We are trying to set AVAILABLE_ONLINE state at multiple places, either we should set this state in feature_store.py or registry.py. Since _materialize_single_feature_view sets state to AVAILABLE_ONLINE and then calls registry.apply_materialization which also sets it to AVAILABLE_ONLINE, this is redundant.
There was a problem hiding this comment.
Removed the duplicate from feature_store.py.
| end_date = utils.make_tzaware(end_date) or _utc_now() | ||
|
|
||
| # Transition state to MATERIALIZING before starting. | ||
| previous_state = getattr(feature_view, "state", None) |
There was a problem hiding this comment.
Similar to cli, can_transition_to() check can be enforced here as well
There was a problem hiding this comment.
Added can_transition_to() check in both materialization paths, guarded with state != STATE_UNSPECIFIED for backward compatibility.
| fv = store.registry.get_any_feature_view(name, store.project) | ||
| except FeastObjectNotFoundException as e: | ||
| print(e) | ||
| exit(1) |
There was a problem hiding this comment.
Use sys.exit(1) or ctx.exit(1) instead
Signed-off-by: RutujaPathade <73137503+RutujaPathade@users.noreply.github.com>
Signed-off-by: ntkathole <nikhilkathole2683@gmail.com> Signed-off-by: RutujaPathade <73137503+RutujaPathade@users.noreply.github.com>
Signed-off-by: RutujaPathade <73137503+RutujaPathade@users.noreply.github.com>
Signed-off-by: RutujaPathade <73137503+RutujaPathade@users.noreply.github.com>
…+ join nodes (feast-dev#6395) * fix: Apply field mapping to join keys in local compute engine nodes When a batch source defines a `field_mapping` that renames an entity join key (e.g. `USERID` -> `user_id`), the source-read node renames the columns on the pulled Arrow table to their mapped names. Downstream `LocalDedupNode` and `LocalJoinNode` then look up the *pre-mapping* names from `column_info.join_keys`, which raises `KeyError: Index(['USERID'])` during materialization (or returns an empty join). Add a `join_keys_columns` property on `ColumnInfo` that mirrors the existing `timestamp_column` / `created_timestamp_column` properties — returning join keys translated through `field_mapping` — and use it from the dedup and join nodes. Fixes feast-dev#5942. Signed-off-by: 1fanwang <1fannnw@gmail.com> * test: also cover LocalJoinNode field_mapping case Signed-off-by: 1fanwang <1fannnw@gmail.com> --------- Signed-off-by: 1fanwang <1fannnw@gmail.com> Signed-off-by: RutujaPathade <73137503+RutujaPathade@users.noreply.github.com>
…east-dev#6354) Signed-off-by: ntkathole <nikhilkathole2683@gmail.com> Signed-off-by: RutujaPathade <73137503+RutujaPathade@users.noreply.github.com>
…e examples Signed-off-by: jvincent-mongodb <jeffrey.vincent@mongodb.com> Signed-off-by: RutujaPathade <73137503+RutujaPathade@users.noreply.github.com>
The requested_features parameter was accepted by online_read and online_read_async but never used -- DynamoDB always fetched all features stored in the values map regardless. Add a ProjectionExpression to BatchGetItem requests when requested_features is provided, reducing data transfer, latency, and read costs. Fixes feast-dev#6058 Signed-off-by: Jonathan Wrede <wrede.jonathan00@gmail.com> Signed-off-by: RutujaPathade <73137503+RutujaPathade@users.noreply.github.com>
The return dict contains both str and Dict[str, str] values, so the return type must be Dict[str, Any] not Dict[str, str]. Signed-off-by: Jonathan Wrede <wrede.jonathan00@gmail.com> Signed-off-by: RutujaPathade <73137503+RutujaPathade@users.noreply.github.com>
c050656 to
86e81b8
Compare
…te_batch When pushing features with array/list types (e.g. STRING_LIST) to BigQuery via offline_write_batch, the data arrives as empty arrays because BigQuery's parquet loader does not infer list structure by default. Set parquet_options.enable_list_inference = True on the LoadJobConfig so array columns are written correctly. Fixes feast-dev#5845 Signed-off-by: Jonathan Wrede <wrede.jonathan00@gmail.com> Signed-off-by: RutujaPathade <73137503+RutujaPathade@users.noreply.github.com>
…ev#6381) * fix(trino): Clean up temporary entity tables after retrieval TrinoOfflineStore.get_historical_features() creates a temporary table for the entity DataFrame but never drops it, leaking tables indefinitely. Apply the same context manager pattern used by BigQuery, Redshift, and Athena offline stores: wrap the query in a generator that issues DROP TABLE IF EXISTS in a finally block. Fixes feast-dev#6306 Signed-off-by: Jonathan Wrede <wrede.jonathan00@gmail.com> * fix: sort imports for ruff compliance Signed-off-by: Jonathan Wrede <wrede.jonathan00@gmail.com> * fix: decouple temp table cleanup from query access Avoid dropping the temporary entity table on to_sql() calls. Previously, every method used a context manager that dropped the table on exit, so calling to_sql() before to_df() would destroy the table and cause subsequent queries to fail. Now the query is stored as a plain string and cleanup is handled by a dedicated _drop_temp_table() method called only after query execution (to_df, to_trino). A __del__ fallback ensures cleanup if execution methods are never called. The _cleaned_up flag makes the drop idempotent. Signed-off-by: Jonathan Wrede <wrede.jonathan00@gmail.com> --------- Signed-off-by: Jonathan Wrede <wrede.jonathan00@gmail.com> Signed-off-by: RutujaPathade <73137503+RutujaPathade@users.noreply.github.com>
…6362) * feat(bigquery): Support DATE-type event timestamp columns When the event_timestamp column in BigQuery is a DATE type, the generated SQL wraps comparison values in TIMESTAMP(), causing a type mismatch error. This adds a timestamp_field_type parameter to BigQuerySource that, when set to "DATE", generates DATE() comparisons instead. Closes feast-dev#2530 (part 2) Signed-off-by: Jonathan Wrede <wrede.jonathan00@gmail.com> * fix(bigquery): Use protobuf 4.25.x compatible generated code The proto files were regenerated with protobuf 6.31.1 / grpcio-tools 1.80.0, which imports runtime_version -- a module that does not exist in protobuf 4.25.x used by the project. Revert generated code to 4.25.1 format while keeping the new timestamp_field_type field. Signed-off-by: Jonathan Wrede <wrede.jonathan00@gmail.com> * fix(bigquery): Add Literal type annotation for cast_style Mypy infers str from the ternary expression; annotate with the exact Literal union so the call to get_timestamp_filter_sql passes type checking. Signed-off-by: Jonathan Wrede <wrede.jonathan00@gmail.com> * fix: Make timestamp_field_type default to None in FeatureViewQueryContext Callers that do not use DATE-typed timestamp fields (e.g. Spark offline store tests) should not be forced to pass timestamp_field_type. Adding a default keeps the new field backward-compatible. Signed-off-by: Jonathan Wrede <wrede.jonathan00@gmail.com> * fix: Keep timestamp_field_type required in FeatureViewQueryContext A default value on timestamp_field_type breaks the SparkFeatureViewQueryContext subclass because its non-default fields (min_date_partition, max_date_partition) would follow a field with a default. Instead, keep it required and update the Spark test to pass it. Signed-off-by: Jonathan Wrede <wrede.jonathan00@gmail.com> * fix: regenerate protos matching upstream mypy-protobuf style Reset all non-DataSource generated files to match master. Only DataSource_pb2.py and DataSource_pb2.pyi contain our timestamp_field_type additions (field 28). The .pyi stub is hand-edited to match the existing import style used on master. Signed-off-by: Jonathan Wrede <wrede.jonathan00@gmail.com> --------- Signed-off-by: Jonathan Wrede <wrede.jonathan00@gmail.com> Signed-off-by: RutujaPathade <73137503+RutujaPathade@users.noreply.github.com>
Signed-off-by: ntkathole <nikhilkathole2683@gmail.com> Signed-off-by: RutujaPathade <73137503+RutujaPathade@users.noreply.github.com>
Mount the existing REST registry routers under /registry on the feature server so that fastapi_mcp automatically exposes registry introspection (list/get for entities, feature views, data sources, feature services, permissions, projects, saved datasets, lineage, search) as MCP tools. The RegistryServer is created in-process from store.registry — no external registry server is required. Auth is enforced via inject_user_details on every mounted router. Made-with: Cursor Signed-off-by: Chaitany patel <patelchaitany93@gmail.com> Made-with: Cursor Signed-off-by: RutujaPathade <73137503+RutujaPathade@users.noreply.github.com>
…elds Signed-off-by: RutujaPathade <73137503+RutujaPathade@users.noreply.github.com>
…chine to be opt-in Signed-off-by: RutujaPathade <73137503+RutujaPathade@users.noreply.github.com>
…egistry Signed-off-by: RutujaPathade <73137503+RutujaPathade@users.noreply.github.com>
Signed-off-by: RutujaPathade <73137503+RutujaPathade@users.noreply.github.com>
Signed-off-by: RutujaPathade <73137503+RutujaPathade@users.noreply.github.com>
Signed-off-by: RutujaPathade <73137503+RutujaPathade@users.noreply.github.com>
Co-authored-by: Nikhil Kathole <nikhilkathole2683@gmail.com> Signed-off-by: RutujaPathade <73137503+RutujaPathade@users.noreply.github.com>
Signed-off-by: RutujaPathade <73137503+RutujaPathade@users.noreply.github.com>
Signed-off-by: RutujaPathade <73137503+RutujaPathade@users.noreply.github.com>
Signed-off-by: RutujaPathade <73137503+RutujaPathade@users.noreply.github.com>
86e81b8 to
a4c85dc
Compare
…nabled-disabled-v2 Signed-off-by: RutujaPathade <73137503+RutujaPathade@users.noreply.github.com>
|
@rpathade Code looks good, but I see couple of gaps in overall feature:
Let me know if you would like to handle it all or some of them in same PR or different one. |
Thanks for the review! I think it makes sense to handle these incrementally: This PR:
Follow-up PRs:
If this plan works for you, happy to create the follow-up issues and resolve them. |
|
@rpathade Sounds good! |
Signed-off-by: RutujaPathade <73137503+RutujaPathade@users.noreply.github.com>
Signed-off-by: RutujaPathade <73137503+RutujaPathade@users.noreply.github.com>
… to follow-up PR) Signed-off-by: RutujaPathade <73137503+RutujaPathade@users.noreply.github.com>
|
@rpathade please resolve the conflicts, and rebase, then will get it merged |
…nabled-disabled-v2 Signed-off-by: RutujaPathade <73137503+RutujaPathade@users.noreply.github.com> # Conflicts: # sdk/python/feast/feature_view.py # sdk/python/feast/on_demand_feature_view.py # sdk/python/feast/stream_feature_view.py
# [0.64.0](v0.63.0...v0.64.0) (2026-06-13) ### Bug Fixes * Add async_supported property to RedisOnlineStore ([9b088fe](9b088fe)) * Add missing feast init templates to operator CRD and enhance persistence documentation ([1941d4d](1941d4d)) * Allow to publish from reference branch ([5458ec8](5458ec8)) * API calls list ([4203eb7](4203eb7)) * **bigquery:** Enable list inference for parquet loads in offline_write_batch ([9243497](9243497)), closes [#5845](#5845) * Bump grpcio dependencies ([07b4782](07b4782)) * **compute-engine/local:** Honor field_mapping on join keys in dedup + join nodes ([#6395](#6395)) ([bd01824](bd01824)) * **dynamodb:** Avoid tag race condition by using diff-based tag updates ([#6479](#6479)) ([bad2b7d](bad2b7d)), closes [#6418](#6418) * **dynamodb:** Fix mypy type for _build_projection_expression return ([217b4da](217b4da)) * Fix intermittent async test failures for DynamoDB and Redis ([63c5eb1](63c5eb1)) * Fix mongodb blog title ([57d28d4](57d28d4)) * Fix shared SQL registry crash - avoid unnecessary UDF deserialization in proto cache building ([ac588d7](ac588d7)) * Fix SparkRetrievalJob.persist() failing for SparkSource ([209d7cd](209d7cd)) * Fixed formatting and image for mongo blog ([#6377](#6377)) ([f8389fb](f8389fb)) * Fixes for ray source ([7f592a4](7f592a4)) * **go:** skip registry refresh when cache_ttl_seconds <= 0 ([97ed40c](97ed40c)) * Handle array of strings columns in Athena materialization ([#6324](#6324)) ([4ed0278](4ed0278)) * make milvus VARCHAR max_length configurable, remove hardcoded 512 limit ([3b98c22](3b98c22)) * **operator:** Set appProtocol: grpc on registry gRPC Service ([#6367](#6367)) ([c9ae2b4](c9ae2b4)) * PyJWT 2.10+ added validation that rejects empty HMAC keys ([e756ffe](e756ffe)) * RemoteOnlineStore sends all features in a single HTTP request ([8f187dd](8f187dd)) * Remove registry proto dump to enforce RBAC and add permission checks to Commit/Refresh RPCs ([328431f](328431f)) * Remove selector migration job - no longer needed ([51c325e](51c325e)) * replace broken .claude skill symlink with correct relative path ([4541690](4541690)) * Replace selector label strip patch with migration Job for upgrade-safe selector uniqueness ([00dea50](00dea50)) * Scope feature view name conflict check to current project in file-based registry ([#6369](#6369)) ([a4fde83](a4fde83)), closes [#6209](#6209) * **snowflake:** Stop double-quoting connection identifiers ([#6462](#6462)) ([e914d59](e914d59)) * **spark:** S3/GCS PyArrow filesystem resolution for staging paths ([#6442](#6442)) ([ae50414](ae50414)) * **trino:** Clean up temporary entity tables after retrieval ([#6381](#6381)) ([d86b13d](d86b13d)), closes [#6306](#6306) * Update go-feature-server base image to Go 1.25 and fix operator Dockerfile COPY permissions ([86ef0bc](86ef0bc)) ### Features * [Backend] Data Quality Monitoring with native compute, multi-backend support, REST API, CLI ([#6202](#6202)) ([5458c37](5458c37)) * Add apache flink compute engine ([#6476](#6476)) ([9636d6a](9636d6a)) * Add demo noteboooks for users ([e362173](e362173)) * Add enabled/disabled toggle for feature views ([#6401](#6401)) ([5f1fa0d](5f1fa0d)), closes [#6395](#6395) * Add Label View to init template ([ec272d5](ec272d5)) * Add mTLS support to remote registry gRPC client ([#6474](#6474)) ([c9602d8](c9602d8)) * Add Prometheus gauges for FeatureStore installation telemetry ([#6354](#6354)) ([1b681b7](1b681b7)) * Adds registry REST API endpoints for managing entities, data sources, and feature views ([#6413](#6413)) ([f77bd1d](f77bd1d)) * Allow CRUD on entities, data sources, and feature views from UI ([#6412](#6412)) ([2321c07](2321c07)) * Allow default openlineage configuration ([#6467](#6467)) ([276b6df](276b6df)) * **bigquery:** Support DATE-type event timestamp columns ([#6362](#6362)) ([753dee5](753dee5)), closes [#2530](#2530) * **cli:** Add `feast projects delete` command (closes [#5095](#5095)) ([#6318](#6318)) ([1a4b96c](1a4b96c)) * Data Quality Monitoring added in feast UI ([#6422](#6422)) ([fa271be](fa271be)) * **dynamodb:** Use ProjectionExpression when requested_features is set ([0adc906](0adc906)), closes [#6058](#6058) * Enhance DataSource and FeatureView modals with error handling and submission states ([96d7169](96d7169)) * Expose registry endpoints on feature server for MCP access ([f77981c](f77981c)) * Feast First-Class LabelView Implementation ([#6292](#6292)) ([c0e7e5d](c0e7e5d)) * Feast-MLflow Integration ([#6235](#6235)) ([7279c75](7279c75)) * Operational metrics for offline store and SOX metrics for both ([#6340](#6340)) ([65b1b80](65b1b80)) * Pre-compute feature service ([8011550](8011550)) * REST API-backed UI for RBAC compatibility and per-page lazy loading ([#6414](#6414)) ([6ae80af](6ae80af)) * Support non-string map key types ([#6382](#6382)) ([#6383](#6383)) ([728aa2e](728aa2e)) * Update FeatureStore CRD with DRA Fields ([01241e4](01241e4)) ### Performance Improvements * Cache feature view resolution in get_online_features to reduce per-request overhead ([55c2f18](55c2f18)) * Optimize feature serving latency with batched async Redis, cached checks fix ([103809a](103809a)) * Replace MessageToDict with optimized custom dict builder ([#6015](#6015)) ([9902064](9902064))
What this PR does / why we need it
Adds a lifecycle state machine and enabled/disabled toggle for feature views:
CREATED → GENERATED → MATERIALIZING → AVAILABLE_ONLINEtracks feature views from registration through materializationENABLED / DISABLEDtoggle controls serving and materializationstate == AVAILABLE_ONLINE AND enabled == TrueWhich issue(s) this PR fixes
Closes #6331
Checks
git commit -s)Testing Strategy