Open
Conversation
- Replace `httpx` http-clients with `impit`
- Move apify_client._errors to apify_client.errors ### Issues - Closes: #158
… `KeyValueStoreClient.get_record` (#463) - Remove deprecated parameters `as_bytes` and `as_file` from the `get_record` method in `KeyValueStoreClient`. This ensures consistency with `KeyValueStoreClientAsync`, where these parameters were previously removed from the method signature.
- Remove the `parse_response` parameter for the `call` method. It was only used to create the private attribute `_maybe_parsed_body` in `Response`. - The `_maybe_parsed_body` attribute has been removed; now the utility is called directly in Key-Value storage client, where it was used. ### Issues - Closes: #166
- Update "Upgrading to v2" guide --------- Co-authored-by: Vlada Dusek <v.dusek96@gmail.com>
…keys_public_url (#453) When storage resources (Datasets or Key-Value Stores) are set to Restricted, accessing or sharing their data externally becomes difficult due to limited permissions. This PR introduces functionality to generate signed URLs that allow controlled external access to these resources without adding token to the request. This PR introduces methods to generate signed URLs for Dataset items and Key-Value Store records: 1. **Datasets** `dataset(:datasetId).create_items_public_url(options, expires_in_millis)` → Returns a signed URL like: `/v2/datasets/:datasetId/items?signature=xxx` 2. Key-Value Stores `key_value_store(:storeId).create_keys_public_url(options, expires_in_millis)` → Returns a signed URL like: `/v2/key-value-stores/:storeId/keys?signature=xxx` 🕒 Expiration: The `expires_in_millis` parameter defines how long the signature is valid. - If provided, the URL will expire after the specified time. - If omitted, the URL will never expire. Note 1: The signature is included only if the token has WRITE access to the storage. Otherwise, an unsigned URL is returned. P.S. We're not yet exposing `urlSigningSecretKey` for datasets, it will be released after [PR](https://github.com/apify/apify-core/pull/22173) is merged. [More context here](https://www.notion.so/apify/Signed-Dataset-Items-KV-store-record-URLs-224f39950a2280158a6bd82bc2e2ebb5?source=copy_link) Same PR in JS apify/apify-client-js#720
## Summary - Bump minimum Python version from 3.10 to 3.11 - Update `pyproject.toml` (`requires-python`, classifiers, `ty` and `datamodel-codegen` target versions) - Remove Python 3.10 from CI matrices (unit tests, integration tests, lint, type check) - Update documentation (`README.md`, `CONTRIBUTING.md`, overview docs, upgrade guide) - Apply Python 3.11+ lint fixes: `datetime.UTC` alias, `StrEnum`, import `Self`/`overload` from `typing`, `fromisoformat` Z-suffix support - Regenerate `uv.lock` (removes `backports-asyncio-runner` and `exceptiongroup` backports) Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
## Summary - Removes `apify-shared` from the docs build pipeline — it is no longer a dependency of `apify-client-python` - Removes cloning of `apify-shared-python` repo and its docspec dump generation from `build_api_reference.sh` - Removes `apify_shared` references from `transformDocs.js` (repo URL, version detection, docspec merging) - Removes `apify_shared` from the module list in `generate_module_shortcuts.py` Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
## Summary - The `_get_finished_run_id` helper in webhook tests asserted that at least one SUCCEEDED run of `apify/hello-world` already exists, but this is not guaranteed (runs can be cleaned up between test runs) - Instead of failing with an assertion error, the helper now falls back to starting a new hello-world actor run via `.call()` (which waits for completion) when no completed runs are found - Fixes the flaky `test_webhook_test[async]` failure seen in CI: https://github.com/apify/apify-client-python/actions/runs/22345359592/job/64658461897?pr=639 Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
## Summary - Replace manual task management (`create_task` + `cancel` + `gather`) with `asyncio.TaskGroup` in `RequestQueueClientAsync.batch_add_requests` for better error propagation and automatic cleanup - Update docs example (`02_tasks_async.py`) to use `asyncio.TaskGroup` instead of `asyncio.gather` - `StreamedLogAsync` and `StatusMessageWatcherAsync` left unchanged — `TaskGroup` doesn't fit their `start()`/`stop()` lifecycle pattern and adds no benefit for single-task cases ## Issue - Closes #598 Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
## Summary - Introduces the `@docs_group()` decorator (following the crawlee-python pattern) to organize all public symbols into clear documentation groups: **Apify API clients**, **Resource clients**, **HTTP clients**, **Models**, and **Errors** - Applies the decorator to all 260+ public classes across the codebase (2 API clients, 61 resource clients, 192 models, 2 HTTP clients, 3 errors) - Updates `website/transformDocs.js` to read group assignments from the decorator instead of hardcoded JS predicates - Improves and polishes all docstrings for Apify API clients, Resource clients, HTTP clients, and Errors with consistent patterns and helpful context ## Screenshot <img width="2880" height="6778" alt="image" src="https://github.com/user-attachments/assets/b4b101e8-6a6d-47a4-b096-04eff0267460" /> ## Issues - Closes: #637 ## Test plan - [x] CI passes 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
## Summary - Introduce `HttpClient` and `HttpClientAsync` ABCs that users can extend to provide custom HTTP client implementations via `ApifyClient(http_client=...)` and `ApifyClientAsync(http_client=...)` - Factor impit-specific logic into `ImpitHttpClient`/`ImpitHttpClientAsync`, keeping `_base.py` free of any `impit` dependency - Add `HttpResponse` protocol with full streaming support (`iter_bytes`, `aiter_bytes`, `read`, `aread`, `close`, `aclose`) - Export all public types (`HttpClient`, `HttpClientAsync`, `HttpResponse`, `ImpitHttpClient`, `ImpitHttpClientAsync`) from `apify_client` ## Issue - Closes: #416 Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
…ments (#648) ## Summary - Replace the `kwargs.pop('resource_path', ...)` anti-pattern with proper keyword arguments in all resource client `__init__` methods. - Improves type safety, readability, and IDE support across 22 files (44 sync/async class pairs). - Special handling for `UserClient` (`resource_id: str | None = None`, resolved to `'me'`) and `RequestQueueClient` (retains extra `client_key` param). Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
## Summary - Add `.rules.md` file containing project conventions and coding guidelines - Create `AGENTS.md`, `CLAUDE.md`, and `GEMINI.md` as symlinks pointing to `.rules.md` - Update `.gitignore` accordingly Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
…650) ## Summary - Replace hand-written `_representations.py` helper functions (302 lines deleted) with Pydantic request models (`UpdateActorRequest`, `ScheduleCreate`, `WebhookCreate`, `WebhookUpdate`, etc.) for constructing API payloads. - Simplify `_update()` / `_create()` in `ResourceClient` to accept `**kwargs` and use a new `_clean_json_payload()` static method on `ResourceClientBase` instead of the removed `filter_none_values()` utility. - Remove unused `enum_to_value()` and `filter_none_values()` from `_utils.py` — Pydantic serialization handles enum conversion and `None` filtering. - Add `populate_by_name=True` to all generated Pydantic model configs via `datamodel-codegen` configuration, so models can be initialized using either `snake_case` field names or `camelCase` aliases. - Models had to be adjusted, see PR to apify-docs - apify/apify-docs#2291. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Vlada Dusek <v.dusek96@gmail.com>
## Summary - Add patch coverage target at 50% - Set both project and patch status checks to informational mode so they report coverage but never block CI Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
## Summary - Restructured documentation from flat structure to numbered hierarchical organization (`01_introduction`, `02_concepts`, `03_guides`), matching the pattern used in [apify-client-js#850](apify/apify-client-js#850) - Renamed `01_overview` to `01_introduction` with simplified overview and separate quick start page - Renamed `03_examples` to `03_guides` - Simplified overview page by removing content duplicated in the quick start guide (authentication, running Actors, providing input, getting results) - Updated sidebar, docusaurus config, and landing page redirect 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
## Summary - Basically documenting #416. ## Description - Add concept page documenting the pluggable HTTP client architecture (default client config, abstract base classes, `HttpResponse` protocol, `call` method parameters) - Add guide page with step-by-step HTTPX implementation example (sync + async) - Add `ApiLink` component for linking to API reference from docs Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
## Summary - Inline integration tests in the CI workflow instead of calling the reusable workflow to avoid GitHub's compile-time secret validation for nested reusable workflows, which fails on fork PRs where repo secrets are not available - Add `workflow_dispatch` to the integration tests condition - Remove unnecessary `secrets: inherit` from unit tests This follows the same pattern as in the Python SDK: https://github.com/apify/apify-sdk-python/blob/master/.github/workflows/_tests.yaml ## Test plan - [x] Verify the workflow syntax is valid - [x] Integration tests should run on PRs from the `apify` org, pushes to `master`, and manual triggers - [x] Integration tests should be skipped on fork PRs 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
#653) ## Summary - Introduce three (four with max) configurable timeout tiers: - `short` (5s by default), - `medium` (30s by default), - `long` (360s by default), - and `max` (360s cap by default). - Introduce `Timeout` type alias: `timedelta | Literal['no_timeout', 'short', 'medium', 'long']` - Keep the exponential timeout growth per retry attempt (doubles each retry, capped at `timeout_max`). - The default timeout tiers were kept as they were (let's adjust them later in a dedicated PR). - Reduce default max retries from 8 to 4 (5 attempts by default). - Rename `_internal_models.py` to `_types.py` and consolidate type aliases (`Timeout`, `JsonSerializable`) into it. - Remove old timeout constants (`FAST_OPERATION_TIMEOUT`, `STANDARD_OPERATION_TIMEOUT`). ## Timeout tiers | Tier | Default | Usage | |------|---------|-------| | `short` | 5s | 16 methods (only in storage clients) | | `medium` | 30s | 7 methods (only in storage clients) | | `long` | 360s | 150+ (all the others) | | `no_timeout` | — | It is not used by default | | `max` | 360s | Cap for exponential timeout growth across retries | Let's discuss the best defaults later in a dedicated PR. ## What this solves - Before this change, timeout handling across the client was fragmented and inconsistent in three major ways: - Some resource clients had hardcoded internal timeouts. - Users had no way to control per-request timeouts. - The timeout parameter name was ambiguous on Actor/Task run methods. ## Test plan - [x] CI passes
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.
No description provided.