This file provides guidance to programming agents when working with code in this repository.
Python client for the Apify API, published on PyPI as apify-client. ApifyClient (sync) and ApifyClientAsync (async) are the entry points.
Read CONTRIBUTING.md first. It covers setup, tasks, tests, code style, generated models, documentation, and commits, and all of it applies to agents too.
@CONTRIBUTING.md
Entry points return resource sub-clients, which can create child clients (e.g. ActorClient.builds() -> BuildCollectionClient):
ApifyClient
├── .actor(id) → ActorClient (single resource operations)
├── .actors() → ActorCollectionClient (list/create)
├── .run(id) → RunClient
└── ... (datasets, schedules, tasks, webhooks, key-value stores, request queues, etc.)
ClientRegistry / ClientRegistryAsync (_client_registry.py) hold the resource client classes and are passed to every client, so clients can create child clients without importing them (avoids circular imports). All resource clients derive from ResourceClientBase (_resource_clients/_resource_client.py), whose WithLogDetailsClient metaclass wraps public methods for structured logging.
Every resource client in src/apify_client/_resource_clients/ has its sync and async variant in the same file (e.g. ActorClient and ActorClientAsync in actor.py) with the same interface. Docstrings are written on the sync client only (see Documentation).
HttpClient / HttpClientAsync (http_clients/_base.py) hold the shared request pipeline (retries, timeouts, API errors); transports (Impit* default, Httpx2* behind the httpx2 extra, or a custom one via ApifyClient.with_custom_http_client()) implement sending, error classification, and lifecycle hooks. Request-body compression lives in http_compressors/, selected by the compression constructor argument.
_models.py, _typeddicts.py, and _literals.py are generated; never edit them by hand (see Generated models). Each input-side TypedDict ships in a snake_case and a camelCase variant (RequestResourceDict, RequestResourceCamelDict); the camel variants are synthesized in the post-processing script, and resource-client signatures accept either casing or the Pydantic model.
The OpenAPI spec can lag behind the API and omit fields, and a live response only shows the fields that happen to be set. If the private apify-core repository is available locally, use it to confirm which fields an endpoint returns:
- A single resource's fields are in
PUBLISHED_*_FIELDSinsrc/packages/<area>-server/src/<resource>/<resource>.server.ts. - A list endpoint has its own, usually smaller,
API_PUBLISHED_*_LIST_FIELDSinsrc/api/src/routes/<resource>/<resource>_list.ts, and often builds each item inline. Don't assume a list item has the same fields as the single resource.