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
### Async `iterate_*` are no longer coroutine functions
199
199
200
200
`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]`.
201
+
202
+
## Scrapy requests and HTTP cache stored as JSON
203
+
204
+
This applies only if you use the Scrapy integration (`apify[scrapy]`).
205
+
206
+
The integration now serializes data as JSON instead of pickle. `ApifyScheduler` stores Scrapy requests in the Apify request queue (under `user_data['scrapy_request']`), and `ApifyCacheStorage` stores HTTP cache entries in the key-value store. Both now hold JSON. Unlike pickle, JSON stays stable across Python and library versions.
207
+
208
+
### Persisted data from before the upgrade is not read back
209
+
210
+
Data written by an older SDK uses the pickle format, which v4 does not load. The two storages handle this differently:
211
+
212
+
- HTTP cache: a legacy entry is treated as a cache miss. Scrapy re-fetches the page and re-stores it as JSON, so the cache heals itself. No action is needed.
213
+
- Request queue: a request stored by an older SDK cannot be reconstructed, so it is skipped and the failure is logged. This matters only when pre-upgrade requests are still in the queue, for example after a run is migrated or restarted, or when you reuse a named request queue. A fresh run is not affected.
214
+
215
+
### `meta` and `cb_kwargs` must be JSON-serializable
216
+
217
+
Pickle could store arbitrary Python objects. JSON cannot, so the values in a request's `meta` and `cb_kwargs` are now subject to JSON's type system:
218
+
219
+
- A `tuple` comes back as a `list`.
220
+
- Non-string `dict` keys come back as strings, so `{1: 'a'}` becomes `{'1': 'a'}`.
221
+
- A value JSON cannot represent (`datetime`, `set`, `Decimal`, a custom object) is no longer stored silently. The request is skipped and the failure is logged. Pydantic models are still supported and are dumped with `model_dump()`.
222
+
223
+
Convert such values to a JSON-friendly form before yielding the request:
224
+
225
+
```python
226
+
from datetime import datetime
227
+
228
+
# Before (v3): relied on pickle to store the datetime object.
0 commit comments