Visitar URL original
feat: Add registry list feature views by updated since (#6092) by nquinn408 · Pull Request #6093 · feast-dev/feast · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
Devin feedback
Signed-off-by: Nick Quinn <nicholas_quinn@apple.com>
  • Loading branch information
nickquinn408 committed Jun 28, 2026
commit d683c2916fae0a69ae8dc8cfcd11324b890cafa6
4 changes: 2 additions & 2 deletions sdk/python/feast/infra/registry/caching_registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import threading
import warnings
from abc import abstractmethod
from datetime import datetime, timedelta
from datetime import datetime, timedelta, timezone
from threading import Lock
from typing import Any, Dict, List, Optional

Expand Down Expand Up @@ -146,7 +146,7 @@ def list_all_feature_views(
if updated_since is not None:
# last_updated_timestamp from proto is offset-naive UTC; normalise for comparison
cutoff = (
updated_since.replace(tzinfo=None)
updated_since.astimezone(timezone.utc).replace(tzinfo=None)
if updated_since.tzinfo
else updated_since
)
Expand Down
2 changes: 1 addition & 1 deletion sdk/python/feast/infra/registry/registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -1094,7 +1094,7 @@ def list_all_feature_views(
if updated_since is not None:
# last_updated_timestamp from proto is offset-naive UTC; normalise for comparison
cutoff = (
updated_since.replace(tzinfo=None)
updated_since.astimezone(timezone.utc).replace(tzinfo=None)
if updated_since.tzinfo
else updated_since
)
Expand Down
4 changes: 2 additions & 2 deletions sdk/python/feast/infra/registry/snowflake.py
Original file line number Diff line number Diff line change
Expand Up @@ -665,7 +665,7 @@ def list_all_feature_views(
)
if updated_since is not None:
cutoff = (
updated_since.replace(tzinfo=None)
updated_since.astimezone(timezone.utc).replace(tzinfo=None)
if updated_since.tzinfo
else updated_since
)
Expand Down Expand Up @@ -702,7 +702,7 @@ def list_all_feature_views(

if updated_since is not None:
cutoff = (
updated_since.replace(tzinfo=None)
updated_since.astimezone(timezone.utc).replace(tzinfo=None)
if updated_since.tzinfo
else updated_since
)
Expand Down
4 changes: 3 additions & 1 deletion sdk/python/feast/registry_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -541,7 +541,9 @@ def ListAllFeatureViews(

updated_since = None
if request.HasField("updated_since"):
updated_since = request.updated_since.ToDatetime(tzinfo=timezone.utc)
updated_since = request.updated_since.ToDatetime().replace(
tzinfo=timezone.utc
)

all_feature_views = cast(
list[FeastObject],
Expand Down
27 changes: 27 additions & 0 deletions sdk/python/tests/unit/infra/registry/test_snowflake_registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -426,3 +426,30 @@ def test_list_all_feature_views_updated_since_future_returns_empty(
"project", allow_cache=False, updated_since=future
)
assert result == []


def test_list_all_feature_views_updated_since_non_utc_tz(mock_snowflake_registry):
"""A non-UTC tz-aware cutoff is converted to UTC before comparing against naive-UTC timestamps."""
est = timezone(timedelta(hours=-5))
# 2023-01-01 00:00 EST == 2023-01-01 05:00 UTC
cutoff_est = datetime(2023, 1, 1, 0, 0, 0, tzinfo=est)

# Feature view updated at 2023-01-01 03:00 UTC — after midnight EST but before 05:00 UTC
ts_between = datetime(2023, 1, 1, 3, 0, 0, tzinfo=timezone.utc)
# Feature view updated at 2023-01-01 06:00 UTC — after both midnight EST and 05:00 UTC
ts_after = datetime(2023, 1, 1, 6, 0, 0, tzinfo=timezone.utc)

fv_between = _make_mock_fv("view_between", ts_between)
fv_after = _make_mock_fv("view_after", ts_after)

mock_snowflake_registry.list_feature_views = MagicMock(
return_value=[fv_between, fv_after]
)
mock_snowflake_registry.list_stream_feature_views = MagicMock(return_value=[])
mock_snowflake_registry.list_on_demand_feature_views = MagicMock(return_value=[])

result = mock_snowflake_registry.list_all_feature_views(
"project", allow_cache=False, updated_since=cutoff_est
)
# Only view_after is at or after 05:00 UTC; view_between (03:00 UTC) should be excluded
assert [fv.name for fv in result] == ["view_after"]