Skip to content

Latest commit

 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

README.md

Apify Rust client — documentation

Official, but experimental — AI-generated and AI-maintained. This is an official Apify client, but it is experimental: it is generated and maintained by AI. Review the code before relying on it in production and report issues on the repository.

This directory documents the public API of the Apify Rust client. The same descriptions are available as rustdoc comments and can be browsed with cargo doc --open.

Note: the cross-file links between these pages (e.g. to actors.md, runs.md, or ../examples/) are written for the repository (GitHub) view. Because the pages are concatenated onto the crate root via include_str! when building rustdoc, those relative links do not resolve in cargo doc output — read the cross-references on GitHub.

Contents

Getting started

Add the crate and an async runtime:

[dependencies]
apify-client = "0.6"
tokio = { version = "1", features = ["macros", "rt-multi-thread"] }

Some snippets and examples need extra crates: add serde_json = "1" when you read dynamically-typed responses as serde_json::Value (as the README Quick start does), futures-util = "0.3" to consume LogClient::stream() (log streaming — see Store, users and logs), and chrono = "0.4" if you construct or read timestamp values yourself (model timestamp fields are chrono::DateTime<Utc> and chrono is not re-exported, so snippets calling chrono::Utc::now() — such as the monthly_usage and account examples — need it as a direct dependency).

Create a client and call a resource:

use apify_client::ApifyClient;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = ApifyClient::new("my-api-token");
    let user = client.me().get().await?.expect("account");
    println!("Logged in as {}", user.username.as_deref().unwrap_or("(none)"));
    Ok(())
}

ApifyClient::new takes the API token as an argument — the client does not read it from the environment for you. By convention the token is kept in the APIFY_TOKEN environment variable (this is what every example in examples/ reads, and what the integration-test suite and the Apify platform use), so production code typically does ApifyClient::new(std::env::var("APIFY_TOKEN")?). The literal "my-api-token" above is only a placeholder for brevity.

Imports

The client, the builder, and every option/parameter struct are re-exported at the crate root, so you can import them directly from apify_client — you never need the longer apify_client::clients::<module>::<Type> path. The complete set of re-exported option/parameter types is:

  • Actors: ActorStartOptions, ActorBuildOptions, ActorListOptions
  • Runs: RunListOptions, RunResurrectOptions, RunMetamorphOptions, RunChargeOptions, LastRunOptions
  • Datasets: DatasetListItemsOptions, DatasetDownloadOptions, DownloadItemsFormat
  • Key-value stores: ListKeysOptions, GetRecordOptions
  • Request queues: ListRequestsOptions
  • Store: StoreListOptions
  • Logs: LogOptions
  • Shared: ListOptions, StorageListOptions
  • Client configuration: RequestCompression

plus the common container PaginationList, ListIterator (the return type of every collection client's iterate() method), StoreActorIterator (a type alias for ListIterator<ActorStoreListItem>, the return type of StoreCollectionClient::iterate), and the two cursor-based iterators KeyValueStoreKeysIterator (from KeyValueStoreClient::iterate_keys) and RequestQueueRequestsIterator (from RequestQueueClient::paginate_requests). Import any of them directly from apify_client:

use apify_client::{ApifyClient, ActorListOptions, StoreListOptions, DownloadItemsFormat};

(The apify_client::clients::<module>::<Type> paths shown by cargo doc's module tree also work, but the short crate-root path above is the supported, stable way to import these option types.)

API resource/response models (Actor, ActorRun, Build, Dataset, KeyValueStore, KeyValueStoreKey, KeyValueStoreKeysPage, KeyValueStoreRecord, RequestQueue, RequestQueueRequest, RequestQueueHead, RequestQueueOperationInfo, Task, Schedule, Webhook, WebhookDispatch, ActorStoreListItem, User, …) all live in the apify_client::models module and are imported from there:

use apify_client::models::RequestQueueRequest;

Every model exposes an extra: Extra field that captures any response fields not otherwise modelled; Extra is a type alias for std::collections::HashMap<String, serde_json::Value>, also in apify_client::models. When constructing a model, set extra: Default::default() (an empty map); read passthrough fields from a returned model's extra by key:

use apify_client::models::Extra;

// `extra` is a HashMap<String, serde_json::Value>; look up any passthrough field by key.
fn some_field(extra: &Extra) -> Option<&serde_json::Value> {
    extra.get("someFieldNotModelled")
}

The error type ApifyClientError (and its companions ApiError, ApifyClientResult) is re-exported at the crate root — see Error handling for import and matching:

use apify_client::ApifyClientError;

ApifyClient and the builder

ApifyClient is the entry point. Construct it with ApifyClient::new(token) for the common case, or with ApifyClient::builder() to customize behaviour.

Builder options:

Method Default Description
token(t) none API token, sent as Authorization: Bearer <token>.
base_url(u) https://api.apify.com API origin; /v2 is appended automatically.
public_base_url(u) = base_url Origin used when building public/shareable URLs.
max_retries(n) 8 Maximum retries for 429/5xx/network errors.
min_delay_between_retries(d) 500ms Base backoff delay (doubled each retry, with jitter).
timeout(d) 360s Overall per-request timeout budget.
user_agent_suffix(s) none Extra text appended to the User-Agent header.
request_compression(c) Brotli Encoding for large request bodies: RequestCompression::Brotli (br) or RequestCompression::Gzip (gzip).
http_backend(b) reqwest Replaceable HTTP transport (apify_client::http_client::{HttpBackend, ReqwestBackend}).

Request bodies of at least 1024 bytes are compressed once (before retries) with the selected request_compression algorithm and sent with the matching Content-Encoding header. Brotli is preferred; select gzip for environments or intermediaries that do not handle brotli:

use apify_client::{ApifyClient, RequestCompression};

let client = ApifyClient::builder()
    .token("my-api-token")
    .request_compression(RequestCompression::Gzip)
    .build();

The User-Agent header has the form ApifyClient/{client_version} ({os}; Rust/{rust_version}); isAtHome/{true|false} where the {os} token matches the reference client's os.platform() value (e.g. darwin, win32, linux) so it is identical across all Apify clients, and isAtHome reflects the APIFY_IS_AT_HOME environment variable (the platform variable the reference clients read; rendered lowercase to match them). To reach those values the client maps Rust's native std::env::consts::OS spellings to Node's (macosdarwin, windowswin32, solaris/illumossunos); all other tokens (linux, android, freebsd, …) are already identical and pass through unchanged.

Convenience methods

Beyond the resource accessors, ApifyClient exposes one convenience method:

Method Arguments Returns Description
set_status_message(message, is_terminal) message: &str, is_terminal: bool ActorRun Sets the status message of the current Actor run.

set_status_message updates the run identified by the ACTOR_RUN_ID environment variable, so it only works when called from inside an Actor run. message is the human-readable status text; when is_terminal is true the message becomes final and is not overwritten by later updates. It returns the updated ActorRun, or ApifyClientError::InvalidArgument if ACTOR_RUN_ID is not set.

use apify_client::ApifyClient;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = ApifyClient::new("my-api-token");
    // Called from inside an Actor run (reads ACTOR_RUN_ID from the environment).
    client.set_status_message("Processing input…", false).await?;
    Ok(())
}

Resource clients

Accessor methods on ApifyClient return resource clients — the collection accessor (plural) lists/creates, and the single-resource accessor (singular) operates on one resource by id:

actors/actor, builds/build, runs/run, tasks/task, datasets/dataset, key_value_stores/key_value_store, request_queues/request_queue, schedules/schedule, webhooks/webhook, webhook_dispatches/webhook_dispatch, store, me/user, log.

Each resource has a dedicated page, linked under Resource clients in the Contents above (Actors, runs, builds, tasks, storages, schedules, webhooks, and store/users/logs).

Iterating collections

A collection's list(...) method returns a single PaginationList page. To walk every item across all pages without tracking offsets yourself, call iterate(...) instead: it returns a lazy ListIterator (re-exported at the crate root) that fetches the next page from the API on demand as you consume items. Every collection client provides it (actors, builds, runs, tasks, datasets, key_value_stores, request_queues, schedules, webhooks, webhook_dispatches, store, and the nested Actor versions/env_vars). DatasetClient exposes iterate_items() for dataset items, and KeyValueStoreClient exposes iterate_keys() for store keys (cursor-based). The options' limit caps the total number of items yielded (unset iterates everything); to control the per-request page size, call .with_chunk_size(n) on the returned iterator (offset-paginated iterators only).

use apify_client::{ApifyClient, ActorListOptions};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = ApifyClient::new("my-api-token");
    let mut actors = client.actors().iterate(ActorListOptions {
        my: Some(true),
        ..Default::default()
    });
    while let Some(actor) = actors.next().await? {
        println!("{}", actor.id);
    }
    Ok(())
}

Error handling

Every fallible method returns Result<T, ApifyClientError>. The variants are:

  • Api(Box<ApiError>) — the API returned a non-success status. ApiError exposes status_code, error_type, message, attempt, http_method, path and optional data.
  • Http(String) — transport/network failure.
  • Timeout — the request exceeded its timeout.
  • Serde(..) — (de)serialization failure.
  • InvalidResponse(..) / InvalidArgument(..) — unexpected response or bad argument.

get/delete map a missing resource to Ok(None) / a no-op.

To inspect the API-level details of an error without matching every variant, use ApifyClientError::as_api_error, which returns Some(&ApiError) for the Api variant and None for any other (transport, timeout, serde, …):

# use apify_client::ApifyClient;
# async fn run() {
# let client = ApifyClient::new("t");
if let Err(err) = client.actor("nonexistent~actor").get().await {
    if let Some(api) = err.as_api_error() {
        eprintln!("API error {}: {}", api.status_code, api.message);
    }
}
# }

Examples

Each example in ../examples is runnable with APIFY_TOKEN=... cargo run --example <name> and is covered by a CI test:

Example Demonstrates
run_store_actor Run a Store Actor, wait, read its default dataset.
storages Create + write + read each storage type.
get_account Fetch the current account, plus its monthly usage (current cycle and for a specific date).
create_build_run_actor Create an Actor, build, run, fetch the run log.
run_and_last_run_storages Run an Actor, then read the last run's storages.
iterate_store Lazily iterate Store Actors.
log_redirection Redirect a separate Actor's run log into your output live, prefixing each line with the source Actor's name.
raw_log Fetch and stream a run's raw (unprocessed) log via LogOptions { raw: Some(true) }.