@@ -16,7 +16,9 @@ class User(BubbleModel, typename="user"):
1616
1717from __future__ import annotations
1818
19+ import asyncio
1920import http
21+ import itertools
2022import typing
2123from datetime import datetime
2224from typing import TYPE_CHECKING
@@ -32,6 +34,12 @@ class User(BubbleModel, typename="user"):
3234from bubble_data_api_client .exceptions import BubbleAPIError , UnknownFieldError
3335from bubble_data_api_client .types import BUILTIN_FIELDS , BubbleField , OnMultiple
3436
37+ # default page size for paginated requests.
38+ _DEFAULT_PAGE_SIZE : int = 100
39+
40+ # max UIDs per "in" constraint batch, matching the API's max page size.
41+ _MAX_IN_CONSTRAINT_SIZE : int = 100
42+
3543
3644def _get_client () -> RawClient :
3745 return RawClient ()
@@ -114,10 +122,16 @@ async def get_many(cls, uids: list[str]) -> dict[str, typing.Self]:
114122 """Retrieve multiple things by their unique IDs, keyed by uid."""
115123 if not uids :
116124 return {}
117- items : list [typing .Self ] = await cls .find (
118- constraints = [constraint (BubbleField .ID , ConstraintType .IN , uids )],
125+ if len (uids ) <= _MAX_IN_CONSTRAINT_SIZE :
126+ items : list [typing .Self ] = await cls .find_all (
127+ constraints = [constraint (BubbleField .ID , ConstraintType .IN , uids )],
128+ )
129+ return {item .uid : item for item in items }
130+ chunks = itertools .batched (uids , _MAX_IN_CONSTRAINT_SIZE , strict = False )
131+ chunk_results : list [dict [str , typing .Self ]] = await asyncio .gather (
132+ * [cls .get_many (list (chunk )) for chunk in chunks ],
119133 )
120- return {item . uid : item for item in items }
134+ return {uid : item for result in chunk_results for uid , item in result . items () }
121135
122136 async def save (self ) -> None :
123137 """Persist all field changes to Bubble.
@@ -210,7 +224,7 @@ async def find_iter(
210224 cls ,
211225 * ,
212226 constraints : list [Constraint ] | None = None ,
213- page_size : int = 100 ,
227+ page_size : int = _DEFAULT_PAGE_SIZE ,
214228 sort_field : str | None = None ,
215229 descending : bool | None = None ,
216230 additional_sort_fields : list [AdditionalSortField ] | None = None ,
@@ -240,7 +254,7 @@ async def find_all(
240254 cls ,
241255 * ,
242256 constraints : list [Constraint ] | None = None ,
243- page_size : int = 100 ,
257+ page_size : int = _DEFAULT_PAGE_SIZE ,
244258 sort_field : str | None = None ,
245259 descending : bool | None = None ,
246260 additional_sort_fields : list [AdditionalSortField ] | None = None ,
0 commit comments