apify 1.7.1b4__py3-none-any.whl → 1.7.2__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 +17 -11
- apify/config.py +3 -0
- {apify-1.7.1b4.dist-info → apify-1.7.2.dist-info}/METADATA +9 -8
- {apify-1.7.1b4.dist-info → apify-1.7.2.dist-info}/RECORD +7 -7
- {apify-1.7.1b4.dist-info → apify-1.7.2.dist-info}/WHEEL +1 -1
- {apify-1.7.1b4.dist-info → apify-1.7.2.dist-info}/LICENSE +0 -0
- {apify-1.7.1b4.dist-info → apify-1.7.2.dist-info}/top_level.txt +0 -0
apify/actor.py
CHANGED
|
@@ -5,7 +5,7 @@ import contextlib
|
|
|
5
5
|
import inspect
|
|
6
6
|
import os
|
|
7
7
|
import sys
|
|
8
|
-
from datetime import datetime, timezone
|
|
8
|
+
from datetime import datetime, timedelta, timezone
|
|
9
9
|
from typing import TYPE_CHECKING, Any, Awaitable, Callable, TypeVar, cast
|
|
10
10
|
|
|
11
11
|
from apify_client import ApifyClientAsync
|
|
@@ -301,6 +301,7 @@ class Actor(metaclass=_ActorContextManager):
|
|
|
301
301
|
exit_code: int = 0,
|
|
302
302
|
event_listeners_timeout_secs: float | None = EVENT_LISTENERS_TIMEOUT_SECS,
|
|
303
303
|
status_message: str | None = None,
|
|
304
|
+
cleanup_timeout: timedelta = timedelta(seconds=30),
|
|
304
305
|
) -> None:
|
|
305
306
|
"""Exit the actor instance.
|
|
306
307
|
|
|
@@ -314,11 +315,13 @@ class Actor(metaclass=_ActorContextManager):
|
|
|
314
315
|
exit_code (int, optional): The exit code with which the actor should fail (defaults to `0`).
|
|
315
316
|
event_listeners_timeout_secs (float, optional): How long should the actor wait for actor event listeners to finish before exiting.
|
|
316
317
|
status_message (str, optional): The final status message that the actor should display.
|
|
318
|
+
cleanup_timeout (timedelta, optional): How long we should wait for event listeners.
|
|
317
319
|
"""
|
|
318
320
|
return await cls._get_default_instance().exit(
|
|
319
321
|
exit_code=exit_code,
|
|
320
322
|
event_listeners_timeout_secs=event_listeners_timeout_secs,
|
|
321
323
|
status_message=status_message,
|
|
324
|
+
cleanup_timeout=cleanup_timeout,
|
|
322
325
|
)
|
|
323
326
|
|
|
324
327
|
async def _exit_internal(
|
|
@@ -327,6 +330,7 @@ class Actor(metaclass=_ActorContextManager):
|
|
|
327
330
|
exit_code: int = 0,
|
|
328
331
|
event_listeners_timeout_secs: float | None = EVENT_LISTENERS_TIMEOUT_SECS,
|
|
329
332
|
status_message: str | None = None,
|
|
333
|
+
cleanup_timeout: timedelta = timedelta(seconds=30),
|
|
330
334
|
) -> None:
|
|
331
335
|
self._raise_if_not_initialized()
|
|
332
336
|
|
|
@@ -336,21 +340,23 @@ class Actor(metaclass=_ActorContextManager):
|
|
|
336
340
|
|
|
337
341
|
self.log.info('Exiting actor', extra={'exit_code': exit_code})
|
|
338
342
|
|
|
339
|
-
|
|
343
|
+
async def finalize() -> None:
|
|
344
|
+
await self._cancel_event_emitting_intervals()
|
|
340
345
|
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
346
|
+
# Send final persist state event
|
|
347
|
+
if not self._was_final_persist_state_emitted:
|
|
348
|
+
self._event_manager.emit(ActorEventTypes.PERSIST_STATE, {'isMigrating': False})
|
|
349
|
+
self._was_final_persist_state_emitted = True
|
|
345
350
|
|
|
346
|
-
|
|
347
|
-
|
|
351
|
+
if status_message is not None:
|
|
352
|
+
await self.set_status_message(status_message, is_terminal=True)
|
|
348
353
|
|
|
349
|
-
|
|
350
|
-
|
|
354
|
+
# Sleep for a bit so that the listeners have a chance to trigger
|
|
355
|
+
await asyncio.sleep(0.1)
|
|
351
356
|
|
|
352
|
-
|
|
357
|
+
await self._event_manager.close(event_listeners_timeout_secs=event_listeners_timeout_secs)
|
|
353
358
|
|
|
359
|
+
await asyncio.wait_for(finalize(), cleanup_timeout.total_seconds())
|
|
354
360
|
self._is_initialized = False
|
|
355
361
|
|
|
356
362
|
if is_running_in_ipython():
|
apify/config.py
CHANGED
|
@@ -35,6 +35,7 @@ class Configuration:
|
|
|
35
35
|
proxy_status_url: str | None = None,
|
|
36
36
|
purge_on_start: bool | None = None,
|
|
37
37
|
token: str | None = None,
|
|
38
|
+
standby_port: int | None = None,
|
|
38
39
|
system_info_interval_millis: int | None = None,
|
|
39
40
|
) -> None:
|
|
40
41
|
"""Create a `Configuration` instance.
|
|
@@ -65,6 +66,7 @@ class Configuration:
|
|
|
65
66
|
purge_on_start (str, optional): Whether the actor should purge its default storages on startup, when running locally.
|
|
66
67
|
token (str, optional): The API token for the Apify API this actor should use.
|
|
67
68
|
system_info_interval_millis (str, optional): How often should the actor emit the SYSTEM_INFO event when running locally.
|
|
69
|
+
standby_port (int, optional): The port on which the container can listen for Actor Standby HTTP requests.
|
|
68
70
|
"""
|
|
69
71
|
# TODO: Document all these members
|
|
70
72
|
# https://github.com/apify/apify-sdk-python/issues/147
|
|
@@ -103,6 +105,7 @@ class Configuration:
|
|
|
103
105
|
self.proxy_port = proxy_port or fetch_and_parse_env_var(ApifyEnvVars.PROXY_PORT, 8000)
|
|
104
106
|
self.proxy_status_url = proxy_status_url or fetch_and_parse_env_var(ApifyEnvVars.PROXY_STATUS_URL, 'http://proxy.apify.com')
|
|
105
107
|
self.purge_on_start = purge_on_start or fetch_and_parse_env_var(ApifyEnvVars.PURGE_ON_START, default=False)
|
|
108
|
+
self.standby_port = standby_port or fetch_and_parse_env_var(ActorEnvVars.STANDBY_PORT, 4322)
|
|
106
109
|
self.started_at = fetch_and_parse_env_var(ActorEnvVars.STARTED_AT)
|
|
107
110
|
self.timeout_at = fetch_and_parse_env_var(ActorEnvVars.TIMEOUT_AT)
|
|
108
111
|
self.token = token or fetch_and_parse_env_var(ApifyEnvVars.TOKEN)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: apify
|
|
3
|
-
Version: 1.7.
|
|
3
|
+
Version: 1.7.2
|
|
4
4
|
Summary: Apify SDK for Python
|
|
5
5
|
Author-email: "Apify Technologies s.r.o." <support@apify.com>
|
|
6
6
|
License: Apache Software License
|
|
@@ -24,21 +24,21 @@ Classifier: Topic :: Software Development :: Libraries
|
|
|
24
24
|
Requires-Python: >=3.8
|
|
25
25
|
Description-Content-Type: text/markdown
|
|
26
26
|
License-File: LICENSE
|
|
27
|
-
Requires-Dist: apify-client ~=1.6.
|
|
28
|
-
Requires-Dist: apify-shared ~=1.1.
|
|
27
|
+
Requires-Dist: apify-client ~=1.6.0
|
|
28
|
+
Requires-Dist: apify-shared ~=1.1.2
|
|
29
29
|
Requires-Dist: aiofiles >=22.1.0
|
|
30
30
|
Requires-Dist: aioshutil >=1.0
|
|
31
31
|
Requires-Dist: colorama >=0.4.6
|
|
32
32
|
Requires-Dist: cryptography >=39.0.0
|
|
33
|
-
Requires-Dist: httpx >=0.24.
|
|
34
|
-
Requires-Dist: psutil >=5.9.
|
|
35
|
-
Requires-Dist: pyee >=11.0.
|
|
36
|
-
Requires-Dist: sortedcollections >=2.0.
|
|
33
|
+
Requires-Dist: httpx >=0.24.0
|
|
34
|
+
Requires-Dist: psutil >=5.9.0
|
|
35
|
+
Requires-Dist: pyee >=11.0.0
|
|
36
|
+
Requires-Dist: sortedcollections >=2.0.0
|
|
37
37
|
Requires-Dist: typing-extensions >=4.1.0
|
|
38
38
|
Requires-Dist: websockets >=10.1
|
|
39
39
|
Provides-Extra: dev
|
|
40
40
|
Requires-Dist: build ~=1.2.0 ; extra == 'dev'
|
|
41
|
-
Requires-Dist: filelock ~=3.
|
|
41
|
+
Requires-Dist: filelock ~=3.15.1 ; extra == 'dev'
|
|
42
42
|
Requires-Dist: mypy ~=1.10.0 ; extra == 'dev'
|
|
43
43
|
Requires-Dist: pre-commit ~=3.5.0 ; extra == 'dev'
|
|
44
44
|
Requires-Dist: pydoc-markdown ~=4.8.0 ; extra == 'dev'
|
|
@@ -50,6 +50,7 @@ Requires-Dist: pytest-timeout ~=2.3.0 ; extra == 'dev'
|
|
|
50
50
|
Requires-Dist: pytest-xdist ~=3.6.0 ; extra == 'dev'
|
|
51
51
|
Requires-Dist: respx ~=0.21.0 ; extra == 'dev'
|
|
52
52
|
Requires-Dist: ruff ~=0.4.0 ; extra == 'dev'
|
|
53
|
+
Requires-Dist: setuptools ~=70.1.0 ; extra == 'dev'
|
|
53
54
|
Requires-Dist: twine ~=5.1.0 ; extra == 'dev'
|
|
54
55
|
Requires-Dist: types-aiofiles ~=23.2.0.20240403 ; extra == 'dev'
|
|
55
56
|
Requires-Dist: types-colorama ~=0.4.15.20240311 ; extra == 'dev'
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
apify/__init__.py,sha256=aAjho-r0-XAqUjD9j55ueCo4lZJzyytOWjk0VCmkeeY,283
|
|
2
2
|
apify/_crypto.py,sha256=mbqwfgVz7efAw6ko1PTtpaaRqlBvTi-oskiZmWufTrk,5822
|
|
3
3
|
apify/_utils.py,sha256=7_iHGRw8AZA7ITStg5cN8k_ZmqMKdAQ_ev2ZRcO3X0M,16963
|
|
4
|
-
apify/actor.py,sha256=
|
|
5
|
-
apify/config.py,sha256=
|
|
4
|
+
apify/actor.py,sha256=lwgE9huMDVgw8ehTFNrZAk5hwSlQNGuYeBx6aKcHiBM,60423
|
|
5
|
+
apify/config.py,sha256=1orNGYPiqcT_3Q8_DPRIpX1LjicqzK6e_nvMaGcU1ng,9045
|
|
6
6
|
apify/consts.py,sha256=eSD23HmwLKwWG8bRp5O1c7bmtlhvYE17Yw46BKs4vQQ,2263
|
|
7
7
|
apify/event_manager.py,sha256=k4_f977esIOvgGshec4yUSulU10-UsEkoVEV4sZEjwg,10612
|
|
8
8
|
apify/log.py,sha256=PObD-34j4GFUTLHHWDfgdd39ftfERBQBTc2DyvPJT3o,5005
|
|
@@ -34,8 +34,8 @@ apify/storages/dataset.py,sha256=gfMlJ6dSXDdjCykkStZCyp4u8xKCIZqflGS9-jLzK74,233
|
|
|
34
34
|
apify/storages/key_value_store.py,sha256=BUGYPI4MuRlOJ_aPzZr8bq7ay_K04qAZ7yKW7C8ItV4,10760
|
|
35
35
|
apify/storages/request_queue.py,sha256=68pM2nJUYjkdpBTM315NnjRYE_yzeoslVtBQRB7bm74,28829
|
|
36
36
|
apify/storages/storage_client_manager.py,sha256=fvXg3PRojATNamEN29BBZyZZ5GWN_s0r29A59aiL-wQ,2465
|
|
37
|
-
apify-1.7.
|
|
38
|
-
apify-1.7.
|
|
39
|
-
apify-1.7.
|
|
40
|
-
apify-1.7.
|
|
41
|
-
apify-1.7.
|
|
37
|
+
apify-1.7.2.dist-info/LICENSE,sha256=AsFjHssKjj4LGd2ZCqXn6FBzMqcWdjQre1byPPSypVw,11355
|
|
38
|
+
apify-1.7.2.dist-info/METADATA,sha256=mBlpWItbOHFUsOD1delotf4yjW06-ARaVus6W4vzY7U,6305
|
|
39
|
+
apify-1.7.2.dist-info/WHEEL,sha256=mguMlWGMX-VHnMpKOjjQidIo1ssRlCFu4a4mBpz1s2M,91
|
|
40
|
+
apify-1.7.2.dist-info/top_level.txt,sha256=2oFNsHggn5m_rCaaP7xijQg_-Va2ByOSYuvKgACsS5w,6
|
|
41
|
+
apify-1.7.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|