Skip to content

Commit d55fceb

Browse files
authored
fix(sdk): fixed pagination for scorer, scenario and network policy list methods (#731)
1 parent c3bebb5 commit d55fceb

4 files changed

Lines changed: 46 additions & 71 deletions

File tree

src/runloop_api_client/sdk/async_.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -557,7 +557,7 @@ async def list(self, **params: Unpack[SDKScorerListParams]) -> list[AsyncScorer]
557557
:rtype: list[AsyncScorer]
558558
"""
559559
page = await self._client.scenarios.scorers.list(**params)
560-
return [AsyncScorer(self._client, item.id) async for item in page]
560+
return [AsyncScorer(self._client, item.id) for item in page.scorers]
561561

562562

563563
class AsyncAgentOps:
@@ -818,7 +818,7 @@ async def list(self, **params: Unpack[SDKScenarioListParams]) -> list[AsyncScena
818818
:rtype: list[AsyncScenario]
819819
"""
820820
page = await self._client.scenarios.list(**params)
821-
return [AsyncScenario(self._client, item.id) async for item in page]
821+
return [AsyncScenario(self._client, item.id) for item in page.scenarios]
822822

823823

824824
class AsyncBenchmarkOps:
@@ -920,8 +920,8 @@ async def list(self, **params: Unpack[SDKNetworkPolicyListParams]) -> list[Async
920920
:return: List of network policies
921921
:rtype: list[AsyncNetworkPolicy]
922922
"""
923-
page = self._client.network_policies.list(**params)
924-
return [AsyncNetworkPolicy(self._client, item.id) async for item in page]
923+
page = await self._client.network_policies.list(**params)
924+
return [AsyncNetworkPolicy(self._client, item.id) for item in page.network_policies]
925925

926926

927927
class AsyncRunloopSDK:

src/runloop_api_client/sdk/sync.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -552,7 +552,7 @@ def list(self, **params: Unpack[SDKScorerListParams]) -> list[Scorer]:
552552
:rtype: list[Scorer]
553553
"""
554554
page = self._client.scenarios.scorers.list(**params)
555-
return [Scorer(self._client, item.id) for item in page]
555+
return [Scorer(self._client, item.id) for item in page.scorers]
556556

557557

558558
class AgentOps:
@@ -843,7 +843,7 @@ def list(self, **params: Unpack[SDKScenarioListParams]) -> list[Scenario]:
843843
:rtype: list[Scenario]
844844
"""
845845
page = self._client.scenarios.list(**params)
846-
return [Scenario(self._client, item.id) for item in page]
846+
return [Scenario(self._client, item.id) for item in page.scenarios]
847847

848848

849849
class BenchmarkOps:
@@ -946,7 +946,7 @@ def list(self, **params: Unpack[SDKNetworkPolicyListParams]) -> list[NetworkPoli
946946
:rtype: list[NetworkPolicy]
947947
"""
948948
page = self._client.network_policies.list(**params)
949-
return [NetworkPolicy(self._client, item.id) for item in page]
949+
return [NetworkPolicy(self._client, item.id) for item in page.network_policies]
950950

951951

952952
class RunloopSDK:

tests/sdk/test_async_ops.py

Lines changed: 21 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -732,12 +732,8 @@ def test_from_id(self, mock_async_client: AsyncMock) -> None:
732732
@pytest.mark.asyncio
733733
async def test_list_empty(self, mock_async_client: AsyncMock) -> None:
734734
"""Test list method with empty results."""
735-
736-
async def async_iter():
737-
return
738-
yield # Make this a generator
739-
740-
mock_async_client.scenarios.scorers.list = AsyncMock(return_value=async_iter())
735+
page = SimpleNamespace(scorers=[])
736+
mock_async_client.scenarios.scorers.list = AsyncMock(return_value=page)
741737

742738
ops = AsyncScorerOps(mock_async_client)
743739
scorers = await ops.list(limit=10)
@@ -748,11 +744,8 @@ async def async_iter():
748744
@pytest.mark.asyncio
749745
async def test_list_single(self, mock_async_client: AsyncMock, scorer_view: MockScorerView) -> None:
750746
"""Test list method with single result."""
751-
752-
async def async_iter():
753-
yield scorer_view
754-
755-
mock_async_client.scenarios.scorers.list = AsyncMock(return_value=async_iter())
747+
page = SimpleNamespace(scorers=[scorer_view])
748+
mock_async_client.scenarios.scorers.list = AsyncMock(return_value=page)
756749

757750
ops = AsyncScorerOps(mock_async_client)
758751
scorers = await ops.list(
@@ -770,12 +763,8 @@ async def test_list_multiple(self, mock_async_client: AsyncMock) -> None:
770763
"""Test list method with multiple results."""
771764
scorer_view1 = MockScorerView(id="scorer_001", type="scorer-1")
772765
scorer_view2 = MockScorerView(id="scorer_002", type="scorer-2")
773-
774-
async def async_iter():
775-
yield scorer_view1
776-
yield scorer_view2
777-
778-
mock_async_client.scenarios.scorers.list = AsyncMock(return_value=async_iter())
766+
page = SimpleNamespace(scorers=[scorer_view1, scorer_view2])
767+
mock_async_client.scenarios.scorers.list = AsyncMock(return_value=page)
779768

780769
ops = AsyncScorerOps(mock_async_client)
781770
scorers = await ops.list(limit=10)
@@ -1152,12 +1141,8 @@ def test_from_id(self, mock_async_client: AsyncMock) -> None:
11521141
@pytest.mark.asyncio
11531142
async def test_list_empty(self, mock_async_client: AsyncMock) -> None:
11541143
"""Test list method with empty results."""
1155-
1156-
async def async_iter():
1157-
return
1158-
yield # Make this a generator
1159-
1160-
mock_async_client.scenarios.list = AsyncMock(return_value=async_iter())
1144+
page = SimpleNamespace(scenarios=[])
1145+
mock_async_client.scenarios.list = AsyncMock(return_value=page)
11611146

11621147
ops = AsyncScenarioOps(mock_async_client)
11631148
scenarios = await ops.list(limit=10)
@@ -1168,11 +1153,8 @@ async def async_iter():
11681153
@pytest.mark.asyncio
11691154
async def test_list_single(self, mock_async_client: AsyncMock, scenario_view: MockScenarioView) -> None:
11701155
"""Test list method with single result."""
1171-
1172-
async def async_iter():
1173-
yield scenario_view
1174-
1175-
mock_async_client.scenarios.list = AsyncMock(return_value=async_iter())
1156+
page = SimpleNamespace(scenarios=[scenario_view])
1157+
mock_async_client.scenarios.list = AsyncMock(return_value=page)
11761158

11771159
ops = AsyncScenarioOps(mock_async_client)
11781160
scenarios = await ops.list(limit=10)
@@ -1185,15 +1167,10 @@ async def async_iter():
11851167
@pytest.mark.asyncio
11861168
async def test_list_multiple(self, mock_async_client: AsyncMock) -> None:
11871169
"""Test list method with multiple results."""
1188-
11891170
scenario_view1 = MockScenarioView(id="scn_001", name="scenario-1")
11901171
scenario_view2 = MockScenarioView(id="scn_002", name="scenario-2")
1191-
1192-
async def async_iter():
1193-
yield scenario_view1
1194-
yield scenario_view2
1195-
1196-
mock_async_client.scenarios.list = AsyncMock(return_value=async_iter())
1172+
page = SimpleNamespace(scenarios=[scenario_view1, scenario_view2])
1173+
mock_async_client.scenarios.list = AsyncMock(return_value=page)
11971174

11981175
ops = AsyncScenarioOps(mock_async_client)
11991176
scenarios = await ops.list(limit=10)
@@ -1291,26 +1268,20 @@ def test_from_id(self, mock_async_client: AsyncMock) -> None:
12911268
@pytest.mark.asyncio
12921269
async def test_list_empty(self, mock_async_client: AsyncMock) -> None:
12931270
"""Test list method with empty results."""
1294-
1295-
async def async_iter():
1296-
return
1297-
yield # Make this a generator
1298-
1299-
mock_async_client.network_policies.list.return_value = async_iter()
1271+
page = SimpleNamespace(network_policies=[])
1272+
mock_async_client.network_policies.list = AsyncMock(return_value=page)
13001273

13011274
ops = AsyncNetworkPolicyOps(mock_async_client)
13021275
network_policies = await ops.list(limit=10)
13031276

13041277
assert len(network_policies) == 0
1278+
mock_async_client.network_policies.list.assert_awaited_once()
13051279

13061280
@pytest.mark.asyncio
13071281
async def test_list_single(self, mock_async_client: AsyncMock, network_policy_view: MockNetworkPolicyView) -> None:
13081282
"""Test list method with single result."""
1309-
1310-
async def async_iter():
1311-
yield network_policy_view
1312-
1313-
mock_async_client.network_policies.list.return_value = async_iter()
1283+
page = SimpleNamespace(network_policies=[network_policy_view])
1284+
mock_async_client.network_policies.list = AsyncMock(return_value=page)
13141285

13151286
ops = AsyncNetworkPolicyOps(mock_async_client)
13161287
network_policies = await ops.list(
@@ -1321,18 +1292,15 @@ async def async_iter():
13211292
assert len(network_policies) == 1
13221293
assert isinstance(network_policies[0], AsyncNetworkPolicy)
13231294
assert network_policies[0].id == "np_123"
1295+
mock_async_client.network_policies.list.assert_awaited_once()
13241296

13251297
@pytest.mark.asyncio
13261298
async def test_list_multiple(self, mock_async_client: AsyncMock) -> None:
13271299
"""Test list method with multiple results."""
13281300
network_policy_view1 = MockNetworkPolicyView(id="np_001", name="policy-1")
13291301
network_policy_view2 = MockNetworkPolicyView(id="np_002", name="policy-2")
1330-
1331-
async def async_iter():
1332-
yield network_policy_view1
1333-
yield network_policy_view2
1334-
1335-
mock_async_client.network_policies.list.return_value = async_iter()
1302+
page = SimpleNamespace(network_policies=[network_policy_view1, network_policy_view2])
1303+
mock_async_client.network_policies.list = AsyncMock(return_value=page)
13361304

13371305
ops = AsyncNetworkPolicyOps(mock_async_client)
13381306
network_policies = await ops.list(limit=10)
@@ -1342,6 +1310,7 @@ async def async_iter():
13421310
assert isinstance(network_policies[1], AsyncNetworkPolicy)
13431311
assert network_policies[0].id == "np_001"
13441312
assert network_policies[1].id == "np_002"
1313+
mock_async_client.network_policies.list.assert_awaited_once()
13451314

13461315

13471316
class TestAsyncRunloopSDK:

tests/sdk/test_ops.py

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -679,7 +679,8 @@ def test_from_id(self, mock_client: Mock) -> None:
679679

680680
def test_list_empty(self, mock_client: Mock) -> None:
681681
"""Test list method with empty results."""
682-
mock_client.scenarios.scorers.list.return_value = []
682+
page = SimpleNamespace(scorers=[])
683+
mock_client.scenarios.scorers.list.return_value = page
683684

684685
ops = ScorerOps(mock_client)
685686
scorers = ops.list(limit=10)
@@ -689,7 +690,8 @@ def test_list_empty(self, mock_client: Mock) -> None:
689690

690691
def test_list_single(self, mock_client: Mock, scorer_view: MockScorerView) -> None:
691692
"""Test list method with single result."""
692-
mock_client.scenarios.scorers.list.return_value = [scorer_view]
693+
page = SimpleNamespace(scorers=[scorer_view])
694+
mock_client.scenarios.scorers.list.return_value = page
693695

694696
ops = ScorerOps(mock_client)
695697
scorers = ops.list(
@@ -706,7 +708,8 @@ def test_list_multiple(self, mock_client: Mock) -> None:
706708
"""Test list method with multiple results."""
707709
scorer_view1 = MockScorerView(id="scorer_001", type="scorer-1")
708710
scorer_view2 = MockScorerView(id="scorer_002", type="scorer-2")
709-
mock_client.scenarios.scorers.list.return_value = [scorer_view1, scorer_view2]
711+
page = SimpleNamespace(scorers=[scorer_view1, scorer_view2])
712+
mock_client.scenarios.scorers.list.return_value = page
710713

711714
ops = ScorerOps(mock_client)
712715
scorers = ops.list(limit=10)
@@ -1062,8 +1065,8 @@ def test_from_id(self, mock_client: Mock) -> None:
10621065

10631066
def test_list_empty(self, mock_client: Mock) -> None:
10641067
"""Test list method with empty results."""
1065-
1066-
mock_client.scenarios.list.return_value = []
1068+
page = SimpleNamespace(scenarios=[])
1069+
mock_client.scenarios.list.return_value = page
10671070

10681071
ops = ScenarioOps(mock_client)
10691072
scenarios = ops.list(limit=10)
@@ -1073,8 +1076,8 @@ def test_list_empty(self, mock_client: Mock) -> None:
10731076

10741077
def test_list_single(self, mock_client: Mock, scenario_view: MockScenarioView) -> None:
10751078
"""Test list method with single result."""
1076-
1077-
mock_client.scenarios.list.return_value = [scenario_view]
1079+
page = SimpleNamespace(scenarios=[scenario_view])
1080+
mock_client.scenarios.list.return_value = page
10781081

10791082
ops = ScenarioOps(mock_client)
10801083
scenarios = ops.list(limit=10)
@@ -1086,10 +1089,10 @@ def test_list_single(self, mock_client: Mock, scenario_view: MockScenarioView) -
10861089

10871090
def test_list_multiple(self, mock_client: Mock) -> None:
10881091
"""Test list method with multiple results."""
1089-
10901092
scenario_view1 = MockScenarioView(id="scn_001", name="scenario-1")
10911093
scenario_view2 = MockScenarioView(id="scn_002", name="scenario-2")
1092-
mock_client.scenarios.list.return_value = [scenario_view1, scenario_view2]
1094+
page = SimpleNamespace(scenarios=[scenario_view1, scenario_view2])
1095+
mock_client.scenarios.list.return_value = page
10931096

10941097
ops = ScenarioOps(mock_client)
10951098
scenarios = ops.list(limit=10)
@@ -1182,7 +1185,8 @@ def test_from_id(self, mock_client: Mock) -> None:
11821185

11831186
def test_list_empty(self, mock_client: Mock) -> None:
11841187
"""Test list method with empty results."""
1185-
mock_client.network_policies.list.return_value = []
1188+
page = SimpleNamespace(network_policies=[])
1189+
mock_client.network_policies.list.return_value = page
11861190

11871191
ops = NetworkPolicyOps(mock_client)
11881192
network_policies = ops.list(limit=10)
@@ -1192,7 +1196,8 @@ def test_list_empty(self, mock_client: Mock) -> None:
11921196

11931197
def test_list_single(self, mock_client: Mock, network_policy_view: MockNetworkPolicyView) -> None:
11941198
"""Test list method with single result."""
1195-
mock_client.network_policies.list.return_value = [network_policy_view]
1199+
page = SimpleNamespace(network_policies=[network_policy_view])
1200+
mock_client.network_policies.list.return_value = page
11961201

11971202
ops = NetworkPolicyOps(mock_client)
11981203
network_policies = ops.list(
@@ -1209,7 +1214,8 @@ def test_list_multiple(self, mock_client: Mock) -> None:
12091214
"""Test list method with multiple results."""
12101215
network_policy_view1 = MockNetworkPolicyView(id="np_001", name="policy-1")
12111216
network_policy_view2 = MockNetworkPolicyView(id="np_002", name="policy-2")
1212-
mock_client.network_policies.list.return_value = [network_policy_view1, network_policy_view2]
1217+
page = SimpleNamespace(network_policies=[network_policy_view1, network_policy_view2])
1218+
mock_client.network_policies.list.return_value = page
12131219

12141220
ops = NetworkPolicyOps(mock_client)
12151221
network_policies = ops.list(limit=10)

0 commit comments

Comments
 (0)