Skip to content

Commit 5e93f44

Browse files
committed
batch get_many requests to respect apis max in constraint size
1 parent 08b5dd6 commit 5e93f44

File tree

1 file changed

+19
-5
lines changed
  • src/bubble_data_api_client/client

1 file changed

+19
-5
lines changed

src/bubble_data_api_client/client/orm.py

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@ class User(BubbleModel, typename="user"):
1616

1717
from __future__ import annotations
1818

19+
import asyncio
1920
import http
21+
import itertools
2022
import typing
2123
from datetime import datetime
2224
from typing import TYPE_CHECKING
@@ -32,6 +34,12 @@ class User(BubbleModel, typename="user"):
3234
from bubble_data_api_client.exceptions import BubbleAPIError, UnknownFieldError
3335
from 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

3644
def _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

Comments
 (0)