Skip to content

Latest commit

 

History

History
44 lines (26 loc) · 3.12 KB

.rules.md

File metadata and controls

44 lines (26 loc) · 3.12 KB

Coding guidelines

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

Architecture

Client hierarchy

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.

Sync/async symmetry

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).

HTTP layer

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.

Generated models

_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.

Checking API response shapes

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_*_FIELDS in src/packages/<area>-server/src/<resource>/<resource>.server.ts.
  • A list endpoint has its own, usually smaller, API_PUBLISHED_*_LIST_FIELDS in src/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.