Skip to content
Python SDK

Input & output

Read input, including secrets, and write results to default storage.

An Actor reads one input object and writes results to its default dataset and default key-value store. This page covers how Actor.get_input() resolves input, how secret input fields arrive, and the shortcuts for writing output: push_data(), get_value() and set_value().

Input

Actor.get_input()

await Actor.get_input() returns the input as a dict, or None when the run has no input. It checks these sources in order:

  1. If ACTOR_METAMORPH_COUNT is greater than 0, the INPUT-METAMORPH-<count> record in the default key-value store.
  2. The ACTOR_INPUT environment variable, decoded as base64 JSON and, failing that, as plain JSON.
  3. The record named by ACTOR_INPUT_KEY, normally INPUT, in the default key-value store.

The SDK caches the result, so later calls return the same object.

.python
actor_input = await Actor.get_input() or {}
url = actor_input.get("url", "https://example.com")

Actor.get_input_or_throw()

.python
actor_input = await Actor.get_input_or_throw()

Raises ValueError("Input does not exist") when get_input() returns None. It doesn't validate the input's shape. Use an input schema, or check required fields yourself.

Actor.input

Actor.input is a synchronous property. It returns the cached input, or it parses ACTOR_INPUT. It never reads the key-value store, so use get_input() in normal code.

Secret inputs

Fields marked isSecret in the input schema are stored encrypted. When a run starts, the platform decrypts them on the host and passes the plaintext input to the container in ACTOR_INPUT. The INPUT record keeps them encrypted, but reads with the run's own token return them decrypted. The private key never enters the container. So get_input() returns secret fields as plain values, and your code doesn't need to do anything extra. See Secret input fields.

The SDK still contains a fallback decryptor for compatibility. It runs only when APIFY_INPUT_SECRETS_PRIVATE_KEY_FILE and APIFY_INPUT_SECRETS_PRIVATE_KEY_PASSPHRASE are set, which Scrape.ly doesn't do.

Output

Actor.push_data()

.python
await Actor.push_data(data, charged_event_name=None)

Writes one JSON-serializable object, or a list of them, to the default dataset. It returns a ChargeResult.

.python
await Actor.push_data({"url": "https://example.com", "title": "Example"})
await Actor.push_data([
    {"page": 1, "value": "a"},
    {"page": 2, "value": "b"},
])

For pay-per-event Actors, pass charged_event_name to charge one event per item:

.python
result = await Actor.push_data(items, charged_event_name="result-item")
if result.event_charge_limit_reached:
    Actor.log.info("Budget reached, stopping")

When the run's maximum charge only covers part of the batch, the SDK pushes and charges only the items that fit. It drops the rest without writing them. For Actors that aren't pay-per-event, push_data() writes everything and returns an empty result.

event_name= is a deprecated alias of charged_event_name. Passing both with different values raises ValueError. Passing one of the synthetic default-dataset event names raises ValueError too. See Charging.

Actor.get_value() and Actor.set_value()

These are shortcuts for the default key-value store:

.python
state = await Actor.get_value("STATE", default_value={"cursor": None})
await Actor.set_value("STATE", {"cursor": "next"})
await Actor.set_value("PAGE_HTML", "<h1>Hello</h1>", content_type="text/html")
ParameterMeaning
keyRecord key
valueRecord value. Without content_type, the value is stored as JSON
content_typeMIME type to store the record with

To delete a record, open the store and call delete_value():

.python
store = await Actor.open_key_value_store()
await store.delete_value("TEMPORARY")

On platform storage, set_value(key, None) also deletes the record.

Always await writes. For other stores and for reading results back, see Storages.