You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Build the SDK on apify-client v3 and drop the apify-shared dependency: typed
model responses (Run, pricing info, webhook representations), Literal string
aliases instead of StrEnum classes, the new tiered timeout system, and a
slimmed-down @DataClass Webhook.
Collapse the SDK's standalone pricing-info models into thin subclasses of the
apify-client models that relax only the fields the platform's
APIFY_ACTOR_PRICING_INFO env var omits, so Run.pricing_info from the API flows
through unchanged and the converter is removed. Configuration.actor_pricing_info
keeps its discriminated-union shape (no public API change), and event_price_usd
is now correctly optional so tier-priced pay-per-event Actors no longer fail
env-var validation.
Document these changes in the v4 upgrading guide.
Copy file name to clipboardExpand all lines: docs/04_upgrading/upgrading_to_v4.md
+134Lines changed: 134 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -50,3 +50,137 @@ run = await Actor.call('user/actor', timeout='inherit')
50
50
The deprecated `latest_sdk_version`, `log_format`, and `standby_port` fields have been removed from `Configuration`:
51
51
- In place of `standby_port`, use `web_server_port`.
52
52
-`latest_sdk_version` and `log_format` don't have replacement. SDK version checking isn't supported for the Python SDK and the log format should be adjusted in code instead.
53
+
54
+
## Built on `apify-client` v3
55
+
56
+
The SDK is now built on [`apify-client`](https://docs.apify.com/api/client/python) v3 and no longer depends on `apify-shared`. The sections below cover the user-visible consequences; see the client's [Upgrading to v3](https://docs.apify.com/api/client/python/docs/upgrading/upgrading-to-v3) guide for the full list of changes in the client itself.
57
+
58
+
## Typed responses
59
+
60
+
`Actor.start`, `Actor.abort`, `Actor.call`, and `Actor.call_task` now return `apify_client._models.Run` instead of the SDK-side `ActorRun`. Both are [Pydantic](https://docs.pydantic.dev/latest/) models with the same snake_case fields, so field access is unchanged — only the type and import path differ. The SDK no longer ships its own response models (`apify._models` has been removed); response shapes come from `apify-client`.
61
+
62
+
## Literal string aliases instead of StrEnum classes
63
+
64
+
Generated enum-like types are now [`Literal`](https://docs.python.org/3/library/typing.html#typing.Literal) string aliases instead of `StrEnum` classes. Pass plain strings instead of enum members.
65
+
66
+
-`apify.WebhookEventType` is now a `Literal[...]` instead of a `StrEnum`. Use plain string values (`'ACTOR.RUN.FAILED'`) instead of enum members.
67
+
-`apify_shared.consts.ActorEventTypes` (a `StrEnum`) is replaced by `apify.ActorEventTypes`, now a `Literal['systemInfo', 'persistState', 'migrating', 'aborting']`. For runtime values, use `apify.Event` (re-exported from Crawlee) instead of enum members.
68
+
69
+
**Before (v3.x):**
70
+
71
+
```python
72
+
from apify import Actor
73
+
from apify_shared.consts import ActorEventTypes
74
+
75
+
Actor.on(ActorEventTypes.SYSTEM_INFO, callback)
76
+
```
77
+
78
+
**Now (v4.0):**
79
+
80
+
```python
81
+
from apify import Actor, Event
82
+
83
+
Actor.on(Event.SYSTEM_INFO, callback)
84
+
```
85
+
86
+
## Actor pricing info models
87
+
88
+
The Actor pricing-info models exposed through `Actor.configuration.actor_pricing_info` — `FreeActorPricingInfo`, `FlatPricePerMonthActorPricingInfo`, `PricePerDatasetItemActorPricingInfo`, `PayPerEventActorPricingInfo`, and the nested `ActorChargeEvent` / `PricingPerEvent` — are now thin subclasses of the corresponding `apify-client` models instead of standalone SDK copies. The discriminated-union shape is unchanged, so existing access (`pricing_model`, per-event titles and prices) keeps working; the models now expose the full `apify-client` field set, and a charge event's `event_price_usd` is optional (it is unset for tier-priced events). `ChargingManager.get_pricing_info()` is unchanged.
89
+
90
+
## `Webhook` API simplified
91
+
92
+
The `Webhook` model has been slimmed down to only the fields a user sets when defining a webhook. Server-populated response fields (`id`, `created_at`, `modified_at`, `user_id`, `is_ad_hoc`, `condition`, `last_dispatch`, `stats`) and the unused `WebhookCondition` helper class have been removed. `Webhook` is now a plain `@dataclass` instead of a Pydantic `BaseModel` — construct it with snake_case kwargs; `.model_dump()` / `.model_validate()` are gone.
93
+
94
+
The retry and idempotency kwargs that used to live on `Actor.add_webhook` have moved onto the `Webhook` instance itself.
The `idempotency_key` kwarg form on `Actor.add_webhook` still works for one more release but emits a `DeprecationWarning` and will be removed in v5.0. The `ignore_ssl_errors` and `do_not_retry` kwargs have been removed outright — set them on the `Webhook` instance.
126
+
127
+
`apify.WebhookCondition` is no longer exported; the SDK now binds the webhook to the current Actor run internally.
128
+
129
+
The `webhooks` argument on `Actor.start`, `Actor.call`, and `Actor.call_task` still accepts `list[Webhook]` and the fields used at the call site (`event_types`, `request_url`, `payload_template`, `headers_template`) are unchanged.
130
+
131
+
## `Actor.new_client` — `timeout` scales all tiers
132
+
133
+
`apify-client` v3 split its single timeout into four tiers (short / medium / long / max). `Actor.new_client(timeout=...)` still takes a single `timedelta`; the SDK uses it as the medium-tier baseline and scales the other tiers proportionally (short = `timeout / 6`, long = `timeout * 12`, max = `timeout * 24`). The public signature is unchanged — no migration needed.
134
+
135
+
## Using the client from `Actor.new_client`
136
+
137
+
`Actor.new_client()` (and the `Actor.apify_client` property) now returns an `apify-client` v3 `ApifyClientAsync`. When you use that client directly, the client's v3 breaking changes apply — the most impactful ones are below. See the client's [Upgrading to v3](https://docs.apify.com/api/client/python/docs/upgrading/upgrading-to-v3) guide for the complete reference.
138
+
139
+
### 404 raises `NotFoundError` on ambiguous endpoints
140
+
141
+
Direct `.get(id)` and `.delete(id)` calls still swallow 404 into `None`. But where a 404 could mean either the parent or the sub-resource is missing, the client now raises `NotFoundError` instead of returning `None`.
### Async `iterate_*` are no longer coroutine functions
185
+
186
+
`DatasetClientAsync.iterate_items()` and `KeyValueStoreClientAsync.iterate_keys()` are now plain `def` functions returning `AsyncIterator[T]`. Consumer code (`async for ...`) is unchanged; if you annotate the call's return value, change `AsyncGenerator[T, None]` to `AsyncIterator[T]`.
0 commit comments