mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-10 03:28:53 +00:00
fix(batches): keep an empty after meaning "start from the beginning"
Validating the cursor whenever `after` was non-None turned `?after=` into a 400, which the listing has always read as "no cursor". Only a cursor the client actually sent is looked up now, matching the sibling managed-resource listing.
This commit is contained in:
parent
c1ea54a1d0
commit
85ad6971e9
2 changed files with 31 additions and 4 deletions
|
|
@ -315,7 +315,7 @@ class _PROXY_LiteLLMManagedFiles(CustomLogger, BaseFileEndpoints):
|
|||
|
||||
where_clause: Dict[str, Any] = {"file_purpose": "batch", **owner_filter}
|
||||
|
||||
if after is not None:
|
||||
if after:
|
||||
cursor_row = (
|
||||
await self.prisma_client.db.litellm_managedobjecttable.find_first(
|
||||
where={**where_clause, "unified_object_id": after}
|
||||
|
|
@ -329,9 +329,7 @@ class _PROXY_LiteLLMManagedFiles(CustomLogger, BaseFileEndpoints):
|
|||
|
||||
page_size = limit or 20
|
||||
cursor_args: Dict[str, Any] = (
|
||||
{"cursor": {"unified_object_id": after}, "skip": 1}
|
||||
if after is not None
|
||||
else {}
|
||||
{"cursor": {"unified_object_id": after}, "skip": 1} if after else {}
|
||||
)
|
||||
|
||||
batches = await self.prisma_client.db.litellm_managedobjecttable.find_many(
|
||||
|
|
|
|||
|
|
@ -2309,6 +2309,35 @@ async def test_list_batches_rejects_unknown_after_cursor():
|
|||
)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_list_batches_treats_empty_after_as_no_cursor():
|
||||
"""``?after=`` means "start from the beginning", as it always has.
|
||||
|
||||
Only a cursor the client actually sent is validated, so an SDK that always
|
||||
emits the query parameter does not get a 400 on its first page.
|
||||
"""
|
||||
from litellm.proxy._types import UserAPIKeyAuth
|
||||
|
||||
rows = [_managed_batch_row(i) for i in range(2)]
|
||||
prisma_client = _fake_managed_object_table(rows)
|
||||
|
||||
proxy_managed_files = _PROXY_LiteLLMManagedFiles(
|
||||
DualCache(), prisma_client=prisma_client
|
||||
)
|
||||
|
||||
page = await proxy_managed_files.list_user_batches(
|
||||
user_api_key_dict=UserAPIKeyAuth(user_id="test-user"), limit=2, after=""
|
||||
)
|
||||
|
||||
assert [batch.id for batch in page["data"]] == [
|
||||
rows[1].unified_object_id,
|
||||
rows[0].unified_object_id,
|
||||
]
|
||||
prisma_client.db.litellm_managedobjecttable.find_first.assert_not_called()
|
||||
_, call_kwargs = prisma_client.db.litellm_managedobjecttable.find_many.call_args
|
||||
assert "cursor" not in call_kwargs
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_list_batches_rejects_after_cursor_owned_by_another_user():
|
||||
"""The cursor lookup must be scoped to the rows the caller can list.
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue