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 , WebhookEventType
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
18
18
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 ._models import ActorRun
22
23
from apify ._platform_event_manager import EventManager , LocalEventManager , PlatformEventManager
23
24
from apify ._proxy_configuration import ProxyConfiguration
24
25
from apify ._utils import get_system_info , is_running_in_ipython
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 @@ async def start(
533
536
memory_mbytes : int | None = None ,
534
537
timeout : timedelta | None = None ,
535
538
wait_for_finish : int | None = None ,
536
- webhooks : list [dict ] | None = None ,
537
- ) -> dict :
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 @@ async def start(
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,24 +566,33 @@ async def start(
567
566
568
567
client = self .new_client (token = token ) if token else self ._apify_client
569
568
570
- return await client .actor (actor_id ).start (
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 = 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 ,
583
591
* ,
584
592
token : str | None = None ,
585
593
status_message : str | None = None ,
586
594
gracefully : bool | None = None ,
587
- ) -> dict :
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 @@ async def abort(
607
615
if status_message :
608
616
await client .run (run_id ).update (status_message = status_message )
609
617
610
- return await client .run (run_id ).abort (gracefully = gracefully )
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 @@ async def call(
619
629
build : str | None = None ,
620
630
memory_mbytes : int | None = None ,
621
631
timeout : timedelta | None = None ,
622
- webhooks : list [dict ] | None = None ,
632
+ webhooks : list [Webhook ] | None = None ,
623
633
wait : timedelta | None = None ,
624
- ) -> dict | None :
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 @@ async def call(
650
660
651
661
client = self .new_client (token = token ) if token else self ._apify_client
652
662
653
- return await client .actor (actor_id ).call (
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 = 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 @@ async def call_task(
668
687
build : str | None = None ,
669
688
memory_mbytes : int | None = None ,
670
689
timeout : timedelta | None = None ,
671
- webhooks : list [dict ] | None = None ,
690
+ webhooks : list [Webhook ] | None = None ,
672
691
wait : timedelta | None = None ,
673
692
token : str | None = None ,
674
- ) -> dict | None :
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 @@ async def call_task(
703
722
704
723
client = self .new_client (token = token ) if token else self ._apify_client
705
724
706
- return await client .task (task_id ).call (
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 = 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 @@ async def reboot(
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
- ) -> dict | None :
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 @@ async def add_webhook(
814
840
For more information about Apify Actor webhooks, please see the [documentation](https://docs.apify.com/webhooks).
815
841
816
842
Args:
817
- event_types: List of event types that should trigger the webhook. At least one is required.
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 @@ async def add_webhook(
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 None
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
- return await self ._apify_client .webhooks ().create (
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 @@ async def set_status_message(
850
874
status_message : str ,
851
875
* ,
852
876
is_terminal : bool | None = None ,
853
- ) -> dict | None :
877
+ ) -> ActorRun | None :
854
878
"""Set the status message for the current Actor run.
855
879
856
880
Args:
@@ -871,10 +895,12 @@ async def set_status_message(
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
- return await self ._apify_client .run (self ._configuration .actor_run_id ).update (
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 commit comments