apify 2.2.0b5__py3-none-any.whl → 2.2.0b7__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of apify might be problematic. Click here for more details.

apify/_actor.py CHANGED
@@ -7,13 +7,14 @@ from datetime import timedelta
7
7
  from typing import TYPE_CHECKING, Any, Callable, TypeVar, cast
8
8
 
9
9
  from lazy_object_proxy import Proxy
10
+ from more_itertools import flatten
10
11
  from pydantic import AliasChoices
11
12
 
12
13
  from apify_client import ApifyClientAsync
13
14
  from apify_shared.consts import ActorEnvVars, ActorExitCodes, ApifyEnvVars
14
15
  from apify_shared.utils import ignore_docs, maybe_extract_enum_member_value
15
16
  from crawlee import service_container
16
- from crawlee.events._types import Event, EventPersistStateData
17
+ from crawlee.events._types import Event, EventMigratingData, EventPersistStateData
17
18
 
18
19
  from apify._configuration import Configuration
19
20
  from apify._consts import EVENT_LISTENERS_TIMEOUT
@@ -48,6 +49,7 @@ class _ActorType:
48
49
  _apify_client: ApifyClientAsync
49
50
  _configuration: Configuration
50
51
  _is_exiting = False
52
+ _is_rebooting = False
51
53
 
52
54
  def __init__(
53
55
  self,
@@ -839,12 +841,32 @@ class _ActorType:
839
841
  self.log.error('Actor.reboot() is only supported when running on the Apify platform.')
840
842
  return
841
843
 
844
+ if self._is_rebooting:
845
+ self.log.debug('Actor is already rebooting, skipping the additional reboot call.')
846
+ return
847
+
848
+ self._is_rebooting = True
849
+
842
850
  if not custom_after_sleep:
843
851
  custom_after_sleep = self._configuration.metamorph_after_sleep
844
852
 
845
- self._event_manager.emit(event=Event.PERSIST_STATE, event_data=EventPersistStateData(is_migrating=True))
853
+ # Call all the listeners for the PERSIST_STATE and MIGRATING events, and wait for them to finish.
854
+ # PERSIST_STATE listeners are called to allow the Actor to persist its state before the reboot.
855
+ # MIGRATING listeners are called to allow the Actor to gracefully stop in-progress tasks before the reboot.
856
+ # Typically, crawlers are listening for the MIIGRATING event to stop processing new requests.
857
+ # We can't just emit the events and wait for all listeners to finish,
858
+ # because this method might be called from an event listener itself, and we would deadlock.
859
+ persist_state_listeners = flatten(
860
+ (self._event_manager._listeners_to_wrappers[Event.PERSIST_STATE] or {}).values() # noqa: SLF001
861
+ )
862
+ migrating_listeners = flatten(
863
+ (self._event_manager._listeners_to_wrappers[Event.MIGRATING] or {}).values() # noqa: SLF001
864
+ )
846
865
 
847
- await self._event_manager.__aexit__(None, None, None)
866
+ await asyncio.gather(
867
+ *[listener(EventPersistStateData(is_migrating=True)) for listener in persist_state_listeners],
868
+ *[listener(EventMigratingData()) for listener in migrating_listeners],
869
+ )
848
870
 
849
871
  if not self._configuration.actor_run_id:
850
872
  raise RuntimeError('actor_run_id cannot be None when running on the Apify platform.')
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: apify
3
- Version: 2.2.0b5
3
+ Version: 2.2.0b7
4
4
  Summary: Apify SDK for Python
5
5
  License: Apache-2.0
6
6
  Keywords: apify,sdk,automation,chrome,crawlee,crawler,headless,scraper,scraping
@@ -23,8 +23,9 @@ Requires-Dist: apify-client (>=1.8.1)
23
23
  Requires-Dist: apify-shared (>=1.2.1)
24
24
  Requires-Dist: crawlee (>=0.4.0,<0.5.0)
25
25
  Requires-Dist: cryptography (>=42.0.0)
26
- Requires-Dist: httpx (>=0.27.0,<0.28.0)
26
+ Requires-Dist: httpx (>=0.27.0)
27
27
  Requires-Dist: lazy-object-proxy (>=1.10.0)
28
+ Requires-Dist: more_itertools (>=10.2.0)
28
29
  Requires-Dist: scrapy (>=2.11.0) ; extra == "scrapy"
29
30
  Requires-Dist: typing-extensions (>=4.1.0)
30
31
  Requires-Dist: websockets (>=10.0,<14.0.0)
@@ -1,5 +1,5 @@
1
1
  apify/__init__.py,sha256=99ynaDWBLEcCjdLq7R0Exy_iACsXiXoQ8VUZKmbzTeM,550
2
- apify/_actor.py,sha256=mrjOBjCoyLtW8LceQ94z2l-pQHGLD3DAvoKazoorMDk,42561
2
+ apify/_actor.py,sha256=bDCiS-IswmR2bQi4r71BK0wjvqA4qFUZpIAbN878-W8,43800
3
3
  apify/_configuration.py,sha256=_pPkesm1NEE6IxT1Mgxu3fGM89b1rtnLyeC3Hfpbh-Q,10516
4
4
  apify/_consts.py,sha256=_Xq4hOfOA1iZ3n1P967YWdyncKivpbX6RTlp_qanUoE,330
5
5
  apify/_crypto.py,sha256=e0_aM3l9_5Osk-jszYOOjrAKK60OggSHbiw5c30QnsU,5638
@@ -32,7 +32,7 @@ apify/scrapy/utils.py,sha256=758DcHCSAgCTProY0QX74uJ1XrzVsQwvCmFanj2f_3Q,2928
32
32
  apify/storages/__init__.py,sha256=FW-z6ubuPnHGM-Wp15T8mR5q6lnpDGrCW-IkgZd5L30,177
33
33
  apify/storages/_request_list.py,sha256=4nrvSdMUF-kiwGVIPEfIOygLKgjUpO37Jl8Om-jRbIU,5858
34
34
  apify/storages/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
35
- apify-2.2.0b5.dist-info/LICENSE,sha256=AsFjHssKjj4LGd2ZCqXn6FBzMqcWdjQre1byPPSypVw,11355
36
- apify-2.2.0b5.dist-info/METADATA,sha256=ygXe35NWdOz-tm1vjWXUbuo-ifmfPozdDdFuctVy3mw,8680
37
- apify-2.2.0b5.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
38
- apify-2.2.0b5.dist-info/RECORD,,
35
+ apify-2.2.0b7.dist-info/LICENSE,sha256=AsFjHssKjj4LGd2ZCqXn6FBzMqcWdjQre1byPPSypVw,11355
36
+ apify-2.2.0b7.dist-info/METADATA,sha256=R7ulgXBsHg1btpiBvhpO7cMuwnuIWJ2Qe73-VZecn4A,8713
37
+ apify-2.2.0b7.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
38
+ apify-2.2.0b7.dist-info/RECORD,,