apify 2.0.0b6__tar.gz → 2.0.0b7__tar.gz
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-2.0.0b6 → apify-2.0.0b7}/PKG-INFO +10 -16
- {apify-2.0.0b6 → apify-2.0.0b7}/pyproject.toml +26 -35
- {apify-2.0.0b6 → apify-2.0.0b7}/src/apify/__init__.py +12 -1
- {apify-2.0.0b6 → apify-2.0.0b7}/src/apify/_actor.py +60 -34
- apify-2.0.0b7/src/apify/_models.py +110 -0
- {apify-2.0.0b6 → apify-2.0.0b7}/src/apify/_platform_event_manager.py +1 -1
- {apify-2.0.0b6 → apify-2.0.0b7}/src/apify/_proxy_configuration.py +1 -1
- apify-2.0.0b6/src/apify/_log.py → apify-2.0.0b7/src/apify/log.py +1 -1
- {apify-2.0.0b6 → apify-2.0.0b7}/LICENSE +0 -0
- {apify-2.0.0b6 → apify-2.0.0b7}/README.md +0 -0
- {apify-2.0.0b6 → apify-2.0.0b7}/src/apify/_configuration.py +0 -0
- {apify-2.0.0b6 → apify-2.0.0b7}/src/apify/_consts.py +0 -0
- {apify-2.0.0b6 → apify-2.0.0b7}/src/apify/_crypto.py +0 -0
- {apify-2.0.0b6 → apify-2.0.0b7}/src/apify/_utils.py +0 -0
- {apify-2.0.0b6 → apify-2.0.0b7}/src/apify/apify_storage_client/__init__.py +0 -0
- {apify-2.0.0b6 → apify-2.0.0b7}/src/apify/apify_storage_client/_apify_storage_client.py +0 -0
- {apify-2.0.0b6 → apify-2.0.0b7}/src/apify/apify_storage_client/_dataset_client.py +0 -0
- {apify-2.0.0b6 → apify-2.0.0b7}/src/apify/apify_storage_client/_dataset_collection_client.py +0 -0
- {apify-2.0.0b6 → apify-2.0.0b7}/src/apify/apify_storage_client/_key_value_store_client.py +0 -0
- {apify-2.0.0b6 → apify-2.0.0b7}/src/apify/apify_storage_client/_key_value_store_collection_client.py +0 -0
- {apify-2.0.0b6 → apify-2.0.0b7}/src/apify/apify_storage_client/_request_queue_client.py +0 -0
- {apify-2.0.0b6 → apify-2.0.0b7}/src/apify/apify_storage_client/_request_queue_collection_client.py +0 -0
- {apify-2.0.0b6 → apify-2.0.0b7}/src/apify/apify_storage_client/py.typed +0 -0
- {apify-2.0.0b6 → apify-2.0.0b7}/src/apify/py.typed +0 -0
- {apify-2.0.0b6 → apify-2.0.0b7}/src/apify/scrapy/__init__.py +0 -0
- {apify-2.0.0b6 → apify-2.0.0b7}/src/apify/scrapy/middlewares/__init__.py +0 -0
- {apify-2.0.0b6 → apify-2.0.0b7}/src/apify/scrapy/middlewares/apify_proxy.py +0 -0
- {apify-2.0.0b6 → apify-2.0.0b7}/src/apify/scrapy/middlewares/py.typed +0 -0
- {apify-2.0.0b6 → apify-2.0.0b7}/src/apify/scrapy/pipelines/__init__.py +0 -0
- {apify-2.0.0b6 → apify-2.0.0b7}/src/apify/scrapy/pipelines/actor_dataset_push.py +0 -0
- {apify-2.0.0b6 → apify-2.0.0b7}/src/apify/scrapy/pipelines/py.typed +0 -0
- {apify-2.0.0b6 → apify-2.0.0b7}/src/apify/scrapy/py.typed +0 -0
- {apify-2.0.0b6 → apify-2.0.0b7}/src/apify/scrapy/requests.py +0 -0
- {apify-2.0.0b6 → apify-2.0.0b7}/src/apify/scrapy/scheduler.py +0 -0
- {apify-2.0.0b6 → apify-2.0.0b7}/src/apify/scrapy/utils.py +0 -0
- {apify-2.0.0b6 → apify-2.0.0b7}/src/apify/storages/__init__.py +0 -0
- {apify-2.0.0b6 → apify-2.0.0b7}/src/apify/storages/py.typed +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: apify
|
|
3
|
-
Version: 2.0.
|
|
3
|
+
Version: 2.0.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
|
|
@@ -18,21 +18,15 @@ Classifier: Programming Language :: Python :: 3.11
|
|
|
18
18
|
Classifier: Programming Language :: Python :: 3.12
|
|
19
19
|
Classifier: Topic :: Software Development :: Libraries
|
|
20
20
|
Provides-Extra: scrapy
|
|
21
|
-
Requires-Dist:
|
|
22
|
-
Requires-Dist:
|
|
23
|
-
Requires-Dist:
|
|
24
|
-
Requires-Dist:
|
|
25
|
-
Requires-Dist:
|
|
26
|
-
Requires-Dist:
|
|
27
|
-
Requires-Dist:
|
|
28
|
-
Requires-Dist:
|
|
29
|
-
Requires-Dist:
|
|
30
|
-
Requires-Dist: psutil (>=6.0.0,<7.0.0)
|
|
31
|
-
Requires-Dist: pyee (>=11.0.0,<12.0.0)
|
|
32
|
-
Requires-Dist: scrapy (>=2.11.0,<3.0.0) ; extra == "scrapy"
|
|
33
|
-
Requires-Dist: sortedcollections (>=2.0.0,<3.0.0)
|
|
34
|
-
Requires-Dist: typing-extensions (>=4.1.0,<5.0.0)
|
|
35
|
-
Requires-Dist: websockets (>=10.1,<11.0)
|
|
21
|
+
Requires-Dist: apify-client (>=1.7.1)
|
|
22
|
+
Requires-Dist: apify-shared (>=1.1.2)
|
|
23
|
+
Requires-Dist: crawlee (>=0.3.0)
|
|
24
|
+
Requires-Dist: cryptography (>=42.0.0)
|
|
25
|
+
Requires-Dist: httpx (>=0.27.0)
|
|
26
|
+
Requires-Dist: lazy-object-proxy (>=1.10.0)
|
|
27
|
+
Requires-Dist: scrapy (>=2.11.0) ; extra == "scrapy"
|
|
28
|
+
Requires-Dist: typing-extensions (>=4.1.0)
|
|
29
|
+
Requires-Dist: websockets (>=10.0)
|
|
36
30
|
Project-URL: Apify Homepage, https://apify.com
|
|
37
31
|
Project-URL: Changelog, https://docs.apify.com/sdk/python/docs/changelog
|
|
38
32
|
Project-URL: Documentation, https://docs.apify.com/sdk/python/
|
|
@@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api"
|
|
|
4
4
|
|
|
5
5
|
[tool.poetry]
|
|
6
6
|
name = "apify"
|
|
7
|
-
version = "2.0.
|
|
7
|
+
version = "2.0.0b7"
|
|
8
8
|
description = "Apify SDK for Python"
|
|
9
9
|
authors = ["Apify Technologies s.r.o. <support@apify.com>"]
|
|
10
10
|
license = "Apache-2.0"
|
|
@@ -46,41 +46,32 @@ keywords = [
|
|
|
46
46
|
# https://github.com/apify/apify-sdk-python/pull/154.
|
|
47
47
|
[tool.poetry.dependencies]
|
|
48
48
|
python = "^3.9"
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
psutil = "^6.0.0"
|
|
59
|
-
pyee = "^11.0.0"
|
|
60
|
-
scrapy = { version = "^2.11.0", optional = true }
|
|
61
|
-
sortedcollections = "^2.0.0"
|
|
62
|
-
typing-extensions = "^4.1.0"
|
|
63
|
-
websockets = "^10.1"
|
|
49
|
+
apify-client = ">=1.7.1"
|
|
50
|
+
apify-shared = ">=1.1.2"
|
|
51
|
+
crawlee = ">=0.3.0"
|
|
52
|
+
cryptography = ">=42.0.0"
|
|
53
|
+
httpx = ">=0.27.0"
|
|
54
|
+
lazy-object-proxy = ">=1.10.0"
|
|
55
|
+
scrapy = { version = ">=2.11.0", optional = true }
|
|
56
|
+
typing-extensions = ">=4.1.0"
|
|
57
|
+
websockets = ">=10.0"
|
|
64
58
|
|
|
65
59
|
[tool.poetry.group.dev.dependencies]
|
|
66
|
-
build = "
|
|
67
|
-
filelock = "
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
pytest
|
|
73
|
-
pytest-
|
|
74
|
-
pytest-
|
|
75
|
-
pytest-
|
|
76
|
-
pytest-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
types-aiofiles = "^24.1.0.20240626"
|
|
82
|
-
types-colorama = "^0.4.15.20240311"
|
|
83
|
-
types-psutil = "^6.0.0.20240621"
|
|
60
|
+
build = "~1.2.0"
|
|
61
|
+
filelock = "~3.15.0"
|
|
62
|
+
griffe = "~1.2.0"
|
|
63
|
+
mypy = "~1.11.0"
|
|
64
|
+
pre-commit = "~3.8.0"
|
|
65
|
+
pydoc-markdown = "~4.8.0"
|
|
66
|
+
pytest = "~8.3.0"
|
|
67
|
+
pytest-asyncio = "~0.24.0"
|
|
68
|
+
pytest-cov = "~5.0.0"
|
|
69
|
+
pytest-only = "~2.1.0"
|
|
70
|
+
pytest-timeout = "~2.3.0"
|
|
71
|
+
pytest-xdist = "~3.6.0"
|
|
72
|
+
respx = "~0.21.0"
|
|
73
|
+
ruff = "~0.6.0"
|
|
74
|
+
setuptools = "~74.0.0" # setuptools are used by pytest but not explicitly required
|
|
84
75
|
|
|
85
76
|
[tool.poetry.extras]
|
|
86
77
|
scrapy = ["scrapy"]
|
|
@@ -191,7 +182,7 @@ warn_unused_ignores = true
|
|
|
191
182
|
exclude = []
|
|
192
183
|
|
|
193
184
|
[[tool.mypy.overrides]]
|
|
194
|
-
module = ['scrapy', 'scrapy.*', '
|
|
185
|
+
module = ['scrapy', 'scrapy.*', 'lazy_object_proxy']
|
|
195
186
|
ignore_missing_imports = true
|
|
196
187
|
|
|
197
188
|
[tool.coverage.report]
|
|
@@ -1,11 +1,22 @@
|
|
|
1
1
|
from importlib import metadata
|
|
2
2
|
|
|
3
|
+
from apify_shared.consts import WebhookEventType
|
|
3
4
|
from crawlee.events._types import Event
|
|
4
5
|
|
|
5
6
|
from apify._actor import Actor
|
|
6
7
|
from apify._configuration import Configuration
|
|
8
|
+
from apify._models import Webhook
|
|
7
9
|
from apify._proxy_configuration import ProxyConfiguration, ProxyInfo
|
|
8
10
|
|
|
9
11
|
__version__ = metadata.version('apify')
|
|
10
12
|
|
|
11
|
-
__all__ = [
|
|
13
|
+
__all__ = [
|
|
14
|
+
'Actor',
|
|
15
|
+
'Event',
|
|
16
|
+
'Configuration',
|
|
17
|
+
'ProxyConfiguration',
|
|
18
|
+
'ProxyInfo',
|
|
19
|
+
'Webhook',
|
|
20
|
+
'WebhookEventType',
|
|
21
|
+
'__version__',
|
|
22
|
+
]
|
|
@@ -11,7 +11,7 @@ from pydantic import AliasChoices
|
|
|
11
11
|
from typing_extensions import Self
|
|
12
12
|
|
|
13
13
|
from apify_client import ApifyClientAsync
|
|
14
|
-
from apify_shared.consts import ActorEnvVars, ActorExitCodes, ApifyEnvVars
|
|
14
|
+
from apify_shared.consts import ActorEnvVars, ActorExitCodes, ApifyEnvVars
|
|
15
15
|
from apify_shared.utils import ignore_docs, maybe_extract_enum_member_value
|
|
16
16
|
from crawlee import service_container
|
|
17
17
|
from crawlee.events._types import Event, EventPersistStateData
|
|
@@ -19,11 +19,12 @@ from crawlee.events._types import Event, EventPersistStateData
|
|
|
19
19
|
from apify._configuration import Configuration
|
|
20
20
|
from apify._consts import EVENT_LISTENERS_TIMEOUT
|
|
21
21
|
from apify._crypto import decrypt_input_secrets, load_private_key
|
|
22
|
-
from apify.
|
|
22
|
+
from apify._models import ActorRun
|
|
23
23
|
from apify._platform_event_manager import EventManager, LocalEventManager, PlatformEventManager
|
|
24
24
|
from apify._proxy_configuration import ProxyConfiguration
|
|
25
25
|
from apify._utils import get_system_info, is_running_in_ipython
|
|
26
26
|
from apify.apify_storage_client import ApifyStorageClient
|
|
27
|
+
from apify.log import logger
|
|
27
28
|
from apify.storages import Dataset, KeyValueStore, RequestQueue
|
|
28
29
|
|
|
29
30
|
if TYPE_CHECKING:
|
|
@@ -32,6 +33,8 @@ if TYPE_CHECKING:
|
|
|
32
33
|
|
|
33
34
|
from crawlee.proxy_configuration import _NewUrlFunction
|
|
34
35
|
|
|
36
|
+
from apify._models import Webhook
|
|
37
|
+
|
|
35
38
|
|
|
36
39
|
MainReturnType = TypeVar('MainReturnType')
|
|
37
40
|
|
|
@@ -533,8 +536,8 @@ class _ActorType:
|
|
|
533
536
|
memory_mbytes: int | None = None,
|
|
534
537
|
timeout: timedelta | None = None,
|
|
535
538
|
wait_for_finish: int | None = None,
|
|
536
|
-
webhooks: list[
|
|
537
|
-
) ->
|
|
539
|
+
webhooks: list[Webhook] | None = None,
|
|
540
|
+
) -> ActorRun:
|
|
538
541
|
"""Run an Actor on the Apify platform.
|
|
539
542
|
|
|
540
543
|
Unlike `Actor.call`, this method just starts the run without waiting for finish.
|
|
@@ -555,10 +558,6 @@ class _ActorType:
|
|
|
555
558
|
webhooks: Optional ad-hoc webhooks (https://docs.apify.com/webhooks/ad-hoc-webhooks) associated with
|
|
556
559
|
the Actor run which can be used to receive a notification, e.g. when the Actor finished or failed.
|
|
557
560
|
If you already have a webhook set up for the Actor or task, you do not have to add it again here.
|
|
558
|
-
Each webhook is represented by a dictionary containing these items:
|
|
559
|
-
* `event_types`: list of `WebhookEventType` values which trigger the webhook
|
|
560
|
-
* `request_url`: URL to which to send the webhook HTTP request
|
|
561
|
-
* `payload_template` (optional): Optional template for the request payload
|
|
562
561
|
|
|
563
562
|
Returns:
|
|
564
563
|
Info about the started Actor run
|
|
@@ -567,16 +566,25 @@ class _ActorType:
|
|
|
567
566
|
|
|
568
567
|
client = self.new_client(token=token) if token else self._apify_client
|
|
569
568
|
|
|
570
|
-
|
|
569
|
+
if webhooks:
|
|
570
|
+
serialized_webhooks = [
|
|
571
|
+
hook.model_dump(by_alias=True, exclude_unset=True, exclude_defaults=True) for hook in webhooks
|
|
572
|
+
]
|
|
573
|
+
else:
|
|
574
|
+
serialized_webhooks = None
|
|
575
|
+
|
|
576
|
+
api_result = await client.actor(actor_id).start(
|
|
571
577
|
run_input=run_input,
|
|
572
578
|
content_type=content_type,
|
|
573
579
|
build=build,
|
|
574
580
|
memory_mbytes=memory_mbytes,
|
|
575
581
|
timeout_secs=int(timeout.total_seconds()) if timeout is not None else None,
|
|
576
582
|
wait_for_finish=wait_for_finish,
|
|
577
|
-
webhooks=
|
|
583
|
+
webhooks=serialized_webhooks,
|
|
578
584
|
)
|
|
579
585
|
|
|
586
|
+
return ActorRun.model_validate(api_result)
|
|
587
|
+
|
|
580
588
|
async def abort(
|
|
581
589
|
self,
|
|
582
590
|
run_id: str,
|
|
@@ -584,7 +592,7 @@ class _ActorType:
|
|
|
584
592
|
token: str | None = None,
|
|
585
593
|
status_message: str | None = None,
|
|
586
594
|
gracefully: bool | None = None,
|
|
587
|
-
) ->
|
|
595
|
+
) -> ActorRun:
|
|
588
596
|
"""Abort given Actor run on the Apify platform using the current user account.
|
|
589
597
|
|
|
590
598
|
The user account is determined by the `APIFY_TOKEN` environment variable.
|
|
@@ -607,7 +615,9 @@ class _ActorType:
|
|
|
607
615
|
if status_message:
|
|
608
616
|
await client.run(run_id).update(status_message=status_message)
|
|
609
617
|
|
|
610
|
-
|
|
618
|
+
api_result = await client.run(run_id).abort(gracefully=gracefully)
|
|
619
|
+
|
|
620
|
+
return ActorRun.model_validate(api_result)
|
|
611
621
|
|
|
612
622
|
async def call(
|
|
613
623
|
self,
|
|
@@ -619,9 +629,9 @@ class _ActorType:
|
|
|
619
629
|
build: str | None = None,
|
|
620
630
|
memory_mbytes: int | None = None,
|
|
621
631
|
timeout: timedelta | None = None,
|
|
622
|
-
webhooks: list[
|
|
632
|
+
webhooks: list[Webhook] | None = None,
|
|
623
633
|
wait: timedelta | None = None,
|
|
624
|
-
) ->
|
|
634
|
+
) -> ActorRun | None:
|
|
625
635
|
"""Start an Actor on the Apify Platform and wait for it to finish before returning.
|
|
626
636
|
|
|
627
637
|
It waits indefinitely, unless the wait argument is provided.
|
|
@@ -650,16 +660,25 @@ class _ActorType:
|
|
|
650
660
|
|
|
651
661
|
client = self.new_client(token=token) if token else self._apify_client
|
|
652
662
|
|
|
653
|
-
|
|
663
|
+
if webhooks:
|
|
664
|
+
serialized_webhooks = [
|
|
665
|
+
hook.model_dump(by_alias=True, exclude_unset=True, exclude_defaults=True) for hook in webhooks
|
|
666
|
+
]
|
|
667
|
+
else:
|
|
668
|
+
serialized_webhooks = None
|
|
669
|
+
|
|
670
|
+
api_result = await client.actor(actor_id).call(
|
|
654
671
|
run_input=run_input,
|
|
655
672
|
content_type=content_type,
|
|
656
673
|
build=build,
|
|
657
674
|
memory_mbytes=memory_mbytes,
|
|
658
675
|
timeout_secs=int(timeout.total_seconds()) if timeout is not None else None,
|
|
659
|
-
webhooks=
|
|
676
|
+
webhooks=serialized_webhooks,
|
|
660
677
|
wait_secs=int(wait.total_seconds()) if wait is not None else None,
|
|
661
678
|
)
|
|
662
679
|
|
|
680
|
+
return ActorRun.model_validate(api_result)
|
|
681
|
+
|
|
663
682
|
async def call_task(
|
|
664
683
|
self,
|
|
665
684
|
task_id: str,
|
|
@@ -668,10 +687,10 @@ class _ActorType:
|
|
|
668
687
|
build: str | None = None,
|
|
669
688
|
memory_mbytes: int | None = None,
|
|
670
689
|
timeout: timedelta | None = None,
|
|
671
|
-
webhooks: list[
|
|
690
|
+
webhooks: list[Webhook] | None = None,
|
|
672
691
|
wait: timedelta | None = None,
|
|
673
692
|
token: str | None = None,
|
|
674
|
-
) ->
|
|
693
|
+
) -> ActorRun | None:
|
|
675
694
|
"""Start an Actor task on the Apify Platform and wait for it to finish before returning.
|
|
676
695
|
|
|
677
696
|
It waits indefinitely, unless the wait argument is provided.
|
|
@@ -703,15 +722,24 @@ class _ActorType:
|
|
|
703
722
|
|
|
704
723
|
client = self.new_client(token=token) if token else self._apify_client
|
|
705
724
|
|
|
706
|
-
|
|
725
|
+
if webhooks:
|
|
726
|
+
serialized_webhooks = [
|
|
727
|
+
hook.model_dump(by_alias=True, exclude_unset=True, exclude_defaults=True) for hook in webhooks
|
|
728
|
+
]
|
|
729
|
+
else:
|
|
730
|
+
serialized_webhooks = None
|
|
731
|
+
|
|
732
|
+
api_result = await client.task(task_id).call(
|
|
707
733
|
task_input=task_input,
|
|
708
734
|
build=build,
|
|
709
735
|
memory_mbytes=memory_mbytes,
|
|
710
736
|
timeout_secs=int(timeout.total_seconds()) if timeout is not None else None,
|
|
711
|
-
webhooks=
|
|
737
|
+
webhooks=serialized_webhooks,
|
|
712
738
|
wait_secs=int(wait.total_seconds()) if wait is not None else None,
|
|
713
739
|
)
|
|
714
740
|
|
|
741
|
+
return ActorRun.model_validate(api_result)
|
|
742
|
+
|
|
715
743
|
async def metamorph(
|
|
716
744
|
self,
|
|
717
745
|
target_actor_id: str,
|
|
@@ -796,14 +824,12 @@ class _ActorType:
|
|
|
796
824
|
|
|
797
825
|
async def add_webhook(
|
|
798
826
|
self,
|
|
827
|
+
webhook: Webhook,
|
|
799
828
|
*,
|
|
800
|
-
event_types: list[WebhookEventType],
|
|
801
|
-
request_url: str,
|
|
802
|
-
payload_template: str | None = None,
|
|
803
829
|
ignore_ssl_errors: bool | None = None,
|
|
804
830
|
do_not_retry: bool | None = None,
|
|
805
831
|
idempotency_key: str | None = None,
|
|
806
|
-
) ->
|
|
832
|
+
) -> None:
|
|
807
833
|
"""Create an ad-hoc webhook for the current Actor run.
|
|
808
834
|
|
|
809
835
|
This webhook lets you receive a notification when the Actor run finished or failed.
|
|
@@ -814,9 +840,7 @@ class _ActorType:
|
|
|
814
840
|
For more information about Apify Actor webhooks, please see the [documentation](https://docs.apify.com/webhooks).
|
|
815
841
|
|
|
816
842
|
Args:
|
|
817
|
-
|
|
818
|
-
request_url: URL that will be invoked once the webhook is triggered.
|
|
819
|
-
payload_template: Specification of the payload that will be sent to request_url
|
|
843
|
+
webhook: The webhook to be added
|
|
820
844
|
ignore_ssl_errors: Whether the webhook should ignore SSL errors returned by request_url
|
|
821
845
|
do_not_retry: Whether the webhook should retry sending the payload to request_url upon failure.
|
|
822
846
|
idempotency_key: A unique identifier of a webhook. You can use it to ensure that you won't create
|
|
@@ -829,17 +853,17 @@ class _ActorType:
|
|
|
829
853
|
|
|
830
854
|
if not self.is_at_home():
|
|
831
855
|
self.log.error('Actor.add_webhook() is only supported when running on the Apify platform.')
|
|
832
|
-
return
|
|
856
|
+
return
|
|
833
857
|
|
|
834
858
|
# If is_at_home() is True, config.actor_run_id is always set
|
|
835
859
|
if not self._configuration.actor_run_id:
|
|
836
860
|
raise RuntimeError('actor_run_id cannot be None when running on the Apify platform.')
|
|
837
861
|
|
|
838
|
-
|
|
862
|
+
await self._apify_client.webhooks().create(
|
|
839
863
|
actor_run_id=self._configuration.actor_run_id,
|
|
840
|
-
event_types=event_types,
|
|
841
|
-
request_url=request_url,
|
|
842
|
-
payload_template=payload_template,
|
|
864
|
+
event_types=webhook.event_types,
|
|
865
|
+
request_url=webhook.request_url,
|
|
866
|
+
payload_template=webhook.payload_template,
|
|
843
867
|
ignore_ssl_errors=ignore_ssl_errors,
|
|
844
868
|
do_not_retry=do_not_retry,
|
|
845
869
|
idempotency_key=idempotency_key,
|
|
@@ -850,7 +874,7 @@ class _ActorType:
|
|
|
850
874
|
status_message: str,
|
|
851
875
|
*,
|
|
852
876
|
is_terminal: bool | None = None,
|
|
853
|
-
) ->
|
|
877
|
+
) -> ActorRun | None:
|
|
854
878
|
"""Set the status message for the current Actor run.
|
|
855
879
|
|
|
856
880
|
Args:
|
|
@@ -871,10 +895,12 @@ class _ActorType:
|
|
|
871
895
|
if not self._configuration.actor_run_id:
|
|
872
896
|
raise RuntimeError('actor_run_id cannot be None when running on the Apify platform.')
|
|
873
897
|
|
|
874
|
-
|
|
898
|
+
api_result = await self._apify_client.run(self._configuration.actor_run_id).update(
|
|
875
899
|
status_message=status_message, is_status_message_terminal=is_terminal
|
|
876
900
|
)
|
|
877
901
|
|
|
902
|
+
return ActorRun.model_validate(api_result)
|
|
903
|
+
|
|
878
904
|
async def create_proxy_configuration(
|
|
879
905
|
self,
|
|
880
906
|
*,
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
# ruff: noqa: TCH001 TCH002 TCH003 (Pydantic)
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
from datetime import datetime, timedelta
|
|
5
|
+
from typing import Annotated
|
|
6
|
+
|
|
7
|
+
from pydantic import BaseModel, BeforeValidator, ConfigDict, Field
|
|
8
|
+
|
|
9
|
+
from apify_shared.consts import ActorJobStatus, MetaOrigin, WebhookEventType
|
|
10
|
+
from crawlee._utils.models import timedelta_ms
|
|
11
|
+
from crawlee._utils.urls import validate_http_url
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class Webhook(BaseModel):
|
|
15
|
+
__model_config__ = ConfigDict(populate_by_name=True)
|
|
16
|
+
|
|
17
|
+
event_types: Annotated[
|
|
18
|
+
list[WebhookEventType],
|
|
19
|
+
Field(description='Event types that should trigger the webhook'),
|
|
20
|
+
]
|
|
21
|
+
request_url: Annotated[
|
|
22
|
+
str,
|
|
23
|
+
Field(description='URL that the webhook should call'),
|
|
24
|
+
BeforeValidator(validate_http_url),
|
|
25
|
+
]
|
|
26
|
+
payload_template: Annotated[
|
|
27
|
+
str | None,
|
|
28
|
+
Field(description='Template for the payload sent by the webook'),
|
|
29
|
+
] = None
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class ActorRunMeta(BaseModel):
|
|
33
|
+
__model_config__ = ConfigDict(populate_by_name=True)
|
|
34
|
+
|
|
35
|
+
origin: Annotated[MetaOrigin, Field()]
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class ActorRunStats(BaseModel):
|
|
39
|
+
__model_config__ = ConfigDict(populate_by_name=True)
|
|
40
|
+
|
|
41
|
+
input_body_len: Annotated[int, Field(alias='inputBodyLen')]
|
|
42
|
+
restart_count: Annotated[int, Field(alias='restartCount')]
|
|
43
|
+
resurrect_count: Annotated[int, Field(alias='resurrectCount')]
|
|
44
|
+
mem_avg_bytes: Annotated[float | None, Field(alias='memAvgBytes')] = None
|
|
45
|
+
mem_max_bytes: Annotated[int | None, Field(alias='memMaxBytes')] = None
|
|
46
|
+
mem_current_bytes: Annotated[int | None, Field(alias='memCurrentBytes')] = None
|
|
47
|
+
cpu_avg_usage: Annotated[float | None, Field(alias='cpuAvgUsage')] = None
|
|
48
|
+
cpu_max_usage: Annotated[float | None, Field(alias='cpuMaxUsage')] = None
|
|
49
|
+
cpu_current_usage: Annotated[float | None, Field(alias='cpuCurrentUsage')] = None
|
|
50
|
+
net_rx_bytes: Annotated[int | None, Field(alias='netRxBytes')] = None
|
|
51
|
+
net_tx_bytes: Annotated[int | None, Field(alias='netTxBytes')] = None
|
|
52
|
+
duration: Annotated[timedelta_ms | None, Field(alias='durationMillis')] = None
|
|
53
|
+
run_time: Annotated[timedelta | None, Field(alias='runTimeSecs')] = None
|
|
54
|
+
metamorph: Annotated[int | None, Field(alias='metamorph')] = None
|
|
55
|
+
compute_units: Annotated[float, Field(alias='computeUnits')]
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
class ActorRunOptions(BaseModel):
|
|
59
|
+
__model_config__ = ConfigDict(populate_by_name=True)
|
|
60
|
+
|
|
61
|
+
build: str
|
|
62
|
+
timeout: Annotated[timedelta, Field(alias='timeoutSecs')]
|
|
63
|
+
memory_mbytes: Annotated[int, Field(alias='memoryMbytes')]
|
|
64
|
+
disk_mbytes: Annotated[int, Field(alias='diskMbytes')]
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
class ActorRunUsage(BaseModel):
|
|
68
|
+
__model_config__ = ConfigDict(populate_by_name=True)
|
|
69
|
+
|
|
70
|
+
actor_compute_units: Annotated[float | None, Field(alias='ACTOR_COMPUTE_UNITS')] = None
|
|
71
|
+
dataset_reads: Annotated[float | None, Field(alias='DATASET_READS')] = None
|
|
72
|
+
dataset_writes: Annotated[float | None, Field(alias='DATASET_WRITES')] = None
|
|
73
|
+
key_value_store_reads: Annotated[float | None, Field(alias='KEY_VALUE_STORE_READS')] = None
|
|
74
|
+
key_value_store_writes: Annotated[float | None, Field(alias='KEY_VALUE_STORE_WRITES')] = None
|
|
75
|
+
key_value_store_lists: Annotated[float | None, Field(alias='KEY_VALUE_STORE_LISTS')] = None
|
|
76
|
+
request_queue_reads: Annotated[float | None, Field(alias='REQUEST_QUEUE_READS')] = None
|
|
77
|
+
request_queue_writes: Annotated[float | None, Field(alias='REQUEST_QUEUE_WRITES')] = None
|
|
78
|
+
data_transfer_internal_gbytes: Annotated[float | None, Field(alias='DATA_TRANSFER_INTERNAL_GBYTES')] = None
|
|
79
|
+
data_transfer_external_gbytes: Annotated[float | None, Field(alias='DATA_TRANSFER_EXTERNAL_GBYTES')] = None
|
|
80
|
+
proxy_residential_transfer_gbytes: Annotated[float | None, Field(alias='PROXY_RESIDENTIAL_TRANSFER_GBYTES')] = None
|
|
81
|
+
proxy_serps: Annotated[float | None, Field(alias='PROXY_SERPS')] = None
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
class ActorRun(BaseModel):
|
|
85
|
+
__model_config__ = ConfigDict(populate_by_name=True)
|
|
86
|
+
|
|
87
|
+
id: Annotated[str, Field(alias='id')]
|
|
88
|
+
act_id: Annotated[str, Field(alias='actId')]
|
|
89
|
+
user_id: Annotated[str, Field(alias='userId')]
|
|
90
|
+
actor_task_id: Annotated[str | None, Field(alias='actorTaskId')] = None
|
|
91
|
+
started_at: Annotated[datetime, Field(alias='startedAt')]
|
|
92
|
+
finished_at: Annotated[datetime | None, Field(alias='finishedAt')] = None
|
|
93
|
+
status: Annotated[ActorJobStatus, Field(alias='status')]
|
|
94
|
+
status_message: Annotated[str | None, Field(alias='statusMessage')] = None
|
|
95
|
+
is_status_message_terminal: Annotated[bool | None, Field(alias='isStatusMessageTerminal')] = None
|
|
96
|
+
meta: Annotated[ActorRunMeta, Field(alias='meta')]
|
|
97
|
+
stats: Annotated[ActorRunStats, Field(alias='stats')]
|
|
98
|
+
options: Annotated[ActorRunOptions, Field(alias='options')]
|
|
99
|
+
build_id: Annotated[str, Field(alias='buildId')]
|
|
100
|
+
exit_code: Annotated[int | None, Field(alias='exitCode')] = None
|
|
101
|
+
default_key_value_store_id: Annotated[str, Field(alias='defaultKeyValueStoreId')]
|
|
102
|
+
default_dataset_id: Annotated[str, Field(alias='defaultDatasetId')]
|
|
103
|
+
default_request_queue_id: Annotated[str, Field(alias='defaultRequestQueueId')]
|
|
104
|
+
build_number: Annotated[str | None, Field(alias='buildNumber')] = None
|
|
105
|
+
container_url: Annotated[str, Field(alias='containerUrl')]
|
|
106
|
+
is_container_server_ready: Annotated[bool | None, Field(alias='isContainerServerReady')] = None
|
|
107
|
+
git_branch_name: Annotated[str | None, Field(alias='gitBranchName')] = None
|
|
108
|
+
usage: Annotated[ActorRunUsage | None, Field(alias='usage')] = None
|
|
109
|
+
usage_total_usd: Annotated[float | None, Field(alias='usageTotalUsd')] = None
|
|
110
|
+
usage_usd: Annotated[ActorRunUsage | None, Field(alias='usageUsd')] = None
|
|
@@ -16,7 +16,7 @@ from crawlee.proxy_configuration import ProxyInfo as CrawleeProxyInfo
|
|
|
16
16
|
from crawlee.proxy_configuration import _NewUrlFunction
|
|
17
17
|
|
|
18
18
|
from apify._configuration import Configuration
|
|
19
|
-
from apify.
|
|
19
|
+
from apify.log import logger
|
|
20
20
|
|
|
21
21
|
if TYPE_CHECKING:
|
|
22
22
|
from apify_client import ApifyClientAsync
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{apify-2.0.0b6 → apify-2.0.0b7}/src/apify/apify_storage_client/_dataset_collection_client.py
RENAMED
|
File without changes
|
|
File without changes
|
{apify-2.0.0b6 → apify-2.0.0b7}/src/apify/apify_storage_client/_key_value_store_collection_client.py
RENAMED
|
File without changes
|
|
File without changes
|
{apify-2.0.0b6 → apify-2.0.0b7}/src/apify/apify_storage_client/_request_queue_collection_client.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|