diff --git a/requirements.txt b/requirements.txt index 1f82926..98952d9 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,4 +5,5 @@ sssom-schema sssom oaklib==v0.1.71 pydantic[dotenv] -curies \ No newline at end of file +curies +toolz \ No newline at end of file diff --git a/src/models.py b/src/models.py index fb93fb0..0d731bc 100644 --- a/src/models.py +++ b/src/models.py @@ -7,11 +7,6 @@ from sssom_schema import Mapping, MappingSet, MappingRegistry, MappingSetReference T = TypeVar("T") -# class ResponseMapping(BaseModel): -# subject_id: Mapping.subject_id -# predicate_id: Mapping.predicate_id -# object_id: Mapping.object_id -# mapping_justification: Mapping.mapping_justification class PaginationParams(BaseModel): request: Request @@ -30,9 +25,15 @@ class PaginationInfo(BaseModel): total_pages: int +class FacetInfo(BaseModel): + mapping_justification: dict + predicate_id: dict + + class Page(GenericModel, Generic[T]): data: List[T] pagination: PaginationInfo + facets: FacetInfo class SearchEntity(BaseModel): diff --git a/src/utils.py b/src/utils.py index ff3a802..bad591b 100644 --- a/src/utils.py +++ b/src/utils.py @@ -1,12 +1,13 @@ from typing import Iterable, TypeVar, Union, List import itertools -import functools import math +from toolz.recipes import countby +from toolz.itertoolz import count from fastapi import Request -from .models import Page, PaginationInfo +from .models import Page, PaginationInfo, FacetInfo def _replace_page_param(request: Request, new_page: Union[int, None]) -> Union[str, None]: @@ -24,8 +25,8 @@ def paginate(iterable: Iterable[T], page: int, limit: int, request: Request) -> prev_page = None next_page = None data = [] - iter_data, iter_total = itertools.tee(iterable) - total_items = functools.reduce(lambda prev, curr: prev + 1, iter_total, 0) + iter_data, iter_total, iter_facets = itertools.tee(iterable, 3) + total_items = count(iter_total) total_pages = math.ceil(total_items / limit) for idx, item in enumerate(iter_data): if idx == start - 1: @@ -44,6 +45,15 @@ def paginate(iterable: Iterable[T], page: int, limit: int, request: Request) -> total_items=total_items, total_pages=total_pages ), + facets=_create_facets(iter_facets) + ) + +def _create_facets(data: Iterable[T]) -> FacetInfo: + iter_mj, iter_pred = itertools.tee(data) + + return FacetInfo( + mapping_justification=countby(lambda d: d["mapping_justification"], iter_mj), + predicate_id=countby(lambda d: d["predicate_id"], iter_pred), ) def parser_filter(datamodel: T, filter: Union[List[str], None] = None) -> Union[List[dict], None]: