Visitar URL original
feat: Implemented registry refresh action feature by AdityaPatil22 · Pull Request #6657 · 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
fix: Bypass registry cache for projects-list endpoint
Signed-off-by: Aditya Patil <adpatil@redhat.com>
  • Loading branch information
Aditya Patil
Aditya Patil committed Jul 31, 2026
commit df39c55e3c6fb96b2f2c03ceb389241a7fc9cc5e
2 changes: 1 addition & 1 deletion sdk/python/feast/ui_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ def _build_projects_list(
registry_path_template = f"{root_path}/api/v1"

try:
projects = store.registry.list_projects(allow_cache=True)
projects = store.registry.list_projects(allow_cache=False)
for proj in projects:
discovered_projects.append(
{
Expand Down
63 changes: 48 additions & 15 deletions sdk/python/tests/unit/test_ui_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,11 +148,12 @@ def test_catch_all_route(ui_app_with_registry):
# ---------- projects-list.json tests ----------


def _read_projects_list(temp_dir):
"""Read the projects-list.json written by get_app via the mock (ui_dir = temp_dir)."""
projects_file = os.path.join(temp_dir, "projects-list.json")
with open(projects_file) as f:
return json.load(f)
def _get_projects_list(app):
Comment thread
ntkathole marked this conversation as resolved.
Outdated
"""Fetch the dynamic projects-list.json endpoint."""
client = TestClient(app)
resp = client.get("/projects-list.json")
assertpy.assert_that(resp.status_code).is_equal_to(EXPECTED_SUCCESS_STATUS)
return resp.json()


def test_projects_list_registry_path(mock_feature_store):
Expand All @@ -165,9 +166,9 @@ def test_projects_list_registry_path(mock_feature_store):
_create_mock_ui_files(temp_dir)

with _setup_importlib_mocks(temp_dir):
get_app(mock_feature_store, TEST_PROJECT_NAME)
app = get_app(mock_feature_store, TEST_PROJECT_NAME)

data = _read_projects_list(temp_dir)
data = _get_projects_list(app)
assertpy.assert_that(data["projects"][0]["registryPath"]).is_equal_to("/api/v1")


Expand All @@ -181,13 +182,13 @@ def test_projects_list_with_root_path(mock_feature_store):
_create_mock_ui_files(temp_dir)

with _setup_importlib_mocks(temp_dir):
get_app(
app = get_app(
mock_feature_store,
TEST_PROJECT_NAME,
root_path="/feast",
)

data = _read_projects_list(temp_dir)
data = _get_projects_list(app)
assertpy.assert_that(data["projects"][0]["registryPath"]).is_equal_to(
"/feast/api/v1"
)
Expand All @@ -206,9 +207,9 @@ def test_projects_list_multiple_projects(mock_feature_store):
_create_mock_ui_files(temp_dir)

with _setup_importlib_mocks(temp_dir):
get_app(mock_feature_store, TEST_PROJECT_NAME)
app = get_app(mock_feature_store, TEST_PROJECT_NAME)

data = _read_projects_list(temp_dir)
data = _get_projects_list(app)
assertpy.assert_that(len(data["projects"])).is_equal_to(3)
assertpy.assert_that(data["projects"][0]["id"]).is_equal_to("all")
assertpy.assert_that(data["projects"][1]["id"]).is_equal_to("project_alpha")
Expand All @@ -225,9 +226,9 @@ def test_projects_list_fallback_on_empty(mock_feature_store):
_create_mock_ui_files(temp_dir)

with _setup_importlib_mocks(temp_dir):
get_app(mock_feature_store, TEST_PROJECT_NAME)
app = get_app(mock_feature_store, TEST_PROJECT_NAME)

data = _read_projects_list(temp_dir)
data = _get_projects_list(app)
assertpy.assert_that(len(data["projects"])).is_equal_to(1)
assertpy.assert_that(data["projects"][0]["id"]).is_equal_to(TEST_PROJECT_NAME)

Expand All @@ -242,8 +243,40 @@ def test_projects_list_fallback_on_exception(mock_feature_store):
_create_mock_ui_files(temp_dir)

with _setup_importlib_mocks(temp_dir):
get_app(mock_feature_store, TEST_PROJECT_NAME)
app = get_app(mock_feature_store, TEST_PROJECT_NAME)

data = _read_projects_list(temp_dir)
data = _get_projects_list(app)
assertpy.assert_that(len(data["projects"])).is_equal_to(1)
assertpy.assert_that(data["projects"][0]["id"]).is_equal_to(TEST_PROJECT_NAME)


def test_projects_list_dynamic_refresh(mock_feature_store):
"""New projects appear without restarting the server."""
mock_registry = MagicMock()
mock_registry.list_projects.return_value = [
_make_project_mock("picked_elk"),
]
mock_feature_store.registry = mock_registry

with tempfile.TemporaryDirectory() as temp_dir:
_create_mock_ui_files(temp_dir)

with _setup_importlib_mocks(temp_dir):
app = get_app(mock_feature_store, TEST_PROJECT_NAME)

client = TestClient(app)

data = client.get("/projects-list.json").json()
assertpy.assert_that(len(data["projects"])).is_equal_to(1)
assertpy.assert_that(data["projects"][0]["id"]).is_equal_to("picked_elk")

mock_registry.list_projects.return_value = [
_make_project_mock("picked_elk"),
_make_project_mock("picked_elk2"),
]

data = client.get("/projects-list.json").json()
assertpy.assert_that(len(data["projects"])).is_equal_to(3)
assertpy.assert_that(data["projects"][0]["id"]).is_equal_to("all")
assertpy.assert_that(data["projects"][1]["id"]).is_equal_to("picked_elk")
assertpy.assert_that(data["projects"][2]["id"]).is_equal_to("picked_elk2")