Skip to content

Commit

Permalink
feat(study-search): add a studies counting endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
mabw-rte committed Feb 22, 2024
1 parent df8c249 commit 19bc940
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 24 deletions.
16 changes: 16 additions & 0 deletions antarest/study/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,22 @@ def get_studies_information(
)
}

def count_studies(
self,
study_filter: StudyFilter,
) -> int:
"""
Get number of matching studies.
Args:
study_filter: filtering parameters
Returns: total number of studies matching the filtering criteria
"""
total: int = self.repository.count_studies(
study_filter=study_filter,
)
return total

def _try_get_studies_information(self, study: Study) -> t.Optional[StudyMetadataDTO]:
try:
return self.storage_service.get_storage(study).get_study_information(study)
Expand Down
103 changes: 79 additions & 24 deletions antarest/study/web/studies_blueprint.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@

logger = logging.getLogger(__name__)

QUERY_REGEX = r"^\s*(?:\d+\s*(?:,\s*\d+\s*)*)?$"


def _split_comma_separated_values(value: str, *, default: t.Sequence[str] = ()) -> t.Sequence[str]:
"""Split a comma-separated list of values into an ordered set of strings."""
Expand Down Expand Up @@ -76,23 +78,11 @@ def get_studies(
managed: t.Optional[bool] = Query(None, description="Filter studies based on their management status."),
archived: t.Optional[bool] = Query(None, description="Filter studies based on their archive status."),
variant: t.Optional[bool] = Query(None, description="Filter studies based on their variant status."),
versions: str = Query(
"",
description="Comma-separated list of versions for filtering.",
regex=r"^\s*(?:\d+\s*(?:,\s*\d+\s*)*)?$",
),
users: str = Query(
"",
description="Comma-separated list of user IDs for filtering.",
regex=r"^\s*(?:\d+\s*(?:,\s*\d+\s*)*)?$",
),
versions: str = Query("", description="Comma-separated list of versions for filtering.", regex=QUERY_REGEX),
users: str = Query("", description="Comma-separated list of user IDs for filtering.", regex=QUERY_REGEX),
groups: str = Query("", description="Comma-separated list of group IDs for filtering."),
tags: str = Query("", description="Comma-separated list of tags for filtering."),
study_ids: str = Query(
"",
description="Comma-separated list of study IDs for filtering.",
alias="studyIds",
),
study_ids: str = Query("", description="Comma-separated list of study IDs for filtering.", alias="studyIds"),
exists: t.Optional[bool] = Query(None, description="Filter studies based on their existence on disk."),
workspace: str = Query("", description="Filter studies based on their workspace."),
folder: str = Query("", description="Filter studies based on their folder."),
Expand All @@ -102,23 +92,17 @@ def get_studies(
description="Sort studies based on their name (case-insensitive) or creation date.",
alias="sortBy",
),
page_nb: NonNegativeInt = Query(
0,
description="Page number (starting from 0).",
alias="pageNb",
),
page_nb: NonNegativeInt = Query(0, description="Page number (starting from 0).", alias="pageNb"),
page_size: NonNegativeInt = Query(
0,
description="Number of studies per page (0 = no limit).",
alias="pageSize",
0, description="Number of studies per page (0 = no limit).", alias="pageSize"
),
) -> t.Dict[str, StudyMetadataDTO]:
"""
Get the list of studies matching the specified criteria.
Args:
- `name`: Filter studies based on their name. Case-insensitive search for studies
whose name contains the specified value.
- `managed`: Filter studies based on their management status.
- `archived`: Filter studies based on their archive status.
- `variant`: Filter studies based on their variant status.
Expand Down Expand Up @@ -173,6 +157,77 @@ def get_studies(

return matching_studies

@bp.get(
"/studies/count",
tags=[APITag.study_management],
summary="Count Studies",
)
def count_studies(
current_user: JWTUser = Depends(auth.get_current_user),
name: str = Query("", description="Case-insensitive: filter studies based on their name.", alias="name"),
managed: t.Optional[bool] = Query(None, description="Management status filter."),
archived: t.Optional[bool] = Query(None, description="Archive status filter."),
variant: t.Optional[bool] = Query(None, description="Variant status filter."),
versions: str = Query("", description="Comma-separated versions filter.", regex=QUERY_REGEX),
users: str = Query("", description="Comma-separated user IDs filter.", regex=QUERY_REGEX),
groups: str = Query("", description="Comma-separated group IDs filter."),
tags: str = Query("", description="Comma-separated tags filter."),
study_ids: str = Query("", description="Comma-separated study IDs filter.", alias="studyIds"),
exists: t.Optional[bool] = Query(None, description="Existence on disk filter."),
workspace: str = Query("", description="Workspace filter."),
folder: str = Query("", description="Study folder filter."),
) -> int:
"""
Get the number of studies matching the specified criteria.
Args:
- `name`: Regexp to filter through studies based on their names
- `managed`: Whether to limit the selection based on management status.
- `archived`: Whether to limit the selection based on archive status.
- `variant`: Whether to limit the selection either raw or variant studies.
- `versions`: Comma-separated versions for studies to be selected.
- `users`: Comma-separated user IDs for studies to be selected.
- `groups`: Comma-separated group IDs for studies to be selected.
- `tags`: Comma-separated tags for studies to be selected.
- `studyIds`: Comma-separated IDs of studies to be selected.
- `exists`: Whether to limit the selection based on studies' existence on disk.
- `workspace`: to limit studies selection based on their workspace.
- `folder`: to limit studies selection based on their folder.
Returns:
- An integer representing the total number of studies matching the filters above and the user permissions.
"""

logger.info("Counting matching studies", extra={"user": current_user.id})
params = RequestParameters(user=current_user)

user_list = [int(v) for v in _split_comma_separated_values(users)]

if not params.user:
logger.error("FAIL permission: user is not logged")
raise UserHasNotPermissionError()

total_matching_studies = study_service.count_studies(
study_filter=StudyFilter(
name=name,
managed=managed,
archived=archived,
variant=variant,
versions=_split_comma_separated_values(versions),
users=user_list,
groups=_split_comma_separated_values(groups),
tags=_split_comma_separated_values(tags),
study_ids=_split_comma_separated_values(study_ids),
exists=exists,
workspace=workspace,
folder=folder,
access_permissions=AccessPermissions.from_params(params),
),
)

return total_matching_studies

@bp.get(
"/studies/{uuid}/comments",
tags=[APITag.study_management],
Expand Down

0 comments on commit 19bc940

Please sign in to comment.