Skip to content

fix: return empty list in place of raising FileNotFoundError when there are no eval sets #1835

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 15, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
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
6 changes: 5 additions & 1 deletion src/google/adk/cli/fast_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -523,7 +523,11 @@ def create_eval_set(
)
def list_eval_sets(app_name: str) -> list[str]:
"""Lists all eval sets for the given app."""
return eval_sets_manager.list_eval_sets(app_name)
try:
return eval_sets_manager.list_eval_sets(app_name)
except NotFoundError as e:
logger.warning(e)
return []

@app.post(
"/apps/{app_name}/eval_sets/{eval_set_id}/add_session",
Expand Down
31 changes: 23 additions & 8 deletions src/google/adk/evaluation/local_eval_sets_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
from pydantic import ValidationError
from typing_extensions import override

from ..errors.not_found_error import NotFoundError
from ._eval_sets_manager_utils import add_eval_case_to_eval_set
from ._eval_sets_manager_utils import delete_eval_case_from_eval_set
from ._eval_sets_manager_utils import get_eval_case_from_eval_set
Expand Down Expand Up @@ -226,16 +227,30 @@ def create_eval_set(self, app_name: str, eval_set_id: str):

@override
def list_eval_sets(self, app_name: str) -> list[str]:
"""Returns a list of EvalSets that belong to the given app_name."""
"""Returns a list of EvalSets that belong to the given app_name.

Args:
app_name: The app name to list the eval sets for.

Returns:
A list of EvalSet ids.

Raises:
NotFoundError: If the eval directory for the app is not found.
"""
eval_set_file_path = os.path.join(self._agents_dir, app_name)
eval_sets = []
for file in os.listdir(eval_set_file_path):
if file.endswith(_EVAL_SET_FILE_EXTENSION):
eval_sets.append(
os.path.basename(file).removesuffix(_EVAL_SET_FILE_EXTENSION)
)

return sorted(eval_sets)
try:
for file in os.listdir(eval_set_file_path):
if file.endswith(_EVAL_SET_FILE_EXTENSION):
eval_sets.append(
os.path.basename(file).removesuffix(_EVAL_SET_FILE_EXTENSION)
)
return sorted(eval_sets)
except FileNotFoundError as e:
raise NotFoundError(
f"Eval directory for app `{app_name}` not found."
) from e

@override
def get_eval_case(
Expand Down
9 changes: 9 additions & 0 deletions tests/unittests/evaluation/test_local_eval_sets_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,15 @@ def test_local_eval_sets_manager_list_eval_sets_success(

assert eval_sets == ["eval_set_1", "eval_set_2"]

def test_local_eval_sets_manager_list_eval_sets_not_found(
self, local_eval_sets_manager, mocker
):
app_name = "test_app"
mocker.patch("os.listdir", side_effect=FileNotFoundError)

with pytest.raises(NotFoundError):
local_eval_sets_manager.list_eval_sets(app_name)

def test_local_eval_sets_manager_add_eval_case_success(
self, local_eval_sets_manager, mocker
):
Expand Down