11import logging
2- from typing import Annotated , Final
2+ from typing import Annotated , Final , TypeAlias , TypeVar
33
44from aiocache import cached # type: ignore[import-untyped]
5- from fastapi import APIRouter , Depends , Header , Request
6- from fastapi_pagination import Page , Params
5+ from fastapi import APIRouter , Depends , Header , Query , Request
6+ from fastapi_pagination import LimitOffsetPage , Params
77from fastapi_pagination .api import create_page , resolve_params
88from fastapi_pagination .bases import RawParams
9+ from fastapi_pagination .customization import CustomizedPage , UseParamsFields
910from models_library .api_schemas_datcore_adapter .datasets import (
1011 DatasetMetaData ,
1112 FileMetaData ,
1213)
14+ from models_library .api_schemas_storage .storage_schemas import (
15+ DEFAULT_NUMBER_OF_PATHS_PER_PAGE ,
16+ MAX_NUMBER_OF_PATHS_PER_PAGE ,
17+ )
1318from servicelib .fastapi .requests_decorators import cancel_on_disconnect
1419from starlette import status
1520
2530) # NOTE: this caching time is arbitrary
2631
2732
33+ _T = TypeVar ("_T" )
34+ _CustomPage = CustomizedPage [
35+ LimitOffsetPage [_T ],
36+ UseParamsFields (
37+ limit = Query (
38+ DEFAULT_NUMBER_OF_PATHS_PER_PAGE , ge = 1 , le = MAX_NUMBER_OF_PATHS_PER_PAGE
39+ ),
40+ ),
41+ ]
42+
43+ _CustomizedPageParams : TypeAlias = _CustomPage .__params_type__ # type: ignore
44+
45+
2846@router .get (
2947 "/datasets" ,
3048 summary = "list datasets" ,
3149 status_code = status .HTTP_200_OK ,
32- response_model = Page [DatasetMetaData ],
50+ response_model = _CustomPage [DatasetMetaData ],
3351)
3452@cancel_on_disconnect
3553@cached (
3654 ttl = _PENNSIEVE_CACHING_TTL_S ,
37- key_builder = lambda f , * args , ** kwargs : f"{ f .__name__ } _{ kwargs ['x_datcore_api_key' ]} _{ kwargs ['x_datcore_api_secret' ]} _{ kwargs ['params ' ]} " ,
55+ key_builder = lambda f , * args , ** kwargs : f"{ f .__name__ } _{ kwargs ['x_datcore_api_key' ]} _{ kwargs ['x_datcore_api_secret' ]} _{ kwargs ['page_params ' ]} " ,
3856)
3957async def list_datasets (
4058 request : Request ,
4159 x_datcore_api_key : Annotated [str , Header (..., description = "Datcore API Key" )],
4260 x_datcore_api_secret : Annotated [str , Header (..., description = "Datcore API Secret" )],
4361 pennsieve_client : Annotated [PennsieveApiClient , Depends (get_pennsieve_api_client )],
44- params : Annotated [Params , Depends ()],
45- ) -> Page [ DatasetMetaData ] :
62+ page_params : Annotated [_CustomizedPageParams , Depends ()],
63+ ):
4664 assert request # nosec
47- raw_params : RawParams = resolve_params (params ).to_raw_params ()
48- assert raw_params .limit is not None # nosec
49- assert raw_params .offset is not None # nosec
65+ assert page_params .limit is not None # nosec
66+ assert page_params .offset is not None # nosec
5067 datasets , total = await pennsieve_client .list_datasets (
5168 api_key = x_datcore_api_key ,
5269 api_secret = x_datcore_api_secret ,
53- limit = raw_params .limit ,
54- offset = raw_params .offset ,
70+ limit = page_params .limit ,
71+ offset = page_params .offset ,
5572 )
56- return create_page (datasets , total = total , params = params ) # type: ignore[return-value]
73+ return create_page (datasets , total = total , params = page_params )
5774
5875
5976@router .get (
@@ -85,46 +102,45 @@ async def get_dataset(
85102 "/datasets/{dataset_id}/files" ,
86103 summary = "list top level files/folders in a dataset" ,
87104 status_code = status .HTTP_200_OK ,
88- response_model = Page [FileMetaData ],
105+ response_model = _CustomPage [FileMetaData ],
89106)
90107@cancel_on_disconnect
91108@cached (
92109 ttl = _PENNSIEVE_CACHING_TTL_S ,
93- key_builder = lambda f , * args , ** kwargs : f"{ f .__name__ } _{ kwargs ['x_datcore_api_key' ]} _{ kwargs ['x_datcore_api_secret' ]} _{ kwargs ['dataset_id' ]} _{ kwargs ['params ' ]} " ,
110+ key_builder = lambda f , * args , ** kwargs : f"{ f .__name__ } _{ kwargs ['x_datcore_api_key' ]} _{ kwargs ['x_datcore_api_secret' ]} _{ kwargs ['dataset_id' ]} _{ kwargs ['page_params ' ]} " ,
94111)
95112async def list_dataset_top_level_files (
96113 request : Request ,
97114 dataset_id : str ,
98115 x_datcore_api_key : Annotated [str , Header (..., description = "Datcore API Key" )],
99116 x_datcore_api_secret : Annotated [str , Header (..., description = "Datcore API Secret" )],
100117 pennsieve_client : Annotated [PennsieveApiClient , Depends (get_pennsieve_api_client )],
101- params : Annotated [Params , Depends ()],
102- ) -> Page [ FileMetaData ] :
118+ page_params : Annotated [_CustomizedPageParams , Depends ()],
119+ ):
103120 assert request # nosec
104- raw_params : RawParams = resolve_params (params ).to_raw_params ()
105121
106- assert raw_params .limit is not None # nosec
107- assert raw_params .offset is not None # nosec
122+ assert page_params .limit is not None # nosec
123+ assert page_params .offset is not None # nosec
108124 file_metas , total = await pennsieve_client .list_packages_in_dataset (
109125 api_key = x_datcore_api_key ,
110126 api_secret = x_datcore_api_secret ,
111127 dataset_id = dataset_id ,
112- limit = raw_params .limit ,
113- offset = raw_params .offset ,
128+ limit = page_params .limit ,
129+ offset = page_params .offset ,
114130 )
115- return create_page (file_metas , total = total , params = params ) # type: ignore[return-value]
131+ return create_page (file_metas , total = total , params = page_params )
116132
117133
118134@router .get (
119135 "/datasets/{dataset_id}/files/{collection_id}" ,
120136 summary = "list top level files/folders in a collection in a dataset" ,
121137 status_code = status .HTTP_200_OK ,
122- response_model = Page [FileMetaData ],
138+ response_model = _CustomPage [FileMetaData ],
123139)
124140@cancel_on_disconnect
125141@cached (
126142 ttl = _PENNSIEVE_CACHING_TTL_S ,
127- key_builder = lambda f , * args , ** kwargs : f"{ f .__name__ } _{ kwargs ['x_datcore_api_key' ]} _{ kwargs ['x_datcore_api_secret' ]} _{ kwargs ['dataset_id' ]} _{ kwargs ['collection_id' ]} _{ kwargs ['params ' ]} " ,
143+ key_builder = lambda f , * args , ** kwargs : f"{ f .__name__ } _{ kwargs ['x_datcore_api_key' ]} _{ kwargs ['x_datcore_api_secret' ]} _{ kwargs ['dataset_id' ]} _{ kwargs ['collection_id' ]} _{ kwargs ['page_params ' ]} " ,
128144)
129145async def list_dataset_collection_files (
130146 request : Request ,
@@ -133,21 +149,20 @@ async def list_dataset_collection_files(
133149 x_datcore_api_key : Annotated [str , Header (..., description = "Datcore API Key" )],
134150 x_datcore_api_secret : Annotated [str , Header (..., description = "Datcore API Secret" )],
135151 pennsieve_client : Annotated [PennsieveApiClient , Depends (get_pennsieve_api_client )],
136- params : Annotated [Params , Depends ()],
137- ) -> Page [ FileMetaData ] :
152+ page_params : Annotated [_CustomizedPageParams , Depends ()],
153+ ):
138154 assert request # nosec
139- raw_params : RawParams = resolve_params (params ).to_raw_params ()
140- assert raw_params .limit is not None # nosec
141- assert raw_params .offset is not None # nosec
155+ assert page_params .limit is not None # nosec
156+ assert page_params .offset is not None # nosec
142157 file_metas , total = await pennsieve_client .list_packages_in_collection (
143158 api_key = x_datcore_api_key ,
144159 api_secret = x_datcore_api_secret ,
145- limit = raw_params .limit ,
146- offset = raw_params .offset ,
160+ limit = page_params .limit ,
161+ offset = page_params .offset ,
147162 dataset_id = dataset_id ,
148163 collection_id = collection_id ,
149164 )
150- return create_page (file_metas , total = total , params = params ) # type: ignore[return-value]
165+ return create_page (file_metas , total = total , params = page_params )
151166
152167
153168@router .get (
0 commit comments