|
2 | 2 |
|
3 | 3 | from typing import TYPE_CHECKING, Any |
4 | 4 |
|
5 | | -from apify_client._models import GetListOfRunsResponse, ListOfRuns |
| 5 | +from apify_client._models import GetListOfRunsResponse, ListOfRuns, RunShort |
6 | 6 | from apify_client._resource_clients._resource_client import ResourceClient, ResourceClientAsync |
7 | 7 | from apify_client._utils import enum_to_value, response_to_dict |
8 | 8 |
|
9 | 9 | if TYPE_CHECKING: |
| 10 | + from collections.abc import AsyncIterator, Iterator |
10 | 11 | from datetime import datetime |
11 | 12 |
|
12 | 13 | from apify_client._consts import ActorJobStatus |
@@ -65,6 +66,62 @@ def list( |
65 | 66 | response_as_dict = response_to_dict(response) |
66 | 67 | return GetListOfRunsResponse.model_validate(response_as_dict).data |
67 | 68 |
|
| 69 | + def iterate( |
| 70 | + self, |
| 71 | + *, |
| 72 | + limit: int | None = None, |
| 73 | + desc: bool | None = None, |
| 74 | + status: ActorJobStatus | list[ActorJobStatus] | None = None, # ty: ignore[invalid-type-form] |
| 75 | + started_before: str | datetime | None = None, |
| 76 | + started_after: str | datetime | None = None, |
| 77 | + ) -> Iterator[RunShort]: |
| 78 | + """Iterate over all Actor runs. |
| 79 | +
|
| 80 | + Iterate over all Actor runs, either of a single Actor, or all user's Actors, depending on where this client |
| 81 | + was initialized from. |
| 82 | +
|
| 83 | + https://docs.apify.com/api/v2#/reference/actors/run-collection/get-list-of-runs |
| 84 | + https://docs.apify.com/api/v2#/reference/actor-runs/run-collection/get-user-runs-list |
| 85 | +
|
| 86 | + Args: |
| 87 | + limit: Maximum number of runs to return. By default there is no limit. |
| 88 | + desc: Whether to sort the runs in descending order based on their start date. |
| 89 | + status: Retrieve only runs with the provided statuses. |
| 90 | + started_before: Only return runs started before this date (inclusive). |
| 91 | + started_after: Only return runs started after this date (inclusive). |
| 92 | +
|
| 93 | + Yields: |
| 94 | + A run from the collection. |
| 95 | + """ |
| 96 | + cache_size = 1000 |
| 97 | + read_items = 0 |
| 98 | + offset = 0 |
| 99 | + |
| 100 | + while True: |
| 101 | + effective_limit = cache_size |
| 102 | + if limit is not None: |
| 103 | + if read_items == limit: |
| 104 | + break |
| 105 | + effective_limit = min(cache_size, limit - read_items) |
| 106 | + |
| 107 | + current_page = self.list( |
| 108 | + limit=effective_limit, |
| 109 | + offset=offset, |
| 110 | + desc=desc, |
| 111 | + status=status, |
| 112 | + started_before=started_before, |
| 113 | + started_after=started_after, |
| 114 | + ) |
| 115 | + |
| 116 | + yield from current_page.items |
| 117 | + |
| 118 | + current_page_item_count = len(current_page.items) |
| 119 | + read_items += current_page_item_count |
| 120 | + offset += current_page_item_count |
| 121 | + |
| 122 | + if current_page_item_count < cache_size: |
| 123 | + break |
| 124 | + |
68 | 125 |
|
69 | 126 | class RunCollectionClientAsync(ResourceClientAsync): |
70 | 127 | """Async sub-client for listing Actor runs.""" |
@@ -118,3 +175,60 @@ async def list( |
118 | 175 | ) |
119 | 176 | response_as_dict = response_to_dict(response) |
120 | 177 | return GetListOfRunsResponse.model_validate(response_as_dict).data |
| 178 | + |
| 179 | + async def iterate( |
| 180 | + self, |
| 181 | + *, |
| 182 | + limit: int | None = None, |
| 183 | + desc: bool | None = None, |
| 184 | + status: ActorJobStatus | list[ActorJobStatus] | None = None, # ty: ignore[invalid-type-form] |
| 185 | + started_before: str | datetime | None = None, |
| 186 | + started_after: str | datetime | None = None, |
| 187 | + ) -> AsyncIterator[RunShort]: |
| 188 | + """Iterate over all Actor runs. |
| 189 | +
|
| 190 | + Iterate over all Actor runs, either of a single Actor, or all user's Actors, depending on where this client |
| 191 | + was initialized from. |
| 192 | +
|
| 193 | + https://docs.apify.com/api/v2#/reference/actors/run-collection/get-list-of-runs |
| 194 | + https://docs.apify.com/api/v2#/reference/actor-runs/run-collection/get-user-runs-list |
| 195 | +
|
| 196 | + Args: |
| 197 | + limit: Maximum number of runs to return. By default there is no limit. |
| 198 | + desc: Whether to sort the runs in descending order based on their start date. |
| 199 | + status: Retrieve only runs with the provided statuses. |
| 200 | + started_before: Only return runs started before this date (inclusive). |
| 201 | + started_after: Only return runs started after this date (inclusive). |
| 202 | +
|
| 203 | + Yields: |
| 204 | + A run from the collection. |
| 205 | + """ |
| 206 | + cache_size = 1000 |
| 207 | + read_items = 0 |
| 208 | + offset = 0 |
| 209 | + |
| 210 | + while True: |
| 211 | + effective_limit = cache_size |
| 212 | + if limit is not None: |
| 213 | + if read_items == limit: |
| 214 | + break |
| 215 | + effective_limit = min(cache_size, limit - read_items) |
| 216 | + |
| 217 | + current_page = await self.list( |
| 218 | + limit=effective_limit, |
| 219 | + offset=offset, |
| 220 | + desc=desc, |
| 221 | + status=status, |
| 222 | + started_before=started_before, |
| 223 | + started_after=started_after, |
| 224 | + ) |
| 225 | + |
| 226 | + for item in current_page.items: |
| 227 | + yield item |
| 228 | + |
| 229 | + current_page_item_count = len(current_page.items) |
| 230 | + read_items += current_page_item_count |
| 231 | + offset += current_page_item_count |
| 232 | + |
| 233 | + if current_page_item_count < cache_size: |
| 234 | + break |
0 commit comments