diff --git a/docs/docs.md b/docs/docs.md index 08d53d3d..91ff377b 100644 --- a/docs/docs.md +++ b/docs/docs.md @@ -146,8 +146,12 @@ All public classes, methods and their parameters can be inspected in this API re The Apify API client. * [\_\_init\_\_()](#apifyclient-\_\_init\_\_) +* [actor()](#apifyclient-actor) +* [actors()](#apifyclient-actors) * [build()](#apifyclient-build) * [builds()](#apifyclient-builds) +* [run()](#apifyclient-run) +* [runs()](#apifyclient-runs) * [dataset()](#apifyclient-dataset) * [datasets()](#apifyclient-datasets) * [key\_value\_store()](#apifyclient-key\_value\_store) @@ -184,6 +188,30 @@ Initialize the Apify API Client. *** +#### [](#apifyclient-actor) `ApifyClient.actor(actor_id)` + +Retrieve the sub-client for manipulating a single actor. + +* **Parameters** + + * **actor_id** (`str`) – ID of the actor to be manipulated + +* **Return type** + + [`ActorClient`](#actorclient) + +*** + +#### [](#apifyclient-actors) `ApifyClient.actors()` + +Retrieve the sub-client for manipulating actors. + +* **Return type** + + [`ActorCollectionClient`](#actorcollectionclient) + +*** + #### [](#apifyclient-build) `ApifyClient.build(build_id)` Retrieve the sub-client for manipulating a single actor build. @@ -208,6 +236,30 @@ Retrieve the sub-client for querying multiple builds of a user. *** +#### [](#apifyclient-run) `ApifyClient.run(run_id)` + +Retrieve the sub-client for manipulating a single actor run. + +* **Parameters** + + * **run_id** (`str`) – ID of the actor run to be manipulated + +* **Return type** + + [`RunClient`](#runclient) + +*** + +#### [](#apifyclient-runs) `ApifyClient.runs()` + +Retrieve the sub-client for querying multiple actor runs of a user. + +* **Return type** + + [`RunCollectionClient`](#runcollectionclient) + +*** + #### [](#apifyclient-dataset) `ApifyClient.dataset(dataset_id)` Retrieve the sub-client for manipulating a single dataset. @@ -384,25 +436,782 @@ Retrieve the sub-client for manipulating a single task. #### [](#apifyclient-tasks) `ApifyClient.tasks()` -Retrieve the sub-client for retrieving tasks. +Retrieve the sub-client for manipulating tasks. + +* **Return type** + + [`TaskCollectionClient`](#taskcollectionclient) + +*** + +#### [](#apifyclient-user) `ApifyClient.user(user_id=None)` + +Retrieve the sub-client for querying users. + +* **Parameters** + + * **user_id** (`str`, *optional*) – ID of user to be queried. If `None`, queries the user belonging to the token supplied to the client + +* **Return type** + + [`UserClient`](#userclient) + +*** + +### [](#actorclient) ActorClient + +Sub-client for manipulating a single actor. + +* [get()](#actorclient-get) +* [update()](#actorclient-update) +* [delete()](#actorclient-delete) +* [start()](#actorclient-start) +* [call()](#actorclient-call) +* [build()](#actorclient-build) +* [builds()](#actorclient-builds) +* [runs()](#actorclient-runs) +* [last\_run()](#actorclient-last\_run) +* [versions()](#actorclient-versions) +* [version()](#actorclient-version) +* [webhooks()](#actorclient-webhooks) + +*** + +#### [](#actorclient-get) `ActorClient.get()` + +Retrieve the actor. + +[https://docs.apify.com/api/v2#/reference/actors/actor-object/get-actor](https://docs.apify.com/api/v2#/reference/actors/actor-object/get-actor) + +* **Returns** + + The retrieved actor + +* **Return type** + + `dict`, optional + +*** + +#### [](#actorclient-update) `ActorClient.update(*, name=None, title=None, description=None, seo_title=None, seo_description=None, versions=None, restart_on_error=None, is_public=None, is_deprecated=None, is_anonymously_runnable=None, categories=None, default_run_build=None, default_run_memory_mbytes=None, default_run_timeout_secs=None, example_run_input_body=None, example_run_input_content_type=None)` + +Update the actor with the specified fields. + +[https://docs.apify.com/api/v2#/reference/actors/actor-object/update-actor](https://docs.apify.com/api/v2#/reference/actors/actor-object/update-actor) + +* **Parameters** + + * **name** (`str`, *optional*) – The name of the actor + + * **title** (`str`, *optional*) – The title of the actor (human-readable) + + * **description** (`str`, *optional*) – The description for the actor + + * **seo_title** (`str`, *optional*) – The title of the actor optimized for search engines + + * **seo_description** (`str`, *optional*) – The description of the actor optimized for search engines + + * **versions** (`list of dict`, *optional*) – The list of actor versions + + * **restart_on_error** (`bool`, *optional*) – If true, the main actor run process will be restarted whenever it exits with a non-zero status code. + + * **is_public** (`bool`, *optional*) – Whether the actor is public. + + * **is_deprecated** (`bool`, *optional*) – Whether the actor is deprecated. + + * **is_anonymously_runnable** (`bool`, *optional*) – Whether the actor is anonymously runnable. + + * **categories** (`list of str`, *optional*) – The categories to which the actor belongs to. + + * **default_run_build** (`str`, *optional*) – Tag or number of the build that you want to run by default. + + * **default_run_memory_mbytes** (`int`, *optional*) – Default amount of memory allocated for the runs of this actor, in megabytes. + + * **default_run_timeout_secs** (`int`, *optional*) – Default timeout for the runs of this actor in seconds. + + * **example_run_input_body** (`Any`, *optional*) – Input to be prefilled as default input to new users of this actor. + + * **example_run_input_content_type** (`str`, *optional*) – The content type of the example run input. + +* **Returns** + + The updated actor + +* **Return type** + + `dict` + +*** + +#### [](#actorclient-delete) `ActorClient.delete()` + +Delete the actor. + +[https://docs.apify.com/api/v2#/reference/actors/actor-object/delete-actor](https://docs.apify.com/api/v2#/reference/actors/actor-object/delete-actor) + +* **Return type** + + `None` + +*** + +#### [](#actorclient-start) `ActorClient.start(*, run_input=None, content_type=None, build=None, memory_mbytes=None, timeout_secs=None, wait_for_finish=None, webhooks=None)` + +Start the actor and immediately return the Run object. + +[https://docs.apify.com/api/v2#/reference/actors/run-collection/run-actor](https://docs.apify.com/api/v2#/reference/actors/run-collection/run-actor) + +* **Parameters** + + * **run_input** (`Any`, *optional*) – The input to pass to the actor run. + + * **content_type** (`str`, *optional*) – The content type of the input. + + * **build** (`str`, *optional*) – Specifies the actor build to run. It can be either a build tag or build number. + By default, the run uses the build specified in the default run configuration for the actor (typically latest). + + * **memory_mbytes** (`int`, *optional*) – Memory limit for the run, in megabytes. + By default, the run uses a memory limit specified in the default run configuration for the actor. + + * **timeout_secs** (`int`, *optional*) – Optional timeout for the run, in seconds. + By default, the run uses timeout specified in the default run configuration for the actor. + + * **wait_for_finish** (`int`, *optional*) – The maximum number of seconds the server waits for the run to finish. + By default, it is 0, the maximum value is 300. + + * **webhooks** (`list of dict`, *optional*) – Optional ad-hoc webhooks ([https://docs.apify.com/webhooks/ad-hoc-webhooks](https://docs.apify.com/webhooks/ad-hoc-webhooks)) + associated with the actor run which can be used to receive a notification, + e.g. when the actor finished or failed. + If you already have a webhook set up for the actor or task, you do not have to add it again here. + Each webhook is represented by a dictionary containing these items: + * `event_types`: list of `WebhookEventType` values which trigger the webhook + * `request_url`: URL to which to send the webhook HTTP request + * `payload_template` (optional): Optional template for the request payload + +* **Returns** + + The run object + +* **Return type** + + `dict` + +*** + +#### [](#actorclient-call) `ActorClient.call(*, run_input=None, content_type=None, build=None, memory_mbytes=None, timeout_secs=None, webhooks=None, wait_secs=None)` + +Start the actor and wait for it to finish before returning the Run object. + +It waits indefinitely, unless the wait_secs argument is provided. + +[https://docs.apify.com/api/v2#/reference/actors/run-collection/run-actor](https://docs.apify.com/api/v2#/reference/actors/run-collection/run-actor) + +* **Parameters** + + * **run_input** (`Any`, *optional*) – The input to pass to the actor run. + + * **content_type** (`str`, *optional*) – The content type of the input. + + * **build** (`str`, *optional*) – Specifies the actor build to run. It can be either a build tag or build number. + By default, the run uses the build specified in the default run configuration for the actor (typically latest). + + * **memory_mbytes** (`int`, *optional*) – Memory limit for the run, in megabytes. + By default, the run uses a memory limit specified in the default run configuration for the actor. + + * **timeout_secs** (`int`, *optional*) – Optional timeout for the run, in seconds. + By default, the run uses timeout specified in the default run configuration for the actor. + + * **webhooks** (`list`, *optional*) – Optional webhooks ([https://docs.apify.com/webhooks](https://docs.apify.com/webhooks)) associated with the actor run, + which can be used to receive a notification, e.g. when the actor finished or failed. + If you already have a webhook set up for the actor, you do not have to add it again here. + + * **wait_secs** (`int`, *optional*) – The maximum number of seconds the server waits for the run to finish. If not provided, waits indefinitely. + +* **Returns** + + The run object + +* **Return type** + + `dict` + +*** + +#### [](#actorclient-build) `ActorClient.build(*, version_number, beta_packages=None, tag=None, use_cache=None, wait_for_finish=None)` + +Build the actor. + +[https://docs.apify.com/api/v2#/reference/actors/build-collection/build-actor](https://docs.apify.com/api/v2#/reference/actors/build-collection/build-actor) + +* **Parameters** + + * **version_number** (`str`) – Actor version number to be built. + + * **beta_packages** (`bool`, *optional*) – If True, then the actor is built with beta versions of Apify NPM packages. + By default, the build uses latest stable packages. + + * **tag** (`str`, *optional*) – Tag to be applied to the build on success. By default, the tag is taken from the actor version’s buildTag property. + + * **use_cache** (`bool`, *optional*) – If true, the actor’s Docker container will be rebuilt using layer cache + ([https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#leverage-build-cache](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#leverage-build-cache)). + This is to enable quick rebuild during development. + By default, the cache is not used. + + * **wait_for_finish** (`int`, *optional*) – The maximum number of seconds the server waits for the build to finish before returning. + By default it is 0, the maximum value is 300. + +* **Returns** + + The build object + +* **Return type** + + `dict` + +*** + +#### [](#actorclient-builds) `ActorClient.builds()` + +Retrieve a client for the builds of this actor. + +* **Return type** + + [`BuildCollectionClient`](#buildcollectionclient) + +*** + +#### [](#actorclient-runs) `ActorClient.runs()` + +Retrieve a client for the runs of this actor. + +* **Return type** + + [`RunCollectionClient`](#runcollectionclient) + +*** + +#### [](#actorclient-last_run) `ActorClient.last_run(*, status=None)` + +Retrieve the client for the last run of this actor. + +Last run is retrieved based on the start time of the runs. + +* **Parameters** + + * **status** (`str`, *optional*) – Consider only runs with this status. + +* **Returns** + + The resource client for the last run of this actor. + +* **Return type** + + [`RunClient`](#runclient) + +*** + +#### [](#actorclient-versions) `ActorClient.versions()` + +Retrieve a client for the versions of this actor. + +* **Return type** + + [`ActorVersionCollectionClient`](#actorversioncollectionclient) + +*** + +#### [](#actorclient-version) `ActorClient.version(version_number)` + +Retrieve the client for the specified version of this actor. + +* **Parameters** + + * **version_number** (`str`) – The version number for which to retrieve the resource client. + +* **Returns** + + The resource client for the specified actor version. + +* **Return type** + + [`ActorVersionClient`](#actorversionclient) + +*** + +#### [](#actorclient-webhooks) `ActorClient.webhooks()` + +Retrieve a client for webhooks associated with this actor. * **Return type** - [`TaskCollectionClient`](#taskcollectionclient) + [`WebhookCollectionClient`](#webhookcollectionclient) + +*** + +### [](#actorcollectionclient) ActorCollectionClient + +Sub-client for manipulating actors. + +* [list()](#actorcollectionclient-list) +* [create()](#actorcollectionclient-create) + +*** + +#### [](#actorcollectionclient-list) `ActorCollectionClient.list(*, my=None, limit=None, offset=None, desc=None)` + +List the actors the user has created or used. + +[https://docs.apify.com/api/v2#/reference/actors/actor-collection/get-list-of-actors](https://docs.apify.com/api/v2#/reference/actors/actor-collection/get-list-of-actors) + +* **Parameters** + + * **my** (`bool`, *optional*) – If True, will return only actors which the user has created themselves. + + * **limit** (`int`, *optional*) – How many actors to list + + * **offset** (`int`, *optional*) – What actor to include as first when retrieving the list + + * **desc** (`bool`, *optional*) – Whether to sort the actors in descending order based on their creation date + +* **Returns** + + The list of available actors matching the specified filters. + +* **Return type** + + `dict` + +*** + +#### [](#actorcollectionclient-create) `ActorCollectionClient.create(*, name, title=None, description=None, seo_title=None, seo_description=None, versions=None, restart_on_error=None, is_public=None, is_deprecated=None, is_anonymously_runnable=None, categories=None, default_run_build=None, default_run_memory_mbytes=None, default_run_timeout_secs=None, example_run_input_body=None, example_run_input_content_type=None)` + +Create a new actor. + +[https://docs.apify.com/api/v2#/reference/actors/actor-collection/create-actor](https://docs.apify.com/api/v2#/reference/actors/actor-collection/create-actor) + +* **Parameters** + + * **name** (`str`) – The name of the actor + + * **title** (`str`, *optional*) – The title of the actor (human-readable) + + * **description** (`str`, *optional*) – The description for the actor + + * **seo_title** (`str`, *optional*) – The title of the actor optimized for search engines + + * **seo_description** (`str`, *optional*) – The description of the actor optimized for search engines + + * **versions** (`list of dict`, *optional*) – The list of actor versions + + * **restart_on_error** (`bool`, *optional*) – If true, the main actor run process will be restarted whenever it exits with a non-zero status code. + + * **is_public** (`bool`, *optional*) – Whether the actor is public. + + * **is_deprecated** (`bool`, *optional*) – Whether the actor is deprecated. + + * **is_anonymously_runnable** (`bool`, *optional*) – Whether the actor is anonymously runnable. + + * **categories** (`list of str`, *optional*) – The categories to which the actor belongs to. + + * **default_run_build** (`str`, *optional*) – Tag or number of the build that you want to run by default. + + * **default_run_memory_mbytes** (`int`, *optional*) – Default amount of memory allocated for the runs of this actor, in megabytes. + + * **default_run_timeout_secs** (`int`, *optional*) – Default timeout for the runs of this actor in seconds. + + * **example_run_input_body** (`Any`, *optional*) – Input to be prefilled as default input to new users of this actor. + + * **example_run_input_content_type** (`str`, *optional*) – The content type of the example run input. + +* **Returns** + + The created actor. + +* **Return type** + + `dict` + +*** + +### [](#actorversionclient) ActorVersionClient + +Sub-client for manipulating a single actor version. + +* [get()](#actorversionclient-get) +* [update()](#actorversionclient-update) +* [delete()](#actorversionclient-delete) + +*** + +#### [](#actorversionclient-get) `ActorVersionClient.get()` + +Return information about the actor version. + +[https://docs.apify.com/api/v2#/reference/actors/version-object/get-version](https://docs.apify.com/api/v2#/reference/actors/version-object/get-version) + +* **Returns** + + The retrieved actor version data + +* **Return type** + + `dict`, optional + +*** + +#### [](#actorversionclient-update) `ActorVersionClient.update(*, build_tag=None, env_vars=None, apply_env_vars_to_build=None, source_type=None, source_code=None, base_docker_image=None, source_files=None, git_repo_url=None, tarball_url=None, github_gist_url=None)` + +Update the actor version with specified fields. + +[https://docs.apify.com/api/v2#/reference/actors/version-object/update-version](https://docs.apify.com/api/v2#/reference/actors/version-object/update-version) + +* **Parameters** + + * **build_tag** (`str`, *optional*) – Tag that is automatically set to the latest successful build of the current version. + + * **env_vars** (`list of dict`, *optional*) – Environment variables that will be available to the actor run process, + and optionally also to the build process. See the API docs for their exact structure. + + * **apply_env_vars_to_build** (`bool`, *optional*) – Whether the environment variables specified for the actor run + will also be set to the actor build process. + + * **source_type** (`str`, *optional*) – What source type is the actor version using. Can be one of + SOURCE_CODE, SOURCE_FILES, GIT_REPO, TARBALL and GITHUB_GIST. + + * **source_code** (`str`, *optional*) – Source code as a single JavaScript/Node.js file, using the base Docker image specified in baseDockerImage. + Required when source_type is SOURCE_CODE. + + * **base_docker_image** (`str`, *optional*) – The base Docker image to use for single-file actors. Required when source_type is SOURCE_CODE. + + * **source_files** (`list of dict`, *optional*) – Source code comprised of multiple files, each an item of the array. + Required when source_type is SOURCE_FILES. See the API docs for the exact structure. + + * **git_repo_url** (`str`, *optional*) – The URL of a Git repository from which the source code will be cloned. + Required when source_type is GIT_REPO. + + * **tarball_url** (`str`, *optional*) – The URL of a tarball or a zip archive from which the source code will be downloaded. + Required when source_type is TARBALL. + + * **github_gist_url** (`str`, *optional*) – The URL of a GitHub Gist from which the source will be downloaded. + Required when source_type is GITHUB_GIST. + +* **Returns** + + The updated actor version + +* **Return type** + + `dict` + +*** + +#### [](#actorversionclient-delete) `ActorVersionClient.delete()` + +Delete the actor version. + +[https://docs.apify.com/api/v2#/reference/actors/version-object/delete-version](https://docs.apify.com/api/v2#/reference/actors/version-object/delete-version) + +* **Return type** + + `None` + +*** + +### [](#actorversioncollectionclient) ActorVersionCollectionClient + +Sub-client for manipulating actor versions. + +* [list()](#actorversioncollectionclient-list) +* [create()](#actorversioncollectionclient-create) + +*** + +#### [](#actorversioncollectionclient-list) `ActorVersionCollectionClient.list()` + +List the available actor versions. + +[https://docs.apify.com/api/v2#/reference/actors/version-collection/get-list-of-versions](https://docs.apify.com/api/v2#/reference/actors/version-collection/get-list-of-versions) + +* **Returns** + + The list of available actor versions. + +* **Return type** + + `dict` + +*** + +#### [](#actorversioncollectionclient-create) `ActorVersionCollectionClient.create(*, version_number, build_tag=None, env_vars=None, apply_env_vars_to_build=None, source_type, source_code=None, base_docker_image=None, source_files=None, git_repo_url=None, tarball_url=None, github_gist_url=None)` + +Create a new actor version. + +[https://docs.apify.com/api/v2#/reference/actors/version-collection/create-version](https://docs.apify.com/api/v2#/reference/actors/version-collection/create-version) + +* **Parameters** + + * **version_number** (`str`) – Major and minor version of the actor (e.g. 1.0) + + * **build_tag** (`str`, *optional*) – Tag that is automatically set to the latest successful build of the current version. + + * **env_vars** (`list of dict`, *optional*) – Environment variables that will be available to the actor run process, + and optionally also to the build process. See the API docs for their exact structure. + + * **apply_env_vars_to_build** (`bool`, *optional*) – Whether the environment variables specified for the actor run + will also be set to the actor build process. + + * **source_type** (`str`) – What source type is the actor version using. Can be one of + SOURCE_CODE, SOURCE_FILES, GIT_REPO, TARBALL and GITHUB_GIST. + + * **source_code** (`str`, *optional*) – Source code as a single JavaScript/Node.js file, using the base Docker image specified in baseDockerImage. + Required when source_type is SOURCE_CODE. + + * **base_docker_image** (`str`, *optional*) – The base Docker image to use for single-file actors. Required when source_type is SOURCE_CODE. + + * **source_files** (`list of dict`, *optional*) – Source code comprised of multiple files, each an item of the array. + Required when source_type is SOURCE_FILES. See the API docs for the exact structure. + + * **git_repo_url** (`str`, *optional*) – The URL of a Git repository from which the source code will be cloned. + Required when source_type is GIT_REPO. + + * **tarball_url** (`str`, *optional*) – The URL of a tarball or a zip archive from which the source code will be downloaded. + Required when source_type is TARBALL. + + * **github_gist_url** (`str`, *optional*) – The URL of a GitHub Gist from which the source will be downloaded. + Required when source_type is GITHUB_GIST. + +* **Returns** + + The created actor version + +* **Return type** + + `dict` + +*** + +### [](#runclient) RunClient + +Sub-client for manipulating a single actor run. + +* [get()](#runclient-get) +* [abort()](#runclient-abort) +* [wait\_for\_finish()](#runclient-wait\_for\_finish) +* [metamorph()](#runclient-metamorph) +* [resurrect()](#runclient-resurrect) +* [dataset()](#runclient-dataset) +* [key\_value\_store()](#runclient-key\_value\_store) +* [request\_queue()](#runclient-request\_queue) +* [log()](#runclient-log) + +*** + +#### [](#runclient-get) `RunClient.get()` + +Return information about the actor run. + +[https://docs.apify.com/api/v2#/reference/actor-runs/run-object/get-run](https://docs.apify.com/api/v2#/reference/actor-runs/run-object/get-run) + +* **Returns** + + The retrieved actor run data + +* **Return type** + + `dict` + +*** + +#### [](#runclient-abort) `RunClient.abort()` + +Abort the actor run which is starting or currently running and return its details. + +[https://docs.apify.com/api/v2#/reference/actor-runs/abort-run/abort-run](https://docs.apify.com/api/v2#/reference/actor-runs/abort-run/abort-run) + +* **Returns** + + The data of the aborted actor run + +* **Return type** + + `dict` + +*** + +#### [](#runclient-wait_for_finish) `RunClient.wait_for_finish(*, wait_secs=None)` + +Wait synchronously until the run finishes or the server times out. + +* **Parameters** + + * **wait_secs** (`int`, *optional*) – how long does the client wait for run to finish. `None` for indefinite. + +* **Returns** + + The actor run data. If the status on the object is not one of the terminal statuses + + (SUCEEDED, FAILED, TIMED_OUT, ABORTED), then the run has not yet finished. + +* **Return type** + + `dict`, optional + +*** + +#### [](#runclient-metamorph) `RunClient.metamorph(*, target_actor_id, target_actor_build=None, run_input=None, content_type=None)` + +Transform an actor run into a run of another actor with a new input. + +[https://docs.apify.com/api/v2#/reference/actor-runs/metamorph-run/metamorph-run](https://docs.apify.com/api/v2#/reference/actor-runs/metamorph-run/metamorph-run) + +* **Parameters** + + * **target_actor_id** (`str`) – ID of the target actor that the run should be transformed into + + * **target_actor_build** (`str`, *optional*) – The build of the target actor. It can be either a build tag or build number. + By default, the run uses the build specified in the default run configuration for the target actor (typically the latest build). + + * **run_input** (`Any`, *optional*) – The input to pass to the new run. + + * **content_type** (`str`, *optional*) – The content type of the input. + +* **Returns** + + The actor run data. + +* **Return type** + + `dict` + +*** + +#### [](#runclient-resurrect) `RunClient.resurrect()` + +Resurrect a finished actor run. + +Only finished runs, i.e. runs with status FINISHED, FAILED, ABORTED and TIMED-OUT can be resurrected. +Run status will be updated to RUNNING and its container will be restarted with the same default storages. + +[https://docs.apify.com/api/v2#/reference/actor-runs/resurrect-run/resurrect-run](https://docs.apify.com/api/v2#/reference/actor-runs/resurrect-run/resurrect-run) + +* **Returns** + + The actor run data. + +* **Return type** + + `dict` + +*** + +#### [](#runclient-dataset) `RunClient.dataset()` + +Get the client for the default dataset of the actor run. + +Currently this works only through actor_client.last_run().dataset(). +It will become available for all runs once the API supports it. + +[https://docs.apify.com/api/v2#/reference/actors/last-run-object-and-its-storages](https://docs.apify.com/api/v2#/reference/actors/last-run-object-and-its-storages) + +* **Returns** + + A client allowing access to the default dataset of this actor run. + +* **Return type** + + [`DatasetClient`](#datasetclient) + +*** + +#### [](#runclient-key_value_store) `RunClient.key_value_store()` + +Get the client for the default key-value store of the actor run. + +Currently this works only through actor_client.last_run().key_value_store(). +It will become available for all runs once the API supports it. + +[https://docs.apify.com/api/v2#/reference/actors/last-run-object-and-its-storages](https://docs.apify.com/api/v2#/reference/actors/last-run-object-and-its-storages) + +* **Returns** + + A client allowing access to the default key-value store of this actor run. + +* **Return type** + + [`KeyValueStoreClient`](#keyvaluestoreclient) + +*** + +#### [](#runclient-request_queue) `RunClient.request_queue()` + +Get the client for the default request queue of the actor run. + +Currently this works only through actor_client.last_run().request_queue(). +It will become available for all runs once the API supports it. + +[https://docs.apify.com/api/v2#/reference/actors/last-run-object-and-its-storages](https://docs.apify.com/api/v2#/reference/actors/last-run-object-and-its-storages) + +* **Returns** + + A client allowing access to the default request_queue of this actor run. + +* **Return type** + + [`RequestQueueClient`](#requestqueueclient) + +*** + +#### [](#runclient-log) `RunClient.log()` + +Get the client for the log of the actor run. + +Currently this works only through actor_client.last_run().log(). +It will become available for all runs once the API supports it. + +[https://docs.apify.com/api/v2#/reference/actors/last-run-object-and-its-storages](https://docs.apify.com/api/v2#/reference/actors/last-run-object-and-its-storages) + +* **Returns** + + A client allowing access to the log of this actor run. + +* **Return type** + + [`LogClient`](#logclient) + +*** + +### [](#runcollectionclient) RunCollectionClient + +Sub-client for listing actor runs. + +* [list()](#runcollectionclient-list) + +*** + +#### [](#runcollectionclient-list) `RunCollectionClient.list(*, limit=None, offset=None, desc=None, status=None)` + +List all actor runs (either of a single actor, or all user’s actors, depending on where this client was initialized from). + +[https://docs.apify.com/api/v2#/reference/actors/run-collection/get-list-of-runs](https://docs.apify.com/api/v2#/reference/actors/run-collection/get-list-of-runs) +[https://docs.apify.com/api/v2#/reference/actor-runs/run-collection/get-user-runs-list](https://docs.apify.com/api/v2#/reference/actor-runs/run-collection/get-user-runs-list) + +* **Parameters** + + * **limit** (`int`, *optional*) – How many runs to retrieve -*** + * **offset** (`int`, *optional*) – What run to include as first when retrieving the list -#### [](#apifyclient-user) `ApifyClient.user(user_id=None)` + * **desc** (`bool`, *optional*) – Whether to sort the runs in descending order based on their start date -Retrieve the sub-client for querying users. + * **status** (`str`, *optional*) – Retrieve only runs with the provided status -* **Parameters** +* **Returns** - * **user_id** (`str`, *optional*) – ID of user to be queried. If `None`, queries the user belonging to the token supplied to the client + The retrieved actor runs * **Return type** - [`UserClient`](#userclient) + `dict` *** @@ -1054,47 +1863,6 @@ Retrieve a named key-value store, or create a new one when it doesn’t exist. *** -### [](#logclient) LogClient - -Sub-client for manipulating logs. - -* [get()](#logclient-get) -* [stream()](#logclient-stream) - -*** - -#### [](#logclient-get) `LogClient.get()` - -Retrieve the log as text. - -[https://docs.apify.com/api/v2#/reference/logs/log/get-log](https://docs.apify.com/api/v2#/reference/logs/log/get-log) - -* **Returns** - - The retrieved log, or `None`, if it does not exist. - -* **Return type** - - `str`, optional - -*** - -#### [](#logclient-stream) `LogClient.stream()` - -Retrieve the log as a file-like object. - -[https://docs.apify.com/api/v2#/reference/logs/log/get-log](https://docs.apify.com/api/v2#/reference/logs/log/get-log) - -* **Returns** - - The retrieved log as a file-like object, or `None`, if it does not exist. - -* **Return type** - - `io.IOBase`, optional - -*** - ### [](#requestqueueclient) RequestQueueClient Sub-client for manipulating a single request queue. @@ -1313,26 +2081,67 @@ Retrieve a named request queue, or create a new one when it doesn’t exist. *** -### [](#scheduleclient) ScheduleClient +### [](#logclient) LogClient -Sub-client for manipulating a single schedule. +Sub-client for manipulating logs. -* [get()](#scheduleclient-get) -* [update()](#scheduleclient-update) -* [delete()](#scheduleclient-delete) -* [get\_log()](#scheduleclient-get\_log) +* [get()](#logclient-get) +* [stream()](#logclient-stream) *** -#### [](#scheduleclient-get) `ScheduleClient.get()` +#### [](#logclient-get) `LogClient.get()` -Return information about the schedule. +Retrieve the log as text. -[https://docs.apify.com/api/v2#/reference/schedules/schedule-object/get-schedule](https://docs.apify.com/api/v2#/reference/schedules/schedule-object/get-schedule) +[https://docs.apify.com/api/v2#/reference/logs/log/get-log](https://docs.apify.com/api/v2#/reference/logs/log/get-log) * **Returns** - The retrieved schedule + The retrieved log, or `None`, if it does not exist. + +* **Return type** + + `str`, optional + +*** + +#### [](#logclient-stream) `LogClient.stream()` + +Retrieve the log as a file-like object. + +[https://docs.apify.com/api/v2#/reference/logs/log/get-log](https://docs.apify.com/api/v2#/reference/logs/log/get-log) + +* **Returns** + + The retrieved log as a file-like object, or `None`, if it does not exist. + +* **Return type** + + `io.IOBase`, optional + +*** + +### [](#webhookclient) WebhookClient + +Sub-client for manipulating a single webhook. + +* [get()](#webhookclient-get) +* [update()](#webhookclient-update) +* [delete()](#webhookclient-delete) +* [dispatches()](#webhookclient-dispatches) + +*** + +#### [](#webhookclient-get) `WebhookClient.get()` + +Retrieve the webhook. + +[https://docs.apify.com/api/v2#/reference/webhooks/webhook-object/get-webhook](https://docs.apify.com/api/v2#/reference/webhooks/webhook-object/get-webhook) + +* **Returns** + + The retrieved webhook, or `None` if it does not exist * **Return type** @@ -1340,32 +2149,38 @@ Return information about the schedule. *** -#### [](#scheduleclient-update) `ScheduleClient.update(*, cron_expression=None, is_enabled=None, is_exclusive=None, name=None, actions=None, description=None, timezone=None)` +#### [](#webhookclient-update) `WebhookClient.update(*, event_types=None, request_url=None, payload_template=None, actor_id=None, actor_task_id=None, actor_run_id=None, ignore_ssl_errors=None, do_not_retry=None, is_ad_hoc=None)` -Update the schedule with specified fields. +Update the webhook. -[https://docs.apify.com/api/v2#/reference/schedules/schedule-object/update-schedule](https://docs.apify.com/api/v2#/reference/schedules/schedule-object/update-schedule) +[https://docs.apify.com/api/v2#/reference/webhooks/webhook-object/update-webhook](https://docs.apify.com/api/v2#/reference/webhooks/webhook-object/update-webhook) * **Parameters** - * **cron_expression** (`str`, *optional*) – The cron expression used by this schedule + * **event_types** (`list`, *optional*) – List of event types that should trigger the webhook. + Present in the client constants as WebhookEventType. At least one is required. - * **is_enabled** (`bool`, *optional*) – True if the schedule should be enabled + * **request_url** (`str`, *optional*) – URL that will be invoked once the webhook is triggered. - * **is_exclusive** (`bool`, *optional*) – When set to true, don’t start actor or actor task if it’s still running from the previous schedule. + * **payload_template** (`str`, *optional*) – Specification of the payload that will be sent to request_url - * **name** (`str`, *optional*) – The name of the schedule to create. + * **actor_id** (`str`, *optional*) – Id of the actor whose runs should trigger the webhook. - * **actions** (`list of dict`, *optional*) – Actors or tasks that should be run on this schedule. See the API documentation for exact structure. + * **actor_task_id** (`str`, *optional*) – Id of the actor task whose runs should trigger the webhook. - * **description** (`str`, *optional*) – Description of this schedule + * **actor_run_id** (`str`, *optional*) – Id of the actor run which should trigger the webhook. - * **timezone** (`str`, *optional*) – Timezone in which your cron expression runs - (TZ database name from [https://en.wikipedia.org/wiki/List_of_tz_database_time_zones](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones)) + * **ignore_ssl_errors** (`bool`, *optional*) – Whether the webhook should ignore SSL errors returned by request_url + + * **do_not_retry** (`bool`, *optional*) – Whether the webhook should retry sending the payload to request_url upon + failure. + + * **is_ad_hoc** (`bool`, *optional*) – Set to True if you want the webhook to be triggered only the first time the + condition is fulfilled. Only applicable when actor_run_id is filled. * **Returns** - The updated schedule + The updated webhook * **Return type** @@ -1373,11 +2188,11 @@ Update the schedule with specified fields. *** -#### [](#scheduleclient-delete) `ScheduleClient.delete()` +#### [](#webhookclient-delete) `WebhookClient.delete()` -Delete the schedule. +Delete the webhook. -[https://docs.apify.com/api/v2#/reference/schedules/schedule-object/delete-schedule](https://docs.apify.com/api/v2#/reference/schedules/schedule-object/delete-schedule) +[https://docs.apify.com/api/v2#/reference/webhooks/webhook-object/delete-webhook](https://docs.apify.com/api/v2#/reference/webhooks/webhook-object/delete-webhook) * **Return type** @@ -1385,84 +2200,152 @@ Delete the schedule. *** -#### [](#scheduleclient-get_log) `ScheduleClient.get_log()` +#### [](#webhookclient-dispatches) `WebhookClient.dispatches()` -Return log for the given schedule. +Get dispatches of the webhook. -[https://docs.apify.com/api/v2#/reference/schedules/schedule-log/get-schedule-log](https://docs.apify.com/api/v2#/reference/schedules/schedule-log/get-schedule-log) +[https://docs.apify.com/api/v2#/reference/webhooks/dispatches-collection/get-collection](https://docs.apify.com/api/v2#/reference/webhooks/dispatches-collection/get-collection) * **Returns** - Retrieved log of the given schedule + A client allowing access to dispatches of this webhook using its list method * **Return type** - `list`, optional + [`WebhookDispatchCollectionClient`](#webhookdispatchcollectionclient) *** -### [](#schedulecollectionclient) ScheduleCollectionClient +### [](#webhookcollectionclient) WebhookCollectionClient -Sub-client for manipulating schedules. +Sub-client for manipulating webhooks. -* [list()](#schedulecollectionclient-list) -* [create()](#schedulecollectionclient-create) +* [list()](#webhookcollectionclient-list) +* [create()](#webhookcollectionclient-create) *** -#### [](#schedulecollectionclient-list) `ScheduleCollectionClient.list(*, limit=None, offset=None, desc=None)` +#### [](#webhookcollectionclient-list) `WebhookCollectionClient.list(*, limit=None, offset=None, desc=None)` -List the available schedules. +List the available webhooks. -[https://docs.apify.com/api/v2#/reference/schedules/schedules-collection/get-list-of-schedules](https://docs.apify.com/api/v2#/reference/schedules/schedules-collection/get-list-of-schedules) +[https://docs.apify.com/api/v2#/reference/webhooks/webhook-collection/get-list-of-webhooks](https://docs.apify.com/api/v2#/reference/webhooks/webhook-collection/get-list-of-webhooks) * **Parameters** - * **limit** (`int`, *optional*) – How many schedules to retrieve + * **limit** (`int`, *optional*) – How many webhooks to retrieve - * **offset** (`int`, *optional*) – What schedules to include as first when retrieving the list + * **offset** (`int`, *optional*) – What webhook to include as first when retrieving the list - * **desc** (`bool`, *optional*) – Whether to sort the schedules in descending order based on their modification date + * **desc** (`bool`, *optional*) – Whether to sort the webhooks in descending order based on their date of creation + +* **Returns** + + The list of available webhooks matching the specified filters. * **Return type** - `Dict` + `dict` + +*** + +#### [](#webhookcollectionclient-create) `WebhookCollectionClient.create(*, event_types, request_url, payload_template=None, actor_id=None, actor_task_id=None, actor_run_id=None, ignore_ssl_errors=None, do_not_retry=None, idempotency_key=None, is_ad_hoc=None)` + +Create a new webhook. + +You have to specify exactly one out of actor_id, actor_task_id or actor_run_id. + +[https://docs.apify.com/api/v2#/reference/webhooks/webhook-collection/create-webhook](https://docs.apify.com/api/v2#/reference/webhooks/webhook-collection/create-webhook) + +* **Parameters** + + * **event_types** (`list`) – List of event types that should trigger the webhook. + Present in the client constants as WebhookEventType. At least one is required. + + * **request_url** (`str`) – URL that will be invoked once the webhook is triggered. + + * **payload_template** (`str`, *optional*) – Specification of the payload that will be sent to request_url + + * **actor_id** (`str`, *optional*) – Id of the actor whose runs should trigger the webhook. + + * **actor_task_id** (`str`, *optional*) – Id of the actor task whose runs should trigger the webhook. + + * **actor_run_id** (`str`, *optional*) – Id of the actor run which should trigger the webhook. + + * **ignore_ssl_errors** (`bool`, *optional*) – Whether the webhook should ignore SSL errors returned by request_url + + * **do_not_retry** (`bool`, *optional*) – Whether the webhook should retry sending the payload to request_url upon + failure. + + * **idempotency_key** (`str`, *optional*) – A unique identifier of a webhook. You can use it to ensure that you won’t + create the same webhook multiple times. + + * **is_ad_hoc** (`bool`, *optional*) – Set to True if you want the webhook to be triggered only the first time the + condition is fulfilled. Only applicable when actor_run_id is filled. + +* **Returns** + + The created webhook + +* **Return type** + + `dict` + +*** + +### [](#webhookdispatchclient) WebhookDispatchClient + +Sub-client for querying information about a webhook dispatch. + +* [get()](#webhookdispatchclient-get) + +*** + +#### [](#webhookdispatchclient-get) `WebhookDispatchClient.get()` + +Retrieve the webhook dispatch. + +[https://docs.apify.com/api/v2#/reference/webhook-dispatches/webhook-dispatch-object/get-webhook-dispatch](https://docs.apify.com/api/v2#/reference/webhook-dispatches/webhook-dispatch-object/get-webhook-dispatch) * **Returns** - The list of available schedules matching the specified filters. + The retrieved webhook dispatch, or `None` if it does not exist + +* **Return type** + + `dict`, optional + +*** + +### [](#webhookdispatchcollectionclient) WebhookDispatchCollectionClient + +Sub-client for listing webhook dispatches. + +* [list()](#webhookdispatchcollectionclient-list) *** -#### [](#schedulecollectionclient-create) `ScheduleCollectionClient.create(*, cron_expression, is_enabled, is_exclusive, name=None, actions=[], description=None, timezone=None)` +#### [](#webhookdispatchcollectionclient-list) `WebhookDispatchCollectionClient.list(*, limit=None, offset=None, desc=None)` -Create a new schedule. +List all webhook dispatches of a user. -[https://docs.apify.com/api/v2#/reference/schedules/schedules-collection/create-schedule](https://docs.apify.com/api/v2#/reference/schedules/schedules-collection/create-schedule) +[https://docs.apify.com/api/v2#/reference/webhook-dispatches/webhook-dispatches-collection/get-list-of-webhook-dispatches](https://docs.apify.com/api/v2#/reference/webhook-dispatches/webhook-dispatches-collection/get-list-of-webhook-dispatches) * **Parameters** - * **cron_expression** (`str`) – The cron expression used by this schedule - - * **is_enabled** (`bool`) – True if the schedule should be enabled - - * **is_exclusive** (`bool`) – When set to true, don’t start actor or actor task if it’s still running from the previous schedule. + * **limit** (`int`, *optional*) – How many webhook dispatches to retrieve - * **name** (`Optional[str]`) – The name of the schedule to create. + * **offset** (`int`, *optional*) – What webhook dispatch to include as first when retrieving the list - * **actions** (`List[Dict]`) – Actors or tasks that should be run on this schedule. See the API documentation for exact structure. + * **desc** (`bool`, *optional*) – Whether to sort the webhook dispatches in descending order based on the date of their creation - * **description** (`Optional[str]`) – Description of this schedule +* **Returns** - * **timezone** (`Optional[str]`) – Timezone in which your cron expression runs (TZ database name from [https://en.wikipedia.org/wiki/List_of_tz_database_time_zones](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones)) + The retrieved webhook dispatches of a user * **Return type** - `Dict` - -* **Returns** - - The created schedule. + `dict` *** @@ -1477,8 +2360,8 @@ Sub-client for manipulating a single task. * [call()](#taskclient-call) * [get\_input()](#taskclient-get\_input) * [update\_input()](#taskclient-update\_input) -* [last\_run()](#taskclient-last\_run) * [runs()](#taskclient-runs) +* [last\_run()](#taskclient-last\_run) * [webhooks()](#taskclient-webhooks) *** @@ -1562,9 +2445,14 @@ Start the task and immediately return the Run object. * **wait_for_finish** (`int`, *optional*) – The maximum number of seconds the server waits for the run to finish. By default, it is 0, the maximum value is 300. - * **webhooks** (`list`, *optional*) – Optional webhooks ([https://docs.apify.com/webhooks](https://docs.apify.com/webhooks)) associated with the actor run, - which can be used to receive a notification, e.g. when the actor finished or failed. + * **webhooks** (`list of dict`, *optional*) – Optional ad-hoc webhooks ([https://docs.apify.com/webhooks/ad-hoc-webhooks](https://docs.apify.com/webhooks/ad-hoc-webhooks)) + associated with the actor run which can be used to receive a notification, + e.g. when the actor finished or failed. If you already have a webhook set up for the actor or task, you do not have to add it again here. + Each webhook is represented by a dictionary containing these items: + * `event_types`: list of `WebhookEventType` values which trigger the webhook + * `request_url`: URL to which to send the webhook HTTP request + * `payload_template` (optional): Optional template for the request payload * **Returns** @@ -1576,7 +2464,7 @@ Start the task and immediately return the Run object. *** -#### [](#taskclient-call) `TaskClient.call(*, task_input=None, build=None, memory_mbytes=None, timeout_secs=None, wait_for_finish=None, webhooks=None)` +#### [](#taskclient-call) `TaskClient.call(*, task_input=None, build=None, memory_mbytes=None, timeout_secs=None, webhooks=None, wait_secs=None)` Start a task and wait for it to finish before returning the Run object. @@ -1596,13 +2484,12 @@ It waits indefinitely, unless the wait_secs argument is provided. * **timeout_secs** (`int`, *optional*) – Optional timeout for the run, in seconds. By default, the run uses timeout specified in the task settings. - * **wait_for_finish** (`bool`, *optional*) – The maximum number of seconds the server waits for the run to finish. - By default, it is 0, the maximum value is 300. - * **webhooks** (`list`, *optional*) – Specifies optional webhooks associated with the actor run, which can be used to receive a notification e.g. when the actor finished or failed. Note: if you already have a webhook set up for the actor or task, you do not have to add it again here. + * **wait_secs** (`int`, *optional*) – The maximum number of seconds the server waits for the task run to finish. If not provided, waits indefinitely. + * **Returns** The run object @@ -1645,35 +2532,39 @@ Update the default input for this task. *** -#### [](#taskclient-last_run) `TaskClient.last_run(*, status=None)` +#### [](#taskclient-runs) `TaskClient.runs()` -Retrieve RunClient for last run of this task. +Retrieve a client for the runs of this task. -Last run is retrieved based on the start time of the runs. +* **Return type** -* **Parameters** + [`RunCollectionClient`](#runcollectionclient) - * **status** (`optional, dict`) – Consider only runs with this status. +*** -* **Return type** +#### [](#taskclient-last_run) `TaskClient.last_run(*, status=None)` - `None` +Retrieve the client for the last run of this task. -*** +Last run is retrieved based on the start time of the runs. -#### [](#taskclient-runs) `TaskClient.runs()` +* **Parameters** -Retrieve RunCollectionClient for runs of this task. + * **status** (`str`, *optional*) – Consider only runs with this status. + +* **Returns** + + The resource client for the last run of this task. * **Return type** - `None` + [`RunClient`](#runclient) *** #### [](#taskclient-webhooks) `TaskClient.webhooks()` -Retrieve WebhookCollectionClient for webhooks associated with this task. +Retrieve a client for webhooks associated with this task. * **Return type** @@ -1746,52 +2637,26 @@ Create a new task. *** -### [](#userclient) UserClient - -Sub-client for querying user data. - -* [get()](#userclient-get) - -*** - -#### [](#userclient-get) `UserClient.get()` - -Return information about user account. - -You receive all or only public info based on your token permissions. - -[https://docs.apify.com/api/v2#/reference/users](https://docs.apify.com/api/v2#/reference/users) - -* **Returns** - - The retrieved user data, or `None` if the user does not exist. - -* **Return type** - - `dict`, optional - -*** - -### [](#webhookclient) WebhookClient +### [](#scheduleclient) ScheduleClient -Sub-client for manipulating a single webhook. +Sub-client for manipulating a single schedule. -* [get()](#webhookclient-get) -* [update()](#webhookclient-update) -* [delete()](#webhookclient-delete) -* [dispatches()](#webhookclient-dispatches) +* [get()](#scheduleclient-get) +* [update()](#scheduleclient-update) +* [delete()](#scheduleclient-delete) +* [get\_log()](#scheduleclient-get\_log) *** -#### [](#webhookclient-get) `WebhookClient.get()` +#### [](#scheduleclient-get) `ScheduleClient.get()` -Retrieve the webhook. +Return information about the schedule. -[https://docs.apify.com/api/v2#/reference/webhooks/webhook-object/get-webhook](https://docs.apify.com/api/v2#/reference/webhooks/webhook-object/get-webhook) +[https://docs.apify.com/api/v2#/reference/schedules/schedule-object/get-schedule](https://docs.apify.com/api/v2#/reference/schedules/schedule-object/get-schedule) * **Returns** - The retrieved webhook, or `None` if it does not exist + The retrieved schedule * **Return type** @@ -1799,38 +2664,32 @@ Retrieve the webhook. *** -#### [](#webhookclient-update) `WebhookClient.update(*, event_types=None, request_url=None, payload_template=None, actor_id=None, actor_task_id=None, actor_run_id=None, ignore_ssl_errors=None, do_not_retry=None, is_ad_hoc=None)` +#### [](#scheduleclient-update) `ScheduleClient.update(*, cron_expression=None, is_enabled=None, is_exclusive=None, name=None, actions=None, description=None, timezone=None)` -Update the webhook. +Update the schedule with specified fields. -[https://docs.apify.com/api/v2#/reference/webhooks/webhook-object/update-webhook](https://docs.apify.com/api/v2#/reference/webhooks/webhook-object/update-webhook) +[https://docs.apify.com/api/v2#/reference/schedules/schedule-object/update-schedule](https://docs.apify.com/api/v2#/reference/schedules/schedule-object/update-schedule) * **Parameters** - * **event_types** (`list`, *optional*) – List of event types that should trigger the webhook. - Present in the client constants as WebhookEventType. At least one is required. - - * **request_url** (`str`, *optional*) – URL that will be invoked once the webhook is triggered. - - * **payload_template** (`str`, *optional*) – Specification of the payload that will be sent to request_url + * **cron_expression** (`str`, *optional*) – The cron expression used by this schedule - * **actor_id** (`str`, *optional*) – Id of the actor whose runs should trigger the webhook. + * **is_enabled** (`bool`, *optional*) – True if the schedule should be enabled - * **actor_task_id** (`str`, *optional*) – Id of the actor task whose runs should trigger the webhook. + * **is_exclusive** (`bool`, *optional*) – When set to true, don’t start actor or actor task if it’s still running from the previous schedule. - * **actor_run_id** (`str`, *optional*) – Id of the actor run which should trigger the webhook. + * **name** (`str`, *optional*) – The name of the schedule to create. - * **ignore_ssl_errors** (`bool`, *optional*) – Whether the webhook should ignore SSL errors returned by request_url + * **actions** (`list of dict`, *optional*) – Actors or tasks that should be run on this schedule. See the API documentation for exact structure. - * **do_not_retry** (`bool`, *optional*) – Whether the webhook should retry sending the payload to request_url upon - failure. + * **description** (`str`, *optional*) – Description of this schedule - * **is_ad_hoc** (`bool`, *optional*) – Set to True if you want the webhook to be triggered only the first time the - condition is fulfilled. Only applicable when actor_run_id is filled. + * **timezone** (`str`, *optional*) – Timezone in which your cron expression runs + (TZ database name from [https://en.wikipedia.org/wiki/List_of_tz_database_time_zones](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones)) * **Returns** - The updated webhook + The updated schedule * **Return type** @@ -1838,11 +2697,11 @@ Update the webhook. *** -#### [](#webhookclient-delete) `WebhookClient.delete()` +#### [](#scheduleclient-delete) `ScheduleClient.delete()` -Delete the webhook. +Delete the schedule. -[https://docs.apify.com/api/v2#/reference/webhooks/webhook-object/delete-webhook](https://docs.apify.com/api/v2#/reference/webhooks/webhook-object/delete-webhook) +[https://docs.apify.com/api/v2#/reference/schedules/schedule-object/delete-schedule](https://docs.apify.com/api/v2#/reference/schedules/schedule-object/delete-schedule) * **Return type** @@ -1850,149 +2709,107 @@ Delete the webhook. *** -#### [](#webhookclient-dispatches) `WebhookClient.dispatches()` +#### [](#scheduleclient-get_log) `ScheduleClient.get_log()` -Get dispatches of the webhook. +Return log for the given schedule. -[https://docs.apify.com/api/v2#/reference/webhooks/dispatches-collection/get-collection](https://docs.apify.com/api/v2#/reference/webhooks/dispatches-collection/get-collection) +[https://docs.apify.com/api/v2#/reference/schedules/schedule-log/get-schedule-log](https://docs.apify.com/api/v2#/reference/schedules/schedule-log/get-schedule-log) * **Returns** - A client allowing access to dispatches of this webhook using its list method + Retrieved log of the given schedule * **Return type** - [`WebhookDispatchCollectionClient`](#webhookdispatchcollectionclient) + `list`, optional *** -### [](#webhookcollectionclient) WebhookCollectionClient +### [](#schedulecollectionclient) ScheduleCollectionClient -Sub-client for manipulating webhooks. +Sub-client for manipulating schedules. -* [list()](#webhookcollectionclient-list) -* [create()](#webhookcollectionclient-create) +* [list()](#schedulecollectionclient-list) +* [create()](#schedulecollectionclient-create) *** -#### [](#webhookcollectionclient-list) `WebhookCollectionClient.list(*, limit=None, offset=None, desc=None)` +#### [](#schedulecollectionclient-list) `ScheduleCollectionClient.list(*, limit=None, offset=None, desc=None)` -List the available webhooks. +List the available schedules. -[https://docs.apify.com/api/v2#/reference/webhooks/webhook-collection/get-list-of-webhooks](https://docs.apify.com/api/v2#/reference/webhooks/webhook-collection/get-list-of-webhooks) +[https://docs.apify.com/api/v2#/reference/schedules/schedules-collection/get-list-of-schedules](https://docs.apify.com/api/v2#/reference/schedules/schedules-collection/get-list-of-schedules) * **Parameters** - * **limit** (`int`, *optional*) – How many webhooks to retrieve + * **limit** (`int`, *optional*) – How many schedules to retrieve - * **offset** (`int`, *optional*) – What webhook to include as first when retrieving the list + * **offset** (`int`, *optional*) – What schedules to include as first when retrieving the list - * **desc** (`bool`, *optional*) – Whether to sort the webhooks in descending order based on their date of creation + * **desc** (`bool`, *optional*) – Whether to sort the schedules in descending order based on their modification date -* **Returns** +* **Return type** - The list of available webhooks matching the specified filters. + `Dict` -* **Return type** +* **Returns** - `dict` + The list of available schedules matching the specified filters. *** -#### [](#webhookcollectionclient-create) `WebhookCollectionClient.create(*, event_types, request_url, payload_template=None, actor_id=None, actor_task_id=None, actor_run_id=None, ignore_ssl_errors=None, do_not_retry=None, idempotency_key=None, is_ad_hoc=None)` - -Create a new webhook. +#### [](#schedulecollectionclient-create) `ScheduleCollectionClient.create(*, cron_expression, is_enabled, is_exclusive, name=None, actions=[], description=None, timezone=None)` -You have to specify exactly one out of actor_id, actor_task_id or actor_run_id. +Create a new schedule. -[https://docs.apify.com/api/v2#/reference/webhooks/webhook-collection/create-webhook](https://docs.apify.com/api/v2#/reference/webhooks/webhook-collection/create-webhook) +[https://docs.apify.com/api/v2#/reference/schedules/schedules-collection/create-schedule](https://docs.apify.com/api/v2#/reference/schedules/schedules-collection/create-schedule) * **Parameters** - * **event_types** (`list`) – List of event types that should trigger the webhook. - Present in the client constants as WebhookEventType. At least one is required. - - * **request_url** (`str`) – URL that will be invoked once the webhook is triggered. - - * **payload_template** (`str`, *optional*) – Specification of the payload that will be sent to request_url - - * **actor_id** (`str`, *optional*) – Id of the actor whose runs should trigger the webhook. - - * **actor_task_id** (`str`, *optional*) – Id of the actor task whose runs should trigger the webhook. - - * **actor_run_id** (`str`, *optional*) – Id of the actor run which should trigger the webhook. + * **cron_expression** (`str`) – The cron expression used by this schedule - * **ignore_ssl_errors** (`bool`, *optional*) – Whether the webhook should ignore SSL errors returned by request_url + * **is_enabled** (`bool`) – True if the schedule should be enabled - * **do_not_retry** (`bool`, *optional*) – Whether the webhook should retry sending the payload to request_url upon - failure. + * **is_exclusive** (`bool`) – When set to true, don’t start actor or actor task if it’s still running from the previous schedule. - * **idempotency_key** (`str`, *optional*) – A unique identifier of a webhook. You can use it to ensure that you won’t - create the same webhook multiple times. + * **name** (`Optional[str]`) – The name of the schedule to create. - * **is_ad_hoc** (`bool`, *optional*) – Set to True if you want the webhook to be triggered only the first time the - condition is fulfilled. Only applicable when actor_run_id is filled. + * **actions** (`List[Dict]`) – Actors or tasks that should be run on this schedule. See the API documentation for exact structure. -* **Returns** + * **description** (`Optional[str]`) – Description of this schedule - The created webhook + * **timezone** (`Optional[str]`) – Timezone in which your cron expression runs (TZ database name from [https://en.wikipedia.org/wiki/List_of_tz_database_time_zones](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones)) * **Return type** - `dict` - -*** - -### [](#webhookdispatchclient) WebhookDispatchClient - -Sub-client for querying information about a webhook dispatch. - -* [get()](#webhookdispatchclient-get) - -*** - -#### [](#webhookdispatchclient-get) `WebhookDispatchClient.get()` - -Retrieve the webhook dispatch. - -[https://docs.apify.com/api/v2#/reference/webhook-dispatches/webhook-dispatch-object/get-webhook-dispatch](https://docs.apify.com/api/v2#/reference/webhook-dispatches/webhook-dispatch-object/get-webhook-dispatch) + `Dict` * **Returns** - The retrieved webhook dispatch, or `None` if it does not exist - -* **Return type** - - `dict`, optional + The created schedule. *** -### [](#webhookdispatchcollectionclient) WebhookDispatchCollectionClient +### [](#userclient) UserClient -Sub-client for listing webhook dispatches. +Sub-client for querying user data. -* [list()](#webhookdispatchcollectionclient-list) +* [get()](#userclient-get) *** -#### [](#webhookdispatchcollectionclient-list) `WebhookDispatchCollectionClient.list(*, limit=None, offset=None, desc=None)` - -List all webhook dispatches of a user. - -[https://docs.apify.com/api/v2#/reference/webhook-dispatches/webhook-dispatches-collection/get-list-of-webhook-dispatches](https://docs.apify.com/api/v2#/reference/webhook-dispatches/webhook-dispatches-collection/get-list-of-webhook-dispatches) - -* **Parameters** +#### [](#userclient-get) `UserClient.get()` - * **limit** (`int`, *optional*) – How many webhook dispatches to retrieve +Return information about user account. - * **offset** (`int`, *optional*) – What webhook dispatch to include as first when retrieving the list +You receive all or only public info based on your token permissions. - * **desc** (`bool`, *optional*) – Whether to sort the webhook dispatches in descending order based on the date of their creation +[https://docs.apify.com/api/v2#/reference/users](https://docs.apify.com/api/v2#/reference/users) * **Returns** - The retrieved webhook dispatches of a user + The retrieved user data, or `None` if the user does not exist. * **Return type** - `dict` + `dict`, optional diff --git a/docs/res/format_docs.py b/docs/res/format_docs.py index ef6c743e..2fef8705 100755 --- a/docs/res/format_docs.py +++ b/docs/res/format_docs.py @@ -12,6 +12,7 @@ (r'\*\*Parameters\*\*\n\n \*\*', '**Parameters**\n\n * **'), # workaround for sphinx bug with single parameter not being rendered as list (r'\(`(.*), optional`\)', r'(`\1`, *optional*)'), # workaround for bug formatting parameter types # (r'\*\*\[\*\*(\w+)\*\*\]', r'[\1]'), # workaround for bug formatting parameter types + (r' \\\*', r' *'), # workaround for bug with nested lists in argument descriptions (r'`(\w+)`\[`(\w+)`\]', r'`\1[\2]`'), # workaround for complex parameter types with backticks (\ r'`Union`\[`str`, `int`, `float`, `bool`, `None`, `Dict`\[`str`, `Any`\], `List\[Any\]`\]', \ diff --git a/src/apify_client/_consts.py b/src/apify_client/_consts.py index 771cf74b..59a6f233 100644 --- a/src/apify_client/_consts.py +++ b/src/apify_client/_consts.py @@ -14,6 +14,16 @@ class ActorJobStatus(Enum): ABORTED = 'ABORTED' # aborted by user +class ActorSourceType(Enum): + """Available source types for actors.""" + + SOURCE_CODE = 'SOURCE_CODE' # Source code is a single JavaScript/Node.js file + SOURCE_FILES = 'SOURCE_FILES' # Source code is comprised of multiple files + GIT_REPO = 'GIT_REPO' # Source code is cloned from a Git repository + TARBALL = 'TARBALL' # Source code is downloaded using a tarball or Zip file + GITHUB_GIST = 'GITHUB_GIST' # Source code is taken from a GitHub Gist + + class WebhookEventType(Enum): """Events that can trigger a webhook.""" diff --git a/src/apify_client/_http_client.py b/src/apify_client/_http_client.py index 9b54a41c..0bcc49ca 100644 --- a/src/apify_client/_http_client.py +++ b/src/apify_client/_http_client.py @@ -1,3 +1,5 @@ +import gzip +import json as jsonlib import os import sys from http import HTTPStatus @@ -36,7 +38,7 @@ def call( url: str, headers: Optional[Dict] = None, params: Optional[Dict] = None, - data: Optional[str] = None, + data: Optional[Any] = None, json: Optional[JSONSerializable] = None, stream: Optional[bool] = None, parse_response: Optional[bool] = True, @@ -44,6 +46,19 @@ def call( request_params = self._parse_params(params) requests_session = self.requests_session + if not headers: + headers = {} + + if json and not data: + data = jsonlib.dumps(json, ensure_ascii=False).encode('utf-8') + headers['Content-Type'] = 'application/json' + + if isinstance(data, (str, bytes, bytearray)): + if isinstance(data, str): + data = data.encode('utf-8') + data = gzip.compress(data) + headers['Content-Encoding'] = 'gzip' + def _make_request(bail: Callable, attempt: int) -> requests.models.Response: # type: ignore[return] try: response = requests_session.request( @@ -52,7 +67,6 @@ def _make_request(bail: Callable, attempt: int) -> requests.models.Response: # headers=headers, params=request_params, data=data, - json=json, stream=stream, ) if response.status_code < 300: diff --git a/src/apify_client/_utils.py b/src/apify_client/_utils.py index d098f106..32beb8a2 100644 --- a/src/apify_client/_utils.py +++ b/src/apify_client/_utils.py @@ -6,10 +6,9 @@ import time from datetime import datetime, timezone from http import HTTPStatus -from typing import Any, Callable, Dict, List, TypeVar, cast +from typing import Any, Callable, Dict, List, Optional, Tuple, TypeVar, cast from ._errors import ApifyApiError -from ._types import JSONSerializable PARSE_DATE_FIELDS_MAX_DEPTH = 3 PARSE_DATE_FIELDS_KEY_SUFFIX = 'At' @@ -134,30 +133,19 @@ def _catch_not_found_or_throw(exc: ApifyApiError) -> None: return None -def _encode_json_to_base64(data: JSONSerializable) -> bytes: - """Encode JSON serializable data to base64 string.""" - return base64.b64encode(json.dumps(data).encode("utf-8")) - +def _encode_webhook_list_to_base64(webhooks: List[Dict]) -> bytes: + """Encode a list of dictionaries representing webhooks to their base64-encoded representation for the API.""" + data = [] + for webhook in webhooks: + webhook_representation = { + 'eventTypes': webhook['event_types'], + 'requestUrl': webhook['request_url'], + } + if 'payload_template' in webhook: + webhook_representation['payloadTemplate'] = webhook['payload_template'] + data.append(webhook_representation) -def _decode_base64_to_json(encoded_data: bytes) -> JSONSerializable: - """Decode base64 string into JSONSerializable data. - - >>> _decode_base64_to_json(_encode_json_to_base64(1)) - 1 - >>> _decode_base64_to_json(_encode_json_to_base64(1.1)) - 1.1 - >>> _decode_base64_to_json(_encode_json_to_base64("apify")) - 'apify' - >>> _decode_base64_to_json(_encode_json_to_base64(True)) - True - >>> _decode_base64_to_json(_encode_json_to_base64(None)) is None - True - >>> _decode_base64_to_json(_encode_json_to_base64([1, 2, 3])) - [1, 2, 3] - >>> _decode_base64_to_json(_encode_json_to_base64({"apify": "rocks"})) - {'apify': 'rocks'} - """ - return cast(JSONSerializable, json.loads(base64.b64decode(encoded_data).decode("utf-8"))) + return base64.b64encode(json.dumps(data).encode("utf-8")) def _filter_out_none_values(dictionary: Dict) -> Dict: @@ -198,3 +186,18 @@ def _snake_case_to_camel_case(str_snake_case: str) -> str: part.capitalize() if i > 0 else part for i, part in enumerate(str_snake_case.split("_")) ]) + + +def _encode_key_value_store_record_value(value: Any, content_type: Optional[str] = None) -> Tuple[Any, str]: + if not content_type: + if _is_file_or_bytes(value): + content_type = 'application/octet-stream' + elif isinstance(value, str): + content_type = 'text/plain; charset=utf-8' + else: + content_type = 'application/json; charset=utf-8' + + if 'application/json' in content_type and not _is_file_or_bytes(value) and not isinstance(value, str): + value = json.dumps(value, ensure_ascii=False, indent=2).encode("utf-8") + + return (value, content_type) diff --git a/src/apify_client/client.py b/src/apify_client/client.py index a8774708..e0fac992 100644 --- a/src/apify_client/client.py +++ b/src/apify_client/client.py @@ -2,6 +2,8 @@ from ._http_client import _HTTPClient from .clients import ( + ActorClient, + ActorCollectionClient, BuildClient, BuildCollectionClient, DatasetClient, @@ -11,6 +13,8 @@ LogClient, RequestQueueClient, RequestQueueCollectionClient, + RunClient, + RunCollectionClient, ScheduleClient, ScheduleCollectionClient, TaskClient, @@ -56,6 +60,7 @@ def __init__( def _options(self) -> Dict: return { + 'root_client': self, 'base_url': self.base_url, 'http_client': self.http_client, 'params': { @@ -63,6 +68,18 @@ def _options(self) -> Dict: }, } + def actor(self, actor_id: str) -> ActorClient: + """Retrieve the sub-client for manipulating a single actor. + + Args: + actor_id (str): ID of the actor to be manipulated + """ + return ActorClient(resource_id=actor_id, **self._options()) + + def actors(self) -> ActorCollectionClient: + """Retrieve the sub-client for manipulating actors.""" + return ActorCollectionClient(**self._options()) + def build(self, build_id: str) -> BuildClient: """Retrieve the sub-client for manipulating a single actor build. @@ -75,6 +92,18 @@ def builds(self) -> BuildCollectionClient: """Retrieve the sub-client for querying multiple builds of a user.""" return BuildCollectionClient(**self._options()) + def run(self, run_id: str) -> RunClient: + """Retrieve the sub-client for manipulating a single actor run. + + Args: + run_id (str): ID of the actor run to be manipulated + """ + return RunClient(resource_id=run_id, **self._options()) + + def runs(self) -> RunCollectionClient: + """Retrieve the sub-client for querying multiple actor runs of a user.""" + return RunCollectionClient(**self._options()) + def dataset(self, dataset_id: str) -> DatasetClient: """Retrieve the sub-client for manipulating a single dataset. @@ -165,7 +194,7 @@ def task(self, task_id: str) -> TaskClient: return TaskClient(resource_id=task_id, **self._options()) def tasks(self) -> TaskCollectionClient: - """Retrieve the sub-client for retrieving tasks.""" + """Retrieve the sub-client for manipulating tasks.""" return TaskCollectionClient(**self._options()) def user(self, user_id: Optional[str] = None) -> UserClient: diff --git a/src/apify_client/clients/__init__.py b/src/apify_client/clients/__init__.py index 5adfafef..92c27a27 100644 --- a/src/apify_client/clients/__init__.py +++ b/src/apify_client/clients/__init__.py @@ -1,5 +1,9 @@ from .base import ActorJobBaseClient, BaseClient, ResourceClient, ResourceCollectionClient from .resource_clients import ( + ActorClient, + ActorCollectionClient, + ActorVersionClient, + ActorVersionCollectionClient, BuildClient, BuildCollectionClient, DatasetClient, @@ -9,6 +13,8 @@ LogClient, RequestQueueClient, RequestQueueCollectionClient, + RunClient, + RunCollectionClient, ScheduleClient, ScheduleCollectionClient, TaskClient, @@ -25,6 +31,10 @@ 'BaseClient', 'ResourceClient', 'ResourceCollectionClient', + 'ActorClient', + 'ActorCollectionClient', + 'ActorVersionClient', + 'ActorVersionCollectionClient', 'BuildClient', 'BuildCollectionClient', 'DatasetClient', @@ -34,6 +44,8 @@ 'LogClient', 'RequestQueueClient', 'RequestQueueCollectionClient', + 'RunClient', + 'RunCollectionClient', 'ScheduleClient', 'ScheduleCollectionClient', 'TaskClient', diff --git a/src/apify_client/clients/base/base_client.py b/src/apify_client/clients/base/base_client.py index 780cc509..f8d90a35 100644 --- a/src/apify_client/clients/base/base_client.py +++ b/src/apify_client/clients/base/base_client.py @@ -1,8 +1,14 @@ -from typing import Any, Dict, Optional +from __future__ import annotations + +from typing import TYPE_CHECKING, Any, Dict, Optional from ..._http_client import _HTTPClient from ..._utils import _to_safe_id +# Conditional import only executed when type checking, otherwise we'd get circular dependency issues +if TYPE_CHECKING: + from ...client import ApifyClient + class BaseClient: """Base class for sub-clients.""" @@ -11,6 +17,7 @@ def __init__( self, *, base_url: str, + root_client: ApifyClient, http_client: _HTTPClient, resource_id: Optional[str] = None, resource_path: str, @@ -20,6 +27,7 @@ def __init__( Args: base_url (str): Base URL of the API server + root_client (ApifyClient): The ApifyClient instance under which this resource client exists http_client (_HTTPClient): The _HTTPClient instance to be used in this client resource_id (str): ID of the manipulated resource, in case of a single-resource client resource_path (str): Path to the resource's endpoint on the API server @@ -29,6 +37,7 @@ def __init__( raise ValueError('resource_path must not end with "/"') self.base_url = base_url + self.root_client = root_client self.http_client = http_client self.params = params or {} self.resource_path = resource_path @@ -54,6 +63,7 @@ def _sub_resource_init_options(self, **kwargs: Any) -> Dict: "base_url": self.url, "http_client": self.http_client, "params": self.params, + "root_client": self.root_client, } return { diff --git a/src/apify_client/clients/resource_clients/__init__.py b/src/apify_client/clients/resource_clients/__init__.py index 4b71bc63..a77ecb9d 100644 --- a/src/apify_client/clients/resource_clients/__init__.py +++ b/src/apify_client/clients/resource_clients/__init__.py @@ -1,3 +1,7 @@ +from .actor import ActorClient +from .actor_collection import ActorCollectionClient +from .actor_version import ActorVersionClient +from .actor_version_collection import ActorVersionCollectionClient from .build import BuildClient from .build_collection import BuildCollectionClient from .dataset import DatasetClient @@ -7,6 +11,8 @@ from .log import LogClient from .request_queue import RequestQueueClient from .request_queue_collection import RequestQueueCollectionClient +from .run import RunClient +from .run_collection import RunCollectionClient from .schedule import ScheduleClient from .schedule_collection import ScheduleCollectionClient from .task import TaskClient @@ -18,22 +24,28 @@ from .webhook_dispatch_collection import WebhookDispatchCollectionClient __all__ = [ + 'ActorClient', + 'ActorCollectionClient', + 'ActorVersionClient', + 'ActorVersionCollectionClient', + 'RunClient', + 'RunCollectionClient', 'BuildClient', 'BuildCollectionClient', 'DatasetClient', 'DatasetCollectionClient', 'KeyValueStoreClient', 'KeyValueStoreCollectionClient', - 'LogClient', 'RequestQueueClient', 'RequestQueueCollectionClient', - 'ScheduleClient', - 'ScheduleCollectionClient', - 'TaskClient', - 'TaskCollectionClient', - 'UserClient', + 'LogClient', 'WebhookClient', 'WebhookCollectionClient', 'WebhookDispatchClient', 'WebhookDispatchCollectionClient', + 'TaskClient', + 'TaskCollectionClient', + 'ScheduleClient', + 'ScheduleCollectionClient', + 'UserClient', ] diff --git a/src/apify_client/clients/resource_clients/actor.py b/src/apify_client/clients/resource_clients/actor.py new file mode 100644 index 00000000..dad708d9 --- /dev/null +++ b/src/apify_client/clients/resource_clients/actor.py @@ -0,0 +1,317 @@ +from typing import Any, Dict, List, Optional + +from ..._consts import ActorJobStatus +from ..._utils import _encode_key_value_store_record_value, _encode_webhook_list_to_base64, _parse_date_fields, _pluck_data +from ..base import ResourceClient +from .actor_version import ActorVersionClient +from .actor_version_collection import ActorVersionCollectionClient +from .build_collection import BuildCollectionClient +from .run import RunClient +from .run_collection import RunCollectionClient +from .webhook_collection import WebhookCollectionClient + + +class ActorClient(ResourceClient): + """Sub-client for manipulating a single actor.""" + + def __init__(self, *args: Any, **kwargs: Any) -> None: + """Initialize the ActorClient.""" + resource_path = kwargs.pop('resource_path', 'acts') + super().__init__(*args, resource_path=resource_path, **kwargs) + + def get(self) -> Optional[Dict]: + """Retrieve the actor. + + https://docs.apify.com/api/v2#/reference/actors/actor-object/get-actor + + Returns: + dict, optional: The retrieved actor + """ + return self._get() + + def update( + self, + *, + name: Optional[str] = None, + title: Optional[str] = None, + description: Optional[str] = None, + seo_title: Optional[str] = None, + seo_description: Optional[str] = None, + versions: Optional[List[Dict]] = None, + restart_on_error: Optional[bool] = None, + is_public: Optional[bool] = None, + is_deprecated: Optional[bool] = None, + is_anonymously_runnable: Optional[bool] = None, + categories: Optional[List[str]] = None, + default_run_build: Optional[str] = None, + default_run_memory_mbytes: Optional[int] = None, + default_run_timeout_secs: Optional[int] = None, + example_run_input_body: Optional[Any] = None, + example_run_input_content_type: Optional[str] = None, + ) -> Dict: + """Update the actor with the specified fields. + + https://docs.apify.com/api/v2#/reference/actors/actor-object/update-actor + + Args: + name (str, optional): The name of the actor + title (str, optional): The title of the actor (human-readable) + description (str, optional): The description for the actor + seo_title (str, optional): The title of the actor optimized for search engines + seo_description (str, optional): The description of the actor optimized for search engines + versions (list of dict, optional): The list of actor versions + restart_on_error (bool, optional): If true, the main actor run process will be restarted whenever it exits with a non-zero status code. + is_public (bool, optional): Whether the actor is public. + is_deprecated (bool, optional): Whether the actor is deprecated. + is_anonymously_runnable (bool, optional): Whether the actor is anonymously runnable. + categories (list of str, optional): The categories to which the actor belongs to. + default_run_build (str, optional): Tag or number of the build that you want to run by default. + default_run_memory_mbytes (int, optional): Default amount of memory allocated for the runs of this actor, in megabytes. + default_run_timeout_secs (int, optional): Default timeout for the runs of this actor in seconds. + example_run_input_body (Any, optional): Input to be prefilled as default input to new users of this actor. + example_run_input_content_type (str, optional): The content type of the example run input. + + Returns: + dict: The updated actor + """ + actor_fields: Dict[str, Any] = {} + if name is not None: + actor_fields['name'] = name + if title is not None: + actor_fields['title'] = title + if description is not None: + actor_fields['description'] = description + if seo_title is not None: + actor_fields['seoTitle'] = seo_title + if seo_description is not None: + actor_fields['seoDescription'] = seo_description + if versions is not None: + actor_fields['versions'] = versions + if restart_on_error is not None: + actor_fields['restartOnError'] = restart_on_error + if is_public is not None: + actor_fields['isPublic'] = is_public + if is_deprecated is not None: + actor_fields['isDeprecated'] = is_deprecated + if is_anonymously_runnable is not None: + actor_fields['isAnonymouslyRunnable'] = is_anonymously_runnable + if categories is not None: + actor_fields['categories'] = categories + + default_run_options: Dict[str, Any] = {} + if default_run_build is not None: + default_run_options['build'] = default_run_build + if default_run_memory_mbytes is not None: + default_run_options['memoryMbytes'] = default_run_memory_mbytes + if default_run_timeout_secs is not None: + default_run_options['timeoutSecs'] = default_run_timeout_secs + if default_run_options: + actor_fields['defaultRunOptions'] = default_run_options + + example_run_input: Dict[str, Any] = {} + if example_run_input_body is not None: + example_run_input['body'] = example_run_input_body + if example_run_input_content_type is not None: + example_run_input['contentType'] = example_run_input_content_type + if example_run_input: + actor_fields['exampleRunInput'] = example_run_input + + return self._update(actor_fields) + + def delete(self) -> None: + """Delete the actor. + + https://docs.apify.com/api/v2#/reference/actors/actor-object/delete-actor + """ + return self._delete() + + def start( + self, + *, + run_input: Optional[Any] = None, + content_type: Optional[str] = None, + build: Optional[str] = None, + memory_mbytes: Optional[int] = None, + timeout_secs: Optional[int] = None, + wait_for_finish: Optional[int] = None, + webhooks: Optional[List[Dict]] = None, + ) -> Dict: + """Start the actor and immediately return the Run object. + + https://docs.apify.com/api/v2#/reference/actors/run-collection/run-actor + + Args: + run_input (Any, optional): The input to pass to the actor run. + content_type (str, optional): The content type of the input. + build (str, optional): Specifies the actor build to run. It can be either a build tag or build number. + By default, the run uses the build specified in the default run configuration for the actor (typically latest). + memory_mbytes (int, optional): Memory limit for the run, in megabytes. + By default, the run uses a memory limit specified in the default run configuration for the actor. + timeout_secs (int, optional): Optional timeout for the run, in seconds. + By default, the run uses timeout specified in the default run configuration for the actor. + wait_for_finish (int, optional): The maximum number of seconds the server waits for the run to finish. + By default, it is 0, the maximum value is 300. + webhooks (list of dict, optional): Optional ad-hoc webhooks (https://docs.apify.com/webhooks/ad-hoc-webhooks) + associated with the actor run which can be used to receive a notification, + e.g. when the actor finished or failed. + If you already have a webhook set up for the actor or task, you do not have to add it again here. + Each webhook is represented by a dictionary containing these items: + * ``event_types``: list of ``WebhookEventType`` values which trigger the webhook + * ``request_url``: URL to which to send the webhook HTTP request + * ``payload_template`` (optional): Optional template for the request payload + + Returns: + dict: The run object + """ + run_input, content_type = _encode_key_value_store_record_value(run_input, content_type) + + request_params = self._params( + build=build, + memory=memory_mbytes, + timeout=timeout_secs, + waitForFinish=wait_for_finish, + webhooks=_encode_webhook_list_to_base64(webhooks) if webhooks is not None else None, + ) + + response = self.http_client.call( + url=self._url('runs'), + method='POST', + headers={'content-type': content_type}, + data=run_input, + params=request_params, + ) + + return _parse_date_fields(_pluck_data(response.json())) + + def call( + self, + *, + run_input: Optional[Any] = None, + content_type: Optional[str] = None, + build: Optional[str] = None, + memory_mbytes: Optional[int] = None, + timeout_secs: Optional[int] = None, + webhooks: Optional[List[Dict]] = None, + wait_secs: Optional[int] = None, + ) -> Optional[Dict]: + """Start the actor and wait for it to finish before returning the Run object. + + It waits indefinitely, unless the wait_secs argument is provided. + + https://docs.apify.com/api/v2#/reference/actors/run-collection/run-actor + + Args: + run_input (Any, optional): The input to pass to the actor run. + content_type (str, optional): The content type of the input. + build (str, optional): Specifies the actor build to run. It can be either a build tag or build number. + By default, the run uses the build specified in the default run configuration for the actor (typically latest). + memory_mbytes (int, optional): Memory limit for the run, in megabytes. + By default, the run uses a memory limit specified in the default run configuration for the actor. + timeout_secs (int, optional): Optional timeout for the run, in seconds. + By default, the run uses timeout specified in the default run configuration for the actor. + webhooks (list, optional): Optional webhooks (https://docs.apify.com/webhooks) associated with the actor run, + which can be used to receive a notification, e.g. when the actor finished or failed. + If you already have a webhook set up for the actor, you do not have to add it again here. + wait_secs (int, optional): The maximum number of seconds the server waits for the run to finish. If not provided, waits indefinitely. + + Returns: + dict: The run object + """ + started_run = self.start( + run_input=run_input, + content_type=content_type, + build=build, + memory_mbytes=memory_mbytes, + timeout_secs=timeout_secs, + webhooks=webhooks, + ) + + return self.root_client.run(started_run['id']).wait_for_finish(wait_secs=wait_secs) + + def build( + self, + *, + version_number: str, + beta_packages: Optional[bool] = None, + tag: Optional[str] = None, + use_cache: Optional[bool] = None, + wait_for_finish: Optional[int] = None, + ) -> Dict: + """Build the actor. + + https://docs.apify.com/api/v2#/reference/actors/build-collection/build-actor + + Args: + version_number (str): Actor version number to be built. + beta_packages (bool, optional): If True, then the actor is built with beta versions of Apify NPM packages. + By default, the build uses latest stable packages. + tag (str, optional): Tag to be applied to the build on success. By default, the tag is taken from the actor version's buildTag property. + use_cache (bool, optional): If true, the actor's Docker container will be rebuilt using layer cache + (https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#leverage-build-cache). + This is to enable quick rebuild during development. + By default, the cache is not used. + wait_for_finish (int, optional): The maximum number of seconds the server waits for the build to finish before returning. + By default it is 0, the maximum value is 300. + + Returns: + dict: The build object + """ + request_params = self._params( + version=version_number, + betaPackages=beta_packages, + tag=tag, + useCache=use_cache, + waitForFinish=wait_for_finish, + ) + + response = self.http_client.call( + url=self._url('builds'), + method='POST', + params=request_params, + ) + + return _parse_date_fields(_pluck_data(response.json())) + + def builds(self) -> BuildCollectionClient: + """Retrieve a client for the builds of this actor.""" + return BuildCollectionClient(**self._sub_resource_init_options(resource_path='builds')) + + def runs(self) -> RunCollectionClient: + """Retrieve a client for the runs of this actor.""" + return RunCollectionClient(**self._sub_resource_init_options(resource_path='runs')) + + def last_run(self, *, status: Optional[ActorJobStatus] = None) -> RunClient: + """Retrieve the client for the last run of this actor. + + Last run is retrieved based on the start time of the runs. + + Args: + status (str, optional): Consider only runs with this status. + + Returns: + RunClient: The resource client for the last run of this actor. + """ + return RunClient(**self._sub_resource_init_options( + resource_id='last', + resource_path='runs', + params=self._params(status=status), + )) + + def versions(self) -> ActorVersionCollectionClient: + """Retrieve a client for the versions of this actor.""" + return ActorVersionCollectionClient(**self._sub_resource_init_options()) + + def version(self, version_number: str) -> ActorVersionClient: + """Retrieve the client for the specified version of this actor. + + Args: + version_number (str): The version number for which to retrieve the resource client. + + Returns: + ActorVersionClient: The resource client for the specified actor version. + """ + return ActorVersionClient(**self._sub_resource_init_options(resource_id=version_number)) + + def webhooks(self) -> WebhookCollectionClient: + """Retrieve a client for webhooks associated with this actor.""" + return WebhookCollectionClient(**self._sub_resource_init_options()) diff --git a/src/apify_client/clients/resource_clients/actor_collection.py b/src/apify_client/clients/resource_clients/actor_collection.py new file mode 100644 index 00000000..28c9ca90 --- /dev/null +++ b/src/apify_client/clients/resource_clients/actor_collection.py @@ -0,0 +1,124 @@ +from typing import Any, Dict, List, Optional + +from ..base import ResourceCollectionClient + + +class ActorCollectionClient(ResourceCollectionClient): + """Sub-client for manipulating actors.""" + + def __init__(self, *args: Any, **kwargs: Any) -> None: + """Initialize the ActorCollectionClient.""" + resource_path = kwargs.pop('resource_path', 'acts') + super().__init__(*args, resource_path=resource_path, **kwargs) + + def list( + self, + *, + my: Optional[bool] = None, + limit: Optional[int] = None, + offset: Optional[int] = None, + desc: Optional[bool] = None, + ) -> Dict: + """List the actors the user has created or used. + + https://docs.apify.com/api/v2#/reference/actors/actor-collection/get-list-of-actors + + Args: + my (bool, optional): If True, will return only actors which the user has created themselves. + limit (int, optional): How many actors to list + offset (int, optional): What actor to include as first when retrieving the list + desc (bool, optional): Whether to sort the actors in descending order based on their creation date + + Returns: + dict: The list of available actors matching the specified filters. + """ + return self._list(my=my, limit=limit, offset=offset, desc=desc) + + def create( + self, + *, + name: str, + title: Optional[str] = None, + description: Optional[str] = None, + seo_title: Optional[str] = None, + seo_description: Optional[str] = None, + versions: Optional[List[Dict]] = None, + restart_on_error: Optional[bool] = None, + is_public: Optional[bool] = None, + is_deprecated: Optional[bool] = None, + is_anonymously_runnable: Optional[bool] = None, + categories: Optional[List[str]] = None, + default_run_build: Optional[str] = None, + default_run_memory_mbytes: Optional[int] = None, + default_run_timeout_secs: Optional[int] = None, + example_run_input_body: Optional[Any] = None, + example_run_input_content_type: Optional[str] = None, + ) -> Dict: + """Create a new actor. + + https://docs.apify.com/api/v2#/reference/actors/actor-collection/create-actor + + Args: + name (str): The name of the actor + title (str, optional): The title of the actor (human-readable) + description (str, optional): The description for the actor + seo_title (str, optional): The title of the actor optimized for search engines + seo_description (str, optional): The description of the actor optimized for search engines + versions (list of dict, optional): The list of actor versions + restart_on_error (bool, optional): If true, the main actor run process will be restarted whenever it exits with a non-zero status code. + is_public (bool, optional): Whether the actor is public. + is_deprecated (bool, optional): Whether the actor is deprecated. + is_anonymously_runnable (bool, optional): Whether the actor is anonymously runnable. + categories (list of str, optional): The categories to which the actor belongs to. + default_run_build (str, optional): Tag or number of the build that you want to run by default. + default_run_memory_mbytes (int, optional): Default amount of memory allocated for the runs of this actor, in megabytes. + default_run_timeout_secs (int, optional): Default timeout for the runs of this actor in seconds. + example_run_input_body (Any, optional): Input to be prefilled as default input to new users of this actor. + example_run_input_content_type (str, optional): The content type of the example run input. + + Returns: + dict: The created actor. + """ + actor_fields: Dict[str, Any] = {} + if name is not None: + actor_fields['name'] = name + if title is not None: + actor_fields['title'] = title + if description is not None: + actor_fields['description'] = description + if seo_title is not None: + actor_fields['seoTitle'] = seo_title + if seo_description is not None: + actor_fields['seoDescription'] = seo_description + if versions is not None: + actor_fields['versions'] = versions + if restart_on_error is not None: + actor_fields['restartOnError'] = restart_on_error + if is_public is not None: + actor_fields['isPublic'] = is_public + if is_deprecated is not None: + actor_fields['isDeprecated'] = is_deprecated + if is_anonymously_runnable is not None: + actor_fields['isAnonymouslyRunnable'] = is_anonymously_runnable + if categories is not None: + actor_fields['categories'] = categories + + default_run_options: Dict[str, Any] = {} + if default_run_build is not None: + default_run_options['build'] = default_run_build + if default_run_memory_mbytes is not None: + default_run_options['memoryMbytes'] = default_run_memory_mbytes + if default_run_timeout_secs is not None: + default_run_options['timeoutSecs'] = default_run_timeout_secs + if default_run_options: + actor_fields['defaultRunOptions'] = default_run_options + + example_run_input: Dict[str, Any] = {} + if example_run_input_body is not None: + example_run_input['body'] = example_run_input_body + if example_run_input_content_type is not None: + example_run_input['contentType'] = example_run_input_content_type + if example_run_input: + actor_fields['exampleRunInput'] = example_run_input + + return self._create(actor_fields) diff --git a/src/apify_client/clients/resource_clients/actor_version.py b/src/apify_client/clients/resource_clients/actor_version.py new file mode 100644 index 00000000..2e767c32 --- /dev/null +++ b/src/apify_client/clients/resource_clients/actor_version.py @@ -0,0 +1,95 @@ +from typing import Any, Dict, List, Optional + +from ..._consts import ActorSourceType +from ..base import ResourceClient + + +class ActorVersionClient(ResourceClient): + """Sub-client for manipulating a single actor version.""" + + def __init__(self, *args: Any, **kwargs: Any) -> None: + """Initialize the ActorVersionClient.""" + resource_path = kwargs.pop('resource_path', 'versions') + super().__init__(*args, resource_path=resource_path, **kwargs) + + def get(self) -> Optional[Dict]: + """Return information about the actor version. + + https://docs.apify.com/api/v2#/reference/actors/version-object/get-version + + Returns: + dict, optional: The retrieved actor version data + """ + return self._get() + + def update( + self, + *, + build_tag: Optional[str] = None, + env_vars: Optional[List[Dict]] = None, + apply_env_vars_to_build: Optional[bool] = None, + source_type: Optional[ActorSourceType] = None, + source_code: Optional[str] = None, + base_docker_image: Optional[str] = None, + source_files: Optional[List[Dict]] = None, + git_repo_url: Optional[str] = None, + tarball_url: Optional[str] = None, + github_gist_url: Optional[str] = None, + ) -> Dict: + """Update the actor version with specified fields. + + https://docs.apify.com/api/v2#/reference/actors/version-object/update-version + + Args: + build_tag (str, optional): Tag that is automatically set to the latest successful build of the current version. + env_vars (list of dict, optional): Environment variables that will be available to the actor run process, + and optionally also to the build process. See the API docs for their exact structure. + apply_env_vars_to_build (bool, optional): Whether the environment variables specified for the actor run + will also be set to the actor build process. + source_type (str, optional): What source type is the actor version using. Can be one of + `SOURCE_CODE`, `SOURCE_FILES`, `GIT_REPO`, `TARBALL` and `GITHUB_GIST`. + source_code (str, optional): Source code as a single JavaScript/Node.js file, using the base Docker image specified in `baseDockerImage`. + Required when `source_type` is `SOURCE_CODE`. + base_docker_image (str, optional): The base Docker image to use for single-file actors. Required when `source_type` is `SOURCE_CODE`. + source_files (list of dict, optional): Source code comprised of multiple files, each an item of the array. + Required when `source_type` is `SOURCE_FILES`. See the API docs for the exact structure. + git_repo_url (str, optional): The URL of a Git repository from which the source code will be cloned. + Required when `source_type` is `GIT_REPO`. + tarball_url (str, optional): The URL of a tarball or a zip archive from which the source code will be downloaded. + Required when `source_type` is `TARBALL`. + github_gist_url (str, optional): The URL of a GitHub Gist from which the source will be downloaded. + Required when `source_type` is `GITHUB_GIST`. + + Returns: + dict: The updated actor version + """ + version_fields: Dict[str, Any] = {} + if build_tag is not None: + version_fields['buildTag'] = build_tag + if env_vars is not None: + version_fields['envVars'] = env_vars + if apply_env_vars_to_build is not None: + version_fields['applyEnvVarsToBuild'] = apply_env_vars_to_build + if source_type is not None: + version_fields['sourceType'] = source_type + if source_code is not None: + version_fields['sourceCode'] = source_code + if base_docker_image is not None: + version_fields['baseDockerImage'] = base_docker_image + if source_files is not None: + version_fields['sourceFiles'] = source_files + if git_repo_url is not None: + version_fields['gitRepoUrl'] = git_repo_url + if tarball_url is not None: + version_fields['tarballUrl'] = tarball_url + if github_gist_url is not None: + version_fields['gitHubGistUrl'] = github_gist_url + + return self._update(version_fields) + + def delete(self) -> None: + """Delete the actor version. + + https://docs.apify.com/api/v2#/reference/actors/version-object/delete-version + """ + return self._delete() diff --git a/src/apify_client/clients/resource_clients/actor_version_collection.py b/src/apify_client/clients/resource_clients/actor_version_collection.py new file mode 100644 index 00000000..3ac820f4 --- /dev/null +++ b/src/apify_client/clients/resource_clients/actor_version_collection.py @@ -0,0 +1,92 @@ +from typing import Any, Dict, List, Optional + +from ..._consts import ActorSourceType +from ..base import ResourceCollectionClient + + +class ActorVersionCollectionClient(ResourceCollectionClient): + """Sub-client for manipulating actor versions.""" + + def __init__(self, *args: Any, **kwargs: Any) -> None: + """Initialize the ActorVersionCollectionClient with the passed arguments.""" + resource_path = kwargs.pop('resource_path', 'versions') + super().__init__(*args, resource_path=resource_path, **kwargs) + + def list(self) -> Dict: + """List the available actor versions. + + https://docs.apify.com/api/v2#/reference/actors/version-collection/get-list-of-versions + + Returns: + dict: The list of available actor versions. + """ + return self._list() + + def create( + self, + *, + version_number: str, + build_tag: Optional[str] = None, + env_vars: Optional[List[Dict]] = None, + apply_env_vars_to_build: Optional[bool] = None, + source_type: ActorSourceType, + source_code: Optional[str] = None, + base_docker_image: Optional[str] = None, + source_files: Optional[List[Dict]] = None, + git_repo_url: Optional[str] = None, + tarball_url: Optional[str] = None, + github_gist_url: Optional[str] = None, + ) -> Dict: + """Create a new actor version. + + https://docs.apify.com/api/v2#/reference/actors/version-collection/create-version + + Args: + version_number (str): Major and minor version of the actor (e.g. `1.0`) + build_tag (str, optional): Tag that is automatically set to the latest successful build of the current version. + env_vars (list of dict, optional): Environment variables that will be available to the actor run process, + and optionally also to the build process. See the API docs for their exact structure. + apply_env_vars_to_build (bool, optional): Whether the environment variables specified for the actor run + will also be set to the actor build process. + source_type (str): What source type is the actor version using. Can be one of + `SOURCE_CODE`, `SOURCE_FILES`, `GIT_REPO`, `TARBALL` and `GITHUB_GIST`. + source_code (str, optional): Source code as a single JavaScript/Node.js file, using the base Docker image specified in `baseDockerImage`. + Required when `source_type` is `SOURCE_CODE`. + base_docker_image (str, optional): The base Docker image to use for single-file actors. Required when `source_type` is `SOURCE_CODE`. + source_files (list of dict, optional): Source code comprised of multiple files, each an item of the array. + Required when `source_type` is `SOURCE_FILES`. See the API docs for the exact structure. + git_repo_url (str, optional): The URL of a Git repository from which the source code will be cloned. + Required when `source_type` is `GIT_REPO`. + tarball_url (str, optional): The URL of a tarball or a zip archive from which the source code will be downloaded. + Required when `source_type` is `TARBALL`. + github_gist_url (str, optional): The URL of a GitHub Gist from which the source will be downloaded. + Required when `source_type` is `GITHUB_GIST`. + + Returns: + dict: The created actor version + """ + version_fields: Dict[str, Any] = {} + if version_number is not None: + version_fields['versionNumber'] = version_number + if build_tag is not None: + version_fields['buildTag'] = build_tag + if env_vars is not None: + version_fields['envVars'] = env_vars + if apply_env_vars_to_build is not None: + version_fields['applyEnvVarsToBuild'] = apply_env_vars_to_build + if source_type is not None: + version_fields['sourceType'] = source_type + if source_code is not None: + version_fields['sourceCode'] = source_code + if base_docker_image is not None: + version_fields['baseDockerImage'] = base_docker_image + if source_files is not None: + version_fields['sourceFiles'] = source_files + if git_repo_url is not None: + version_fields['gitRepoUrl'] = git_repo_url + if tarball_url is not None: + version_fields['tarballUrl'] = tarball_url + if github_gist_url is not None: + version_fields['gitHubGistUrl'] = github_gist_url + + return self._create(version_fields) diff --git a/src/apify_client/clients/resource_clients/dataset.py b/src/apify_client/clients/resource_clients/dataset.py index e90ba432..5eeb395e 100644 --- a/src/apify_client/clients/resource_clients/dataset.py +++ b/src/apify_client/clients/resource_clients/dataset.py @@ -10,7 +10,7 @@ class DatasetClient(ResourceClient): def __init__(self, *args: Any, **kwargs: Any) -> None: """Initialize the DatasetClient.""" - resource_path = kwargs.pop('resource_path', 'dataset') + resource_path = kwargs.pop('resource_path', 'datasets') super().__init__(*args, resource_path=resource_path, **kwargs) def get(self) -> Optional[Dict]: diff --git a/src/apify_client/clients/resource_clients/key_value_store.py b/src/apify_client/clients/resource_clients/key_value_store.py index f483f7b6..5ae32923 100644 --- a/src/apify_client/clients/resource_clients/key_value_store.py +++ b/src/apify_client/clients/resource_clients/key_value_store.py @@ -1,8 +1,7 @@ -import json from typing import Any, Dict, Optional from ..._errors import ApifyApiError -from ..._utils import _catch_not_found_or_throw, _is_file_or_bytes, _parse_date_fields, _pluck_data +from ..._utils import _catch_not_found_or_throw, _encode_key_value_store_record_value, _parse_date_fields, _pluck_data from ..base import ResourceClient @@ -120,22 +119,7 @@ def set_record(self, key: str, value: Any, content_type: Optional[str] = None) - value (Any): The value to save into the record content_type (str, optional): The content type of the saved value """ - headers = None - - if not content_type: - if _is_file_or_bytes(value): - content_type = 'application/octet-stream' - elif isinstance(value, str): - content_type = 'text/plain; charset=utf-8' - else: - content_type = 'application/json; charset=utf-8' - - # TODO encode to utf-8 - - if 'application/json' in content_type and not _is_file_or_bytes(value) and not isinstance(value, str): - # TODO decide if we should keep indenting the JSON or not, it could increase the record size considerably, - # but if we gzip the requests it should not matter too much with transfer size - value = json.dumps(value, indent=2) + value, content_type = _encode_key_value_store_record_value(value, content_type) headers = {'content-type': content_type} diff --git a/src/apify_client/clients/resource_clients/run.py b/src/apify_client/clients/resource_clients/run.py new file mode 100644 index 00000000..461102e2 --- /dev/null +++ b/src/apify_client/clients/resource_clients/run.py @@ -0,0 +1,169 @@ +from typing import Any, Dict, Optional + +from ..._utils import _encode_key_value_store_record_value, _parse_date_fields, _pluck_data, _to_safe_id +from ..base import ActorJobBaseClient +from .dataset import DatasetClient +from .key_value_store import KeyValueStoreClient +from .log import LogClient +from .request_queue import RequestQueueClient + + +class RunClient(ActorJobBaseClient): + """Sub-client for manipulating a single actor run.""" + + def __init__(self, *args: Any, **kwargs: Any) -> None: + """Initialize the RunClient.""" + resource_path = kwargs.pop('resource_path', 'actor-runs') + super().__init__(*args, resource_path=resource_path, **kwargs) + + def get(self) -> Optional[Dict]: + """Return information about the actor run. + + https://docs.apify.com/api/v2#/reference/actor-runs/run-object/get-run + + Returns: + dict: The retrieved actor run data + """ + return self._get() + + def abort(self) -> Dict: + """Abort the actor run which is starting or currently running and return its details. + + https://docs.apify.com/api/v2#/reference/actor-runs/abort-run/abort-run + + Returns: + dict: The data of the aborted actor run + """ + return self._abort() + + def wait_for_finish(self, *, wait_secs: Optional[int] = None) -> Optional[Dict]: + """Wait synchronously until the run finishes or the server times out. + + Args: + wait_secs (int, optional): how long does the client wait for run to finish. None for indefinite. + + Returns: + dict, optional: The actor run data. If the status on the object is not one of the terminal statuses + (SUCEEDED, FAILED, TIMED_OUT, ABORTED), then the run has not yet finished. + """ + return self._wait_for_finish(wait_secs=wait_secs) + + def metamorph( + self, + *, + target_actor_id: str, + target_actor_build: Optional[str] = None, + run_input: Optional[Any] = None, + content_type: Optional[str] = None, + ) -> Dict: + """Transform an actor run into a run of another actor with a new input. + + https://docs.apify.com/api/v2#/reference/actor-runs/metamorph-run/metamorph-run + + Args: + target_actor_id (str): ID of the target actor that the run should be transformed into + target_actor_build (str, optional): The build of the target actor. It can be either a build tag or build number. + By default, the run uses the build specified in the default run configuration for the target actor (typically the latest build). + run_input (Any, optional): The input to pass to the new run. + content_type (str, optional): The content type of the input. + + Returns: + dict: The actor run data. + """ + run_input, content_type = _encode_key_value_store_record_value(run_input, content_type) + + safe_target_actor_id = _to_safe_id(target_actor_id) + + request_params = self._params( + targetActorId=safe_target_actor_id, + build=target_actor_build, + ) + + response = self.http_client.call( + url=self._url('metamorph'), + method='POST', + headers={'content-type': content_type}, + data=run_input, + params=request_params, + ) + + return _parse_date_fields(_pluck_data(response.json())) + + def resurrect(self) -> Dict: + """Resurrect a finished actor run. + + Only finished runs, i.e. runs with status FINISHED, FAILED, ABORTED and TIMED-OUT can be resurrected. + Run status will be updated to RUNNING and its container will be restarted with the same default storages. + + https://docs.apify.com/api/v2#/reference/actor-runs/resurrect-run/resurrect-run + + Returns: + dict: The actor run data. + """ + response = self.http_client.call( + url=self._url('resurrect'), + method='POST', + params=self._params(), + ) + + return _parse_date_fields(_pluck_data(response.json())) + + def dataset(self) -> DatasetClient: + """Get the client for the default dataset of the actor run. + + Currently this works only through `actor_client.last_run().dataset()`. + It will become available for all runs once the API supports it. + + https://docs.apify.com/api/v2#/reference/actors/last-run-object-and-its-storages + + Returns: + DatasetClient: A client allowing access to the default dataset of this actor run. + """ + return DatasetClient( + **self._sub_resource_init_options(resource_path="dataset"), + ) + + def key_value_store(self) -> KeyValueStoreClient: + """Get the client for the default key-value store of the actor run. + + Currently this works only through `actor_client.last_run().key_value_store()`. + It will become available for all runs once the API supports it. + + https://docs.apify.com/api/v2#/reference/actors/last-run-object-and-its-storages + + Returns: + KeyValueStoreClient: A client allowing access to the default key-value store of this actor run. + """ + return KeyValueStoreClient( + **self._sub_resource_init_options(resource_path="key-value-store"), + ) + + def request_queue(self) -> RequestQueueClient: + """Get the client for the default request queue of the actor run. + + Currently this works only through `actor_client.last_run().request_queue()`. + It will become available for all runs once the API supports it. + + https://docs.apify.com/api/v2#/reference/actors/last-run-object-and-its-storages + + Returns: + RequestQueueClient: A client allowing access to the default request_queue of this actor run. + """ + return RequestQueueClient( + **self._sub_resource_init_options(resource_path="request-queue"), + ) + + def log(self) -> LogClient: + """Get the client for the log of the actor run. + + Currently this works only through `actor_client.last_run().log()`. + It will become available for all runs once the API supports it. + + https://docs.apify.com/api/v2#/reference/actors/last-run-object-and-its-storages + + Returns: + LogClient: A client allowing access to the log of this actor run. + """ + return LogClient( + **self._sub_resource_init_options(resource_path="log"), + ) diff --git a/src/apify_client/clients/resource_clients/run_collection.py b/src/apify_client/clients/resource_clients/run_collection.py new file mode 100644 index 00000000..f3fcfbbc --- /dev/null +++ b/src/apify_client/clients/resource_clients/run_collection.py @@ -0,0 +1,37 @@ +from typing import Any, Dict, Optional + +from ..._consts import ActorJobStatus +from ..base import ResourceCollectionClient + + +class RunCollectionClient(ResourceCollectionClient): + """Sub-client for listing actor runs.""" + + def __init__(self, *args: Any, **kwargs: Any) -> None: + """Initialize the RunCollectionClient.""" + resource_path = kwargs.pop('resource_path', 'actor-runs') + super().__init__(*args, resource_path=resource_path, **kwargs) + + def list( + self, + *, + limit: Optional[int] = None, + offset: Optional[int] = None, + desc: Optional[bool] = None, + status: Optional[ActorJobStatus] = None, + ) -> Dict: + """List all actor runs (either of a single actor, or all user's actors, depending on where this client was initialized from). + + https://docs.apify.com/api/v2#/reference/actors/run-collection/get-list-of-runs + https://docs.apify.com/api/v2#/reference/actor-runs/run-collection/get-user-runs-list + + Args: + limit (int, optional): How many runs to retrieve + offset (int, optional): What run to include as first when retrieving the list + desc (bool, optional): Whether to sort the runs in descending order based on their start date + status (str, optional): Retrieve only runs with the provided status + + Returns: + dict: The retrieved actor runs + """ + return self._list(limit=limit, offset=offset, desc=desc, status=status) diff --git a/src/apify_client/clients/resource_clients/task.py b/src/apify_client/clients/resource_clients/task.py index 1f7a6c7d..c592a039 100644 --- a/src/apify_client/clients/resource_clients/task.py +++ b/src/apify_client/clients/resource_clients/task.py @@ -1,9 +1,11 @@ from typing import Any, Dict, List, Optional, cast from ..._consts import ActorJobStatus -from ..._errors import ApifyApiError, ApifyClientError -from ..._utils import _catch_not_found_or_throw, _encode_json_to_base64, _filter_out_none_values_recursively, _parse_date_fields, _pluck_data +from ..._errors import ApifyApiError +from ..._utils import _catch_not_found_or_throw, _encode_webhook_list_to_base64, _filter_out_none_values_recursively, _parse_date_fields, _pluck_data from ..base import ResourceClient +from .run import RunClient +from .run_collection import RunCollectionClient from .webhook_collection import WebhookCollectionClient @@ -92,9 +94,14 @@ def start( timeout_secs (int, optional): Optional timeout for the run, in seconds. By default, the run uses timeout specified in the task settings. wait_for_finish (int, optional): The maximum number of seconds the server waits for the run to finish. By default, it is 0, the maximum value is 300. - webhooks (list, optional): Optional webhooks (https://docs.apify.com/webhooks) associated with the actor run, - which can be used to receive a notification, e.g. when the actor finished or failed. - If you already have a webhook set up for the actor or task, you do not have to add it again here. + webhooks (list of dict, optional): Optional ad-hoc webhooks (https://docs.apify.com/webhooks/ad-hoc-webhooks) + associated with the actor run which can be used to receive a notification, + e.g. when the actor finished or failed. + If you already have a webhook set up for the actor or task, you do not have to add it again here. + Each webhook is represented by a dictionary containing these items: + * ``event_types``: list of ``WebhookEventType`` values which trigger the webhook + * ``request_url``: URL to which to send the webhook HTTP request + * ``payload_template`` (optional): Optional template for the request payload Returns: dict: The run object @@ -104,7 +111,7 @@ def start( memory=memory_mbytes, timeout=timeout_secs, waitForFinish=wait_for_finish, - webhooks=_encode_json_to_base64(webhooks) if webhooks is not None else [], + webhooks=_encode_webhook_list_to_base64(webhooks) if webhooks is not None else None, ) response = self.http_client.call( @@ -124,9 +131,9 @@ def call( build: Optional[str] = None, memory_mbytes: Optional[int] = None, timeout_secs: Optional[int] = None, - wait_for_finish: Optional[int] = None, webhooks: Optional[List[Dict]] = None, - ) -> Dict: + wait_secs: Optional[int] = None, + ) -> Optional[Dict]: """Start a task and wait for it to finish before returning the Run object. It waits indefinitely, unless the wait_secs argument is provided. @@ -140,27 +147,23 @@ def call( memory_mbytes (int, optional): Memory limit for the run, in megabytes. By default, the run uses a memory limit specified in the task settings. timeout_secs (int, optional): Optional timeout for the run, in seconds. By default, the run uses timeout specified in the task settings. - wait_for_finish (bool, optional): The maximum number of seconds the server waits for the run to finish. - By default, it is 0, the maximum value is 300. webhooks (list, optional): Specifies optional webhooks associated with the actor run, which can be used to receive a notification e.g. when the actor finished or failed. Note: if you already have a webhook set up for the actor or task, you do not have to add it again here. + wait_secs (int, optional): The maximum number of seconds the server waits for the task run to finish. If not provided, waits indefinitely. Returns: dict: The run object """ - raise ApifyClientError('Method not yet finished. Run subclient needs to be implemented first.') - - # run = self.start( - # task_input=task_input, - # build=build, - # memory_mbytes=memory_mbytes, - # timeout_secs=timeout_secs, - # wait_for_finish=wait_for_finish, - # webhooks=webhooks, - # ) + started_run = self.start( + task_input=task_input, + build=build, + memory_mbytes=memory_mbytes, + timeout_secs=timeout_secs, + webhooks=webhooks, + ) - # TODO - retrieve the run using Run client and wait on it + return self.root_client.run(started_run['id']).wait_for_finish(wait_secs=wait_secs) def get_input(self) -> Optional[Dict]: """Retrieve the default input for this task. @@ -197,24 +200,27 @@ def update_input(self, *, task_input: Dict) -> Dict: ) return cast(Dict, response.json()) - def last_run(self, *, status: Optional[ActorJobStatus] = None) -> None: - """Retrieve RunClient for last run of this task. + def runs(self) -> RunCollectionClient: + """Retrieve a client for the runs of this task.""" + return RunCollectionClient(**self._sub_resource_init_options(resource_path='runs')) + + def last_run(self, *, status: Optional[ActorJobStatus] = None) -> RunClient: + """Retrieve the client for the last run of this task. Last run is retrieved based on the start time of the runs. Args: - status (optional, dict): Consider only runs with this status. - """ - raise ApifyClientError('Method not yet finished. Run subclient needs to be implemented first.') - - # TODO - return run subclient for the last run + status (str, optional): Consider only runs with this status. - def runs(self) -> None: - """Retrieve RunCollectionClient for runs of this task.""" - raise ApifyClientError('Method not yet finished. Run subclient needs to be implemented first.') - - # TODO - return run collection subclient + Returns: + RunClient: The resource client for the last run of this task. + """ + return RunClient(**self._sub_resource_init_options( + resource_id='last', + resource_path='runs', + params=self._params(status=status), + )) def webhooks(self) -> WebhookCollectionClient: - """Retrieve WebhookCollectionClient for webhooks associated with this task.""" + """Retrieve a client for webhooks associated with this task.""" return WebhookCollectionClient(**self._sub_resource_init_options()) diff --git a/tests/unit/test_utils.py b/tests/unit/test_utils.py index 6dbd567c..5cd7a43d 100644 --- a/tests/unit/test_utils.py +++ b/tests/unit/test_utils.py @@ -5,6 +5,7 @@ from typing import Any, Callable from apify_client._utils import ( + _encode_webhook_list_to_base64, _is_content_type_json, _is_content_type_text, _is_content_type_xml, @@ -148,3 +149,20 @@ def bails_on_third_attempt(bail: Callable, attempt: int) -> Any: with self.assertRaises(BailException): _retry_with_exp_backoff(bails_on_third_attempt, backoff_base_millis=1) self.assertEqual(attempt_counter, 3) + + def test__encode_webhook_list_to_base64(self) -> None: + self.assertEqual(_encode_webhook_list_to_base64([]), b'W10=') + self.assertEqual( + _encode_webhook_list_to_base64([ + { + 'event_types': ['ACTOR.RUN.CREATED'], + 'request_url': 'https://example.com/run-created', + }, + { + 'event_types': ['ACTOR.RUN.SUCCEEDED'], + 'request_url': 'https://example.com/run-succeeded', + 'payload_template': '{"hello": "world", "resource":{{resource}}}', + }, + ]), + b'W3siZXZlbnRUeXBlcyI6IFsiQUNUT1IuUlVOLkNSRUFURUQiXSwgInJlcXVlc3RVcmwiOiAiaHR0cHM6Ly9leGFtcGxlLmNvbS9ydW4tY3JlYXRlZCJ9LCB7ImV2ZW50VHlwZXMiOiBbIkFDVE9SLlJVTi5TVUNDRUVERUQiXSwgInJlcXVlc3RVcmwiOiAiaHR0cHM6Ly9leGFtcGxlLmNvbS9ydW4tc3VjY2VlZGVkIiwgInBheWxvYWRUZW1wbGF0ZSI6ICJ7XCJoZWxsb1wiOiBcIndvcmxkXCIsIFwicmVzb3VyY2VcIjp7e3Jlc291cmNlfX19In1d', # noqa: E501 + )