Skip to content

feat: add PHP client for the Apify API (spec v2-2026-07-02T131926Z)#1

Merged
Pijukatel merged 7 commits into
masterfrom
claude/serene-thompson-7s05ro
Jul 5, 2026
Merged

feat: add PHP client for the Apify API (spec v2-2026-07-02T131926Z)#1
Pijukatel merged 7 commits into
masterfrom
claude/serene-thompson-7s05ro

Conversation

@Pijukatel

Copy link
Copy Markdown
Collaborator

Summary

Adds the official (experimental, AI-generated and AI-maintained) PHP client for the Apify API, built from scratch and verified against OpenAPI specification v2-2026-07-01T115402Z. Idiomatic PHP 8.1+ (PSR-4 Apify\Client\, PSR-12); the public interface mirrors the JavaScript reference client and is consistent with the Java/Rust/Go siblings.

What's included

  • Resource-oriented ApifyClient with accessors for Actors (+ versions & env vars), builds, runs, datasets, key-value stores, request queues, tasks, schedules, webhooks, webhook dispatches, the Apify Store, users, and logs, plus setStatusMessage and actor validateInput.
  • Replaceable HTTP transport via Http\HttpClientInterface (default GuzzleHttpClient, plus a Psr18HttpClient adapter for any PSR-18 client).
  • Cross-cutting behaviour on every call: bearer auth, the mandated User-Agent, exponential-backoff-with-jitter retries (429/5xx/transport) with a growing-but-capped per-attempt timeout, and 404 → null on single-resource GETs.
  • Convenience helpers matching the reference client: actor(...)->call/task(...)->call, waitForFinish, defaultBuild, metamorph/reboot/resurrect/charge, run-nested storages, lazy store()->iterate() and requestQueue(...)->paginateRequests(), dataset download/statistics/public URLs, key-value-store record & key-list public URLs with HMAC-SHA256 signing, and request-queue batch add with uniqueKey validation and payload-size-bounded chunking.
  • Public Version constants; models capture unmodelled API fields for forward compatibility.

Tests, docs & CI

  • Unit tests (mock transport: auth/UA, envelope, 404→null, retries, error parsing, batch chunking & retry semantics, signature known-answer vectors), a live integration suite (one GET + one CRUD/complex flow per resource), runnable documentation examples with a snippet linter.
  • docs/ reference for every resource (with namespace guidance and a fully runnable program), CHANGELOG.md, README.
  • Quality gates: php-cs-fixer (PSR-12) and PHPStan (level 6).
  • GitHub Actions: PHP integration tests (lint + static analysis + unit + integration + Test examples, path-filtered PR-to-master + manual dispatch, APIFY_TOKEN guard) and a manual Publish PHP client workflow (tag + GitHub release + Packagist notify from repo secrets).

Verification

  • php-cs-fixer — 0 issues (118 files)
  • phpunit — unit 41, examples 42, integration 42 (live, APIFY_TOKEN set), 0 failures
  • PHPStan (level 6) is wired as a required CI gate.

Scope notes

  • Endpoint scope tracks the JS reference; for in-scope endpoints all OpenAPI parameters are covered (e.g. store allowsAgenticUsers/responseFormat, monthlyUsage(date)).
  • Nested actor/task webhooks() are read-only, matching the spec (those nested endpoints are GET-only).

Generated by Claude Code

claude added 5 commits July 3, 2026 14:03
Bespoke, idiomatic PHP 8.1+ client (PSR-4 Apify\Client, PSR-12) mirroring
the reference JS client: resource clients for actors (+versions, env vars),
builds, runs, datasets, key-value stores, request queues, tasks, schedules,
webhooks, dispatches, store, users and logs, plus setStatusMessage and
actor validateInput. Replaceable transport (Guzzle default + PSR-18 adapter),
bearer auth, mandated User-Agent, exponential-backoff retries, 404->null,
HMAC storage URL signing, and byte-size-bounded batch request add with
uniqueKey validation.

Includes unit tests (mock transport), live integration tests, runnable
documentation examples with a snippet linter, php-cs-fixer (PSR-12) and
PHPStan gates, and CI workflows for integration tests and Packagist
publishing.
The committed lock resolved php-cs-fixer's Symfony dependencies to v8.x
(requires PHP 8.4.1+) because it was generated on PHP 8.4, but composer.json
declares php >=8.1 and CI runs on PHP 8.1, so composer install failed.
Pin config.platform.php to 8.1.0 and regenerate the lock (Symfony 6.4.x).
RunClient stored an ApifyClient $root it never read (PHPStan: 'never read,
only written'). Drop the constructor parameter and import and the argument
at the three call sites; ActorClient/TaskClient keep their own $root, which
they use for waitForFinish.
…ccessors

The run-nested dataset/key-value-store/request-queue/log accessors created
fresh contexts with empty base params, dropping the status/origin filters
pinned by ActorClient::lastRun()/TaskClient::lastRun(). DatasetClient
listItems/downloadItems/pushItems also bypassed mergedParams. Both are now
routed through the inherited base params, matching the apify-client-js
reference (sub-resources inherit params via _subResourceOptions/_params).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019etuGDSwcjs4DKuCd4MKKe
…lt, docs, phpstan tests)

- Remove dead/misleading BatchAddRequestsOptions::maxParallel (+constant): the
  synchronous client sends batches sequentially, so the knob had no effect.
- ActorClient::defaultBuild now clamps waitForFinish via ctx->clampServerWait,
  consistent with run/build get() (avoids socket abort under a short timeout).
- GetRecordOptions defaults attachment=true (matches JS which always sends it),
  so a caller-supplied options object no longer silently drops the param.
- Remove dead QueryParams::isEmpty(); drop cross-class DatasetClient::extractString
  helper in favor of ApifyResource::get() + inline is_string at the 3 call sites.
- docs/storages.md: request-queue getOrCreate takes only a name (no schema).
- phpstan.neon.dist: type-check tests/ too. CHANGELOG notes last-run param propagation.
- Tests: new RequestShapeTest::testDefaultBuildClampsWaitToPerRequestTimeout.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019etuGDSwcjs4DKuCd4MKKe
@Pijukatel Pijukatel changed the title feat: add PHP client for the Apify API (spec v2-2026-07-01T115402Z) feat: add PHP client for the Apify API (spec v2-2026-07-02T131926Z) Jul 4, 2026
claude added 2 commits July 4, 2026 19:23
Match the Java/Rust/Go sibling clients and the orchestration PR (the spec
rolled to 07-02 with a zero diff while this client was generated; pin the
same value across all clients for consistency).
…ive log-redirect example; spec v2-2026-07-02T131926Z

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017sJGjCxFP3bpbeF4LsVqK3
@Pijukatel Pijukatel merged commit 1e45317 into master Jul 5, 2026
2 checks passed
@Pijukatel Pijukatel deleted the claude/serene-thompson-7s05ro branch July 8, 2026 09:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants