22import datetime
33from collections .abc import AsyncGenerator
44from pathlib import Path
5- from typing import TypeAlias
5+ from typing import Annotated , TypeAlias
66
77import sqlalchemy as sa
88from models_library .basic_types import SHA256Str
99from models_library .projects import ProjectID
1010from models_library .projects_nodes_io import NodeID , SimcoreS3FileID
1111from models_library .users import UserID
1212from models_library .utils .fastapi_encoders import jsonable_encoder
13- from pydantic import BaseModel
13+ from pydantic import BaseModel , Field , validate_call
1414from simcore_postgres_database .storage_models import file_meta_data
1515from simcore_postgres_database .utils_repos import (
1616 pass_or_acquire_connection ,
3535
3636
3737class _PathsCursorParameters (BaseModel ):
38+ # NOTE: this is a cursor do not put things that can grow unbounded as this goes then through REST APIs or such
3839 offset : int
3940 file_prefix : Path | None
40- project_ids : list [ProjectID ] | None
4141 partial : bool
4242
4343
4444def _init_pagination (
4545 cursor : GenericCursor | None ,
4646 * ,
47- filter_by_project_ids : list [ProjectID ] | None ,
4847 filter_by_file_prefix : Path | None ,
4948 is_partial_prefix : bool ,
5049) -> _PathsCursorParameters :
@@ -53,7 +52,6 @@ def _init_pagination(
5352 return _PathsCursorParameters (
5453 offset = 0 ,
5554 file_prefix = filter_by_file_prefix ,
56- project_ids = filter_by_project_ids ,
5755 partial = is_partial_prefix ,
5856 )
5957
@@ -229,23 +227,28 @@ async def try_get_directory(
229227 return None
230228 return None
231229
230+ @validate_call (config = {"arbitrary_types_allowed" : True })
232231 async def list_child_paths (
233232 self ,
234233 * ,
235234 connection : AsyncConnection | None = None ,
236- filter_by_project_ids : list [ProjectID ] | None ,
235+ filter_by_project_ids : Annotated [
236+ list [ProjectID ] | None , Field (max_length = 10000 )
237+ ],
237238 filter_by_file_prefix : Path | None ,
238239 cursor : GenericCursor | None ,
239240 limit : int ,
240241 is_partial_prefix : bool ,
241242 ) -> tuple [list [PathMetaData ], GenericCursor | None , TotalChildren ]:
242243 """returns a list of FileMetaDataAtDB that are one level deep.
243244 e.g. when no filter is used, these are top level objects
245+
246+ NOTE: if filter_by_project_ids is huge, this will raise ValidationError and someone needs to fix it!
247+ Maybe using a DB join
244248 """
245249
246250 cursor_params = _init_pagination (
247251 cursor ,
248- filter_by_project_ids = filter_by_project_ids ,
249252 filter_by_file_prefix = filter_by_file_prefix ,
250253 is_partial_prefix = is_partial_prefix ,
251254 )
@@ -278,9 +281,9 @@ async def list_child_paths(
278281 file_meta_data .c .file_id .like (search_prefix ),
279282 (
280283 file_meta_data .c .project_id .in_ (
281- [f"{ _ } " for _ in cursor_params . project_ids ]
284+ [f"{ _ } " for _ in filter_by_project_ids ]
282285 )
283- if cursor_params . project_ids
286+ if filter_by_project_ids
284287 else True
285288 ),
286289 )
@@ -303,9 +306,9 @@ async def list_child_paths(
303306 )
304307 .where (
305308 file_meta_data .c .project_id .in_ (
306- [f"{ _ } " for _ in cursor_params . project_ids ]
309+ [f"{ _ } " for _ in filter_by_project_ids ]
307310 )
308- if cursor_params . project_ids
311+ if filter_by_project_ids
309312 else True
310313 )
311314 .cte ("ranked_files" )
0 commit comments