feat: sync Rust client with Apify OpenAPI spec v2-2026-07-10T105921Z; add lazy pagination iterators - #17
Merged
Merged
Conversation
Bumps API_SPEC_VERSION to v2-2026-07-10T105921Z and crate version to 0.5.1. The spec delta (added 401/402 error responses and relaxed field nullability/optionality) requires no code change: errors are handled generically and response models are forward-compatible. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019rkZYoebybdnv7MFH9Ua6E
Adds a shared generic ListIterator<T> (src/clients/pagination.rs, exported at the crate root) and an iterate() method on every collection client the reference JS client iterates: actors, actor versions, env vars, builds, runs, datasets, key-value stores, request queues, schedules, tasks, webhooks, webhook dispatches, plus DatasetClient::iterate_items(). Store iteration is refactored onto the shared iterator (StoreActorIterator kept as a type alias). Termination is short-page based, robust to the dataset-items endpoint reporting total=0. Adds one item-iteration integration test per collection and corrects the src/models.rs module doc. Minor version bump to 0.6.0. Addresses review items in notes.md (iteration helpers, iteration tests, module-doc accuracy). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019rkZYoebybdnv7MFH9Ua6E
Addresses staff-review nits from notes.md: - Add ListIterator::new_single_page for non-paginated endpoints (env-vars), removing the reliance on the API omitting a page limit. - Reword pagination.rs module doc to drop the task/requirements reference. - Add token-free unit tests covering all ListIterator termination branches (short-page, total=0, empty-page, reached_total early-stop, caller offset, single-page); tests exercise collect_all as their drain path. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019rkZYoebybdnv7MFH9Ua6E
…se.rs comment Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019rkZYoebybdnv7MFH9Ua6E
…page truncation - ListIterator: limit is now a total-item cap; page size set via with_chunk_size, matching the reference _listPaginatedFromCallback (total-driven termination). - iterate_items no longer truncates when skip_empty/clean/skip_hidden shorten a non-final page (short-page detection confined to the total==0 case). - Corrected misleading limit-as-page-size docs (pagination.rs, dataset.rs, docs/README.md). - Added hermetic unit tests for non-final short pages and total-cap behaviour. - README: bump apify-client 0.5 -> 0.6 to match Cargo.toml. - Iteration integration tests use with_chunk_size for page size (limit unset). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019rkZYoebybdnv7MFH9Ua6E
Migrate the last iteration test off limit-as-page-size (now a total cap) so its seen>=12 break is reachable and it exercises page-crossing, matching siblings. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019rkZYoebybdnv7MFH9Ua6E
Address 5 open review items (behaviour unchanged; reference-consistent): - iterate_items docstring now describes real offset-advance behaviour (may re-yield filtered items), matching the reference JS client, instead of overpromising filters are honoured without truncation. - Reword non_final_short_page test comment: it guards termination logic, not filter de-duplication. - Add cap_truncates_page_that_exceeds_remaining_budget test for the received > remaining truncation branch. - README timestamp prose: Option<chrono::DateTime<Utc>>. - docs/README imports list: add ListIterator (a return type). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019rkZYoebybdnv7MFH9Ua6E
…er; extract iterate boilerplate - Document on all 11 collection iterate() methods that options.limit is a total-item cap (page size via with_chunk_size), pointing to ListIterator. - list_items reports total=0 (not count) when the pagination-total header is absent, so iterate_items no longer falsely terminates after page 1; add a hermetic header-less test in unit_http.rs. - Remove orphaned historical narration from a pagination test comment. - Extract the duplicated iterate() closure into a crate-internal list_iterator! macro used by the 10 uniform collections (run/dataset-items/env-var keep their explicit bodies). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019rkZYoebybdnv7MFH9Ua6E
…ollection Completes the previous commit: task_collection was the 12th option-taking collection and was missed by both the doc note (item 1) and the macro extraction (item 4). All 11 uniform collections now use list_iterator!. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019rkZYoebybdnv7MFH9Ua6E
…or docs Adds KeyValueStoreClient::iterate_keys with a cursor-based KeyValueStoreKeysIterator (exclusiveStartKey/nextExclusiveStartKey), matching the JS reference listKeys() async-iterable. Adds an integration test and hermetic MockBackend coverage for the list_iterator! macro wiring, RunCollectionClient::iterate, and the new key iterator. Reconciles the StoreActorIterator/ListIterator docs, adds iterate()/iterate_items()/iterate_keys() to the per-resource tables, documents with_chunk_size on the Store page, adds a large-cap first-page doc note, and clarifies StoreListOptions.limit. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019rkZYoebybdnv7MFH9Ua6E
…ors, doc polish Derives every iterate_keys page request limit from the remaining budget clamped to a documented KEY_LIST_MAX_LIMIT (1000), so limit=0 means uncapped and a large finite cap paginates instead of sending an out-of-range limit. Adds a defensive cap-truncation guard, drops the unused collect_all, and re-exports KeyValueStoreKeysIterator and RequestQueueRequestsIterator at the crate root. Adds hermetic zero-limit and large-cap tests, a KeyValueStoreKey docs field table, ListKeysOptions.limit dual-meaning callouts, and reworded CHANGELOG to disclose the store().iterate() limit semantic change. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019rkZYoebybdnv7MFH9Ua6E
… output Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019rkZYoebybdnv7MFH9Ua6E
…cs import list - iterate_keys now leads termination with the model's is_truncated flag (cursor presence retained as fallback), avoiding a wasted final fetch and matching model semantics. Adds hermetic test iterate_keys_stops_on_is_truncated_even_with_trailing_cursor. - Drop QueryParams from the docs crate-root import prose (no public API consumes a caller-built QueryParams); re-export left intact. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019rkZYoebybdnv7MFH9Ua6E
GET /v2/key-value-stores/{storeId}/records is not exposed by the reference
JS client, so per client_requirements it is out of scope. Remove get_records
and GetRecordsOptions (method, re-export, docs rows, integration test) and
record the removal in the changelog. Also correct the iterate_keys doc wording
to not claim it mirrors the reference generator's cursor loop.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019rkZYoebybdnv7MFH9Ua6E
…y iterator cap Address 3 open items from the independent full client review: - Document ApifyClient::set_status_message in docs/README.md + root README. - Add BuildClient::get_openapi_definition to the docs/builds.md method table. - Drop dead .max(0) clamp in the offset and KVS iterators (rem is provably > 0). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019rkZYoebybdnv7MFH9Ua6E
…rate() docs - Document the item-drop edge case (fully-filtered window -> empty page -> walk terminates) in iterate_items, alongside the existing duplicate case - Trim the verbose pagination-total unwrap_or(0) rationale comment to 3 lines - Add iterate() to the ActorVersion/ActorEnvVar collection tables in docs/actors.md to agree with docs/README.md and the code Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019rkZYoebybdnv7MFH9Ua6E
…xample, clean Option output Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019rkZYoebybdnv7MFH9Ua6E
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019rkZYoebybdnv7MFH9Ua6E
…sistency The iterate_key_value_stores integration test flaked on CI: a just-created key-value store was not yet reflected in the collection LIST endpoint when the test scanned the iterator once. This is eventual consistency, not a pagination or client bug. Add a bounded, shared test helper `iter_contains_eventually` that rebuilds the iterator and re-scans up to 5 times with a 500ms backoff (~2s budget), matching on the first attempt when the entity is already present (no-op in the common case). Use it for all 12 create-then-iterate collection assertions that share this race. Test-only change; no client runtime behaviour is affected. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019rkZYoebybdnv7MFH9Ua6E
Address flake-fix re-review: raise iter_contains_eventually retry budget from ~2s (5 x 500ms) to ~15s (16 x 1s) so it has real headroom above the ~10s propagation lag previously observed in this suite, instead of an unverified 2s guess that could let the flake recur at lower frequency. Consistent accounts still return on the first attempt with no sleeping. Also drop the concrete incident-test name from the docstring and de-duplicate the budget prose. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019rkZYoebybdnv7MFH9Ua6E
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Syncs the Rust client to Apify OpenAPI spec
v2-2026-07-10T105921Zand adds lazy pagination iterators across the client. Version bumped to0.6.0.Added
ListIterator<T>(exported at the crate root):iterate()on the actor, actor-version, env-var, build, run, dataset, key-value-store, request-queue, schedule, task, webhook, and webhook-dispatch collection clients, plusDatasetClient::iterate_items().options.limitcaps the total items yielded (matching the reference client);ListIterator::with_chunk_sizesets the per-request page size.KeyValueStoreClient::iterate_keys()returning a cursor-basedKeyValueStoreKeysIterator(auto-paginates keys viaexclusiveStartKey/nextExclusiveStartKey, mirroring the referencelistKeys()async-iterable).StoreActorIteratorat the crate root.Changed
API_SPEC_VERSIONtov2-2026-07-10T105921Z. The spec delta (added401/402error responses, relaxed field nullability) needs no functional change: errors are handled generically and response models are forward-compatible.StoreCollectionClient::iteratenow uses the sharedListIterator;store().iterate()'soptions.limitchanged from a per-page size to a total-item cap for consistency with the reference client (set page size viawith_chunk_size).StoreActorIteratoris now a type alias forListIterator<ActorStoreListItem>.ApifyClient::set_status_messageandBuildClient::get_openapi_definition.Removed
KeyValueStoreClient::get_recordsandGetRecordsOptions— theGET /v2/key-value-stores/{storeId}/recordsendpoint is not implemented by the reference JS client, so it is out of scope (corrects an earlier scope violation).Documentation
ActorStartOptionsfields (added the previously undocumentedrestart_on_error,force_permission_level,webhooks); listedJSONLin thedownload_itemsformat summary; made therun_store_actorexample resilient to Store ranking shifts.Test stability
tests/common), fixing an intermittentiterate_key_value_storesfailure. Test-only; no client runtime behaviour changed.See
CHANGELOG.mdfor the full[0.6.0]entry.