From 6f2c2000aa95c3c4ed28b37b3ef843b0465e0edd Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 7 Jul 2026 23:56:49 +0000 Subject: [PATCH] chore: sync PHP client with Apify OpenAPI spec v2-2026-07-07T132551Z - Bump API_SPEC_VERSION to v2-2026-07-07T132551Z and CLIENT_VERSION to 0.1.1. - Correct LastRunOptions origin doc comment: origin is now a spec-declared query parameter on the last-run endpoints. - Documentation improvements (StreamInterface/exception/transport notes, PSR-18 usage, runs.md list() defaults, config units). --- CHANGELOG.md | 7 +++++++ README.md | 27 ++++++++++++++++++++++++--- docs/README.md | 4 ++++ docs/runs.md | 14 +++++++++++++- src/Options/LastRunOptions.php | 6 +++--- src/Version.php | 4 ++-- 6 files changed, 53 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 69fccf7..558a0ed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## 0.1.1 + +- Synced to Apify OpenAPI spec `v2-2026-07-07T132551Z`. No public interface changes. +- `origin` is now a spec-declared query parameter on the last-run endpoints; corrected the + `LastRunOptions` doc comment accordingly (behavior unchanged). Kept parity with the reference + client, which does not expose `waitForFinish` on `lastRun`. + ## 0.1.0 - Initial PHP client for the Apify API (spec `v2-2026-07-02T131926Z`). diff --git a/README.md b/README.md index defae34..eb8fdce 100644 --- a/README.md +++ b/README.md @@ -64,7 +64,7 @@ $configured = new ApifyClient( | `publicBaseUrl` | `baseUrl` | Base URL used when building public, shareable resource URLs. | | `maxRetries` | `8` | Maximum retries for failed requests. | | `minDelayBetweenRetriesMillis` | `500` | Minimum delay between retries (exponential backoff). | -| `maxDelayBetweenRetriesMillis` | request timeout | Upper bound on the growing inter-retry delay. | +| `maxDelayBetweenRetriesMillis` | `timeoutSecs × 1000` (360000) | Upper bound (milliseconds) on the growing inter-retry delay; defaults to the request timeout expressed in milliseconds. | | `timeoutSecs` | `360` | Overall per-request timeout. | | `userAgentSuffix` | `null` | Custom suffix appended to the `User-Agent` header. | | `httpClient` | Guzzle | The replaceable transport (`Apify\Client\Http\HttpClientInterface`). | @@ -79,14 +79,19 @@ can wrap any [PSR-18](https://www.php-fig.org/psr/psr-18/) client with `Psr18Htt your own implementation: ```php +// Use the default Guzzle transport explicitly. $client = new ApifyClient(token: 'my-api-token', httpClient: new GuzzleHttpClient()); + +// Or wrap any PSR-18 client (configure its proxy/TLS/timeout on the wrapped client, since +// PSR-18 has no per-request timeout and Psr18HttpClient ignores the client's timeoutSecs). +$psr18 = new \GuzzleHttp\Client(['timeout' => 120]); // any Psr\Http\Message ClientInterface +$client = new ApifyClient(token: 'my-api-token', httpClient: new Psr18HttpClient($psr18)); ``` ## Error handling Methods that fetch a single resource return `null` when the resource does not exist (rather than -throwing). Other API failures are thrown as `Apify\Client\Exception\ApifyApiException`, which exposes -the HTTP status, API error `type`, message, attempt count, and request method/path: +throwing). Other API failures are thrown as `Apify\Client\Exception\ApifyApiException`: ```php try { @@ -96,6 +101,22 @@ try { } ``` +`ApifyApiException` extends `RuntimeException` and exposes: + +| Accessor | Returns | +|---|---| +| `getStatusCode(): int` | HTTP status code of the error response. | +| `getType(): ?string` | Machine-readable API error type (e.g. `"record-not-found"`). | +| `getApiMessage(): string` | Raw API error message, without the status/type prefix. | +| `getMessage(): string` | Formatted message (`apify API error (status …, type …): …`), from `Throwable`. | +| `getAttempt(): int` | 1-based number of the request attempt that produced the error. | +| `getHttpMethod(): string` | HTTP method of the failed call (e.g. `"GET"`). | +| `getPath(): string` | Path of the API endpoint (URL excluding origin). | +| `getData(): ?array` | Additional structured error data provided by the API, if any. | + +Transport-level failures (network errors, timeouts) are retried internally; only if every retry is +exhausted does the underlying error surface. Requests are retried on network errors, HTTP 429 and 5xx. + ## Versioning - `Apify\Client\Version::CLIENT_VERSION` — the semantic version of this library. diff --git a/docs/README.md b/docs/README.md index ee9cea5..f480b7e 100644 --- a/docs/README.md +++ b/docs/README.md @@ -35,6 +35,10 @@ use Apify\Client\Model\RequestQueueRequest; use Apify\Client\Options\BatchAddRequestsOptions; ``` +The streaming-log accessors (`LogClient::stream()` and `RunClient::getStreamedLog()`) return the +PSR-7 `Psr\Http\Message\StreamInterface` (from the `psr/http-message` package), not an +`Apify\Client\` type — import it as `use Psr\Http\Message\StreamInterface;`. + Methods that fetch a single resource return `null` when the resource does not exist, rather than throwing. API failures are thrown as `ApifyApiException` (see [error handling](../README.md#error-handling)). diff --git a/docs/runs.md b/docs/runs.md index 9315316..56013b6 100644 --- a/docs/runs.md +++ b/docs/runs.md @@ -4,7 +4,7 @@ Snippets assume `$client = new ApifyClient('my-api-token');` and imported types. ## Run collection — `$client->runs()` -- `list(?ListOptions $options, ?RunListOptions $filter): PaginationList` — list runs. +- `list(?ListOptions $options = null, ?RunListOptions $filter = null): PaginationList` — list runs. ```php $page = $client->runs()->list(new ListOptions(limit: 10), new RunListOptions(status: ['SUCCEEDED'])); @@ -31,3 +31,15 @@ $run = $client->run('RUN_ID')->waitForFinish(120); $client->run('RUN_ID')->charge(new RunChargeOptions(eventName: 'result', count: 3)); $items = $client->run('RUN_ID')->dataset()->listItems(); ``` + +### `waitForFinish` — two distinct meanings + +`waitForFinish` appears in two different roles; do not confuse them: + +- **`waitForFinish(?int $waitSecs = null)`** — the client-side helper method (on runs and builds). It + polls until the run/build reaches a terminal state, transparently issuing repeated server-side + waits. `$waitSecs` is the total budget in seconds and is **not** capped; `null` waits indefinitely. + For instance, `waitForFinish(300)` waits up to five minutes. +- **The server-side `waitForFinish` parameter** — `get(?int $waitForFinishSecs = null)` (and + `defaultBuild()`) and the `waitForFinish` field on `*Options` (e.g. `ActorStartOptions`). This is a + single API-side wait and the server caps it at 60 seconds, so the client clamps larger values. diff --git a/src/Options/LastRunOptions.php b/src/Options/LastRunOptions.php index 25750ba..1e25c35 100644 --- a/src/Options/LastRunOptions.php +++ b/src/Options/LastRunOptions.php @@ -8,9 +8,9 @@ * Filters which "last" run the last-run accessors resolve to. Leave a field {@code null} to leave * that filter unset. * - * {@code origin} is an Apify-platform convenience exposed by the reference client but not documented - * as a query parameter in the OpenAPI spec; it is included for parity, threaded to the same - * {@code runs/last} endpoint. + * {@code origin} is a query parameter declared on the {@code runs/last} endpoints in the OpenAPI + * spec (alongside {@code status}); it is threaded to that endpoint, matching the reference client's + * {@code lastRun({ status, origin })}. */ final class LastRunOptions { diff --git a/src/Version.php b/src/Version.php index a3150f7..51b6020 100644 --- a/src/Version.php +++ b/src/Version.php @@ -17,13 +17,13 @@ final class Version * The semantic version of this client library (see https://semver.org/). * Changes to the public interface other than additive ones are considered breaking changes. */ - public const CLIENT_VERSION = '0.1.0'; + public const CLIENT_VERSION = '0.1.1'; /** * The version of the Apify OpenAPI specification this client was generated and verified * against. Corresponds to the {@code info.version} field of the Apify OpenAPI document. */ - public const API_SPEC_VERSION = 'v2-2026-07-02T131926Z'; + public const API_SPEC_VERSION = 'v2-2026-07-07T132551Z'; private function __construct() {