@@ -127,22 +127,12 @@ def __init__(
127
127
128
128
self ._configuration = configuration
129
129
self ._configure_logging = configure_logging
130
- self ._apify_client = self . new_client ()
130
+ self ._apify_client : ApifyClientAsync | None = None
131
131
132
132
# Set the event manager based on whether the Actor is running on the platform or locally.
133
- self ._event_manager = (
134
- ApifyEventManager (
135
- configuration = self .config ,
136
- persist_state_interval = self .config .persist_state_interval ,
137
- )
138
- if self .is_at_home ()
139
- else LocalEventManager (
140
- system_info_interval = self .config .system_info_interval ,
141
- persist_state_interval = self .config .persist_state_interval ,
142
- )
143
- )
133
+ self ._event_manager : EventManager | None = None
144
134
145
- self ._charging_manager = ChargingManagerImplementation ( self . config , self . _apify_client )
135
+ self ._charging_manager : ChargingManagerImplementation | None = None
146
136
147
137
self ._is_initialized = False
148
138
@@ -200,6 +190,8 @@ def __call__(
200
190
@property
201
191
def apify_client (self ) -> ApifyClientAsync :
202
192
"""The ApifyClientAsync instance the Actor instance uses."""
193
+ if not self ._apify_client :
194
+ self ._apify_client = self .new_client ()
203
195
return self ._apify_client
204
196
205
197
@property
@@ -212,15 +204,26 @@ def config(self) -> Configuration:
212
204
"""The Configuration instance the Actor instance uses."""
213
205
if self ._configuration :
214
206
return self ._configuration
215
- self . log . debug (
216
- 'Implicit configuration used .'
217
- "It's recommended to explicitly set the configuration to avoid unexpected behavior."
207
+ raise RuntimeError (
208
+ 'Use of implicit configuration before entering Actor context is no longer allowed .'
209
+ 'Either pass explicit configuration or enter the Actor context.'
218
210
)
219
- return Configuration ()
220
211
221
212
@property
222
213
def event_manager (self ) -> EventManager :
223
214
"""The EventManager instance the Actor instance uses."""
215
+ if not self ._event_manager :
216
+ self ._event_manager = (
217
+ ApifyEventManager (
218
+ configuration = self .config ,
219
+ persist_state_interval = self .config .persist_state_interval ,
220
+ )
221
+ if self .is_at_home ()
222
+ else LocalEventManager (
223
+ system_info_interval = self .config .system_info_interval ,
224
+ persist_state_interval = self .config .persist_state_interval ,
225
+ )
226
+ )
224
227
return self ._event_manager
225
228
226
229
@property
@@ -305,10 +308,10 @@ async def init(self) -> None:
305
308
# TODO: Print outdated SDK version warning (we need a new env var for this)
306
309
# https://github.com/apify/apify-sdk-python/issues/146
307
310
308
- await self ._event_manager .__aenter__ ()
311
+ await self .event_manager .__aenter__ ()
309
312
self .log .debug ('Event manager initialized' )
310
313
311
- await self ._charging_manager .__aenter__ ()
314
+ await self ._get_charging_manager_implementation () .__aenter__ ()
312
315
self .log .debug ('Charging manager initialized' )
313
316
314
317
self ._is_initialized = True
@@ -349,10 +352,10 @@ async def finalize() -> None:
349
352
await asyncio .sleep (0.1 )
350
353
351
354
if event_listeners_timeout :
352
- await self ._event_manager .wait_for_all_listeners_to_complete (timeout = event_listeners_timeout )
355
+ await self .event_manager .wait_for_all_listeners_to_complete (timeout = event_listeners_timeout )
353
356
354
- await self ._event_manager .__aexit__ (None , None , None )
355
- await self ._charging_manager .__aexit__ (None , None , None )
357
+ await self .event_manager .__aexit__ (None , None , None )
358
+ await self ._get_charging_manager_implementation () .__aexit__ (None , None , None )
356
359
357
360
await asyncio .wait_for (finalize (), cleanup_timeout .total_seconds ())
358
361
self ._is_initialized = False
@@ -547,7 +550,9 @@ async def push_data(self, data: dict | list[dict], charged_event_name: str | Non
547
550
data = data if isinstance (data , list ) else [data ]
548
551
549
552
max_charged_count = (
550
- self ._charging_manager .calculate_max_event_charge_count_within_limit (charged_event_name )
553
+ self ._get_charging_manager_implementation ().calculate_max_event_charge_count_within_limit (
554
+ charged_event_name
555
+ )
551
556
if charged_event_name is not None
552
557
else None
553
558
)
@@ -561,7 +566,7 @@ async def push_data(self, data: dict | list[dict], charged_event_name: str | Non
561
566
await dataset .push_data (data )
562
567
563
568
if charged_event_name :
564
- return await self ._charging_manager .charge (
569
+ return await self .get_charging_manager () .charge (
565
570
event_name = charged_event_name ,
566
571
count = min (max_charged_count , len (data )) if max_charged_count is not None else len (data ),
567
572
)
@@ -617,7 +622,12 @@ async def set_value(
617
622
618
623
def get_charging_manager (self ) -> ChargingManager :
619
624
"""Retrieve the charging manager to access granular pricing information."""
625
+ return self ._get_charging_manager_implementation ()
626
+
627
+ def _get_charging_manager_implementation (self ) -> ChargingManagerImplementation :
620
628
self ._raise_if_not_initialized ()
629
+ if not self ._charging_manager :
630
+ self ._charging_manager = ChargingManagerImplementation (self .config , self .apify_client )
621
631
return self ._charging_manager
622
632
623
633
async def charge (self , event_name : str , count : int = 1 ) -> ChargeResult :
@@ -630,7 +640,7 @@ async def charge(self, event_name: str, count: int = 1) -> ChargeResult:
630
640
count: Number of events to charge for.
631
641
"""
632
642
self ._raise_if_not_initialized ()
633
- return await self ._charging_manager .charge (event_name , count )
643
+ return await self .get_charging_manager () .charge (event_name , count )
634
644
635
645
@overload
636
646
def on (
@@ -681,7 +691,7 @@ def on(self, event_name: Event, listener: EventListener[Any]) -> EventListener[A
681
691
"""
682
692
self ._raise_if_not_initialized ()
683
693
684
- self ._event_manager .on (event = event_name , listener = listener )
694
+ self .event_manager .on (event = event_name , listener = listener )
685
695
return listener
686
696
687
697
@overload
@@ -707,7 +717,7 @@ def off(self, event_name: Event, listener: Callable | None = None) -> None:
707
717
"""
708
718
self ._raise_if_not_initialized ()
709
719
710
- self ._event_manager .off (event = event_name , listener = listener )
720
+ self .event_manager .off (event = event_name , listener = listener )
711
721
712
722
def is_at_home (self ) -> bool :
713
723
"""Return `True` when the Actor is running on the Apify platform, and `False` otherwise (e.g. local run)."""
@@ -782,7 +792,7 @@ async def start(
782
792
"""
783
793
self ._raise_if_not_initialized ()
784
794
785
- client = self .new_client (token = token ) if token else self ._apify_client
795
+ client = self .new_client (token = token ) if token else self .apify_client
786
796
787
797
if webhooks :
788
798
serialized_webhooks = [
@@ -849,7 +859,7 @@ async def abort(
849
859
"""
850
860
self ._raise_if_not_initialized ()
851
861
852
- client = self .new_client (token = token ) if token else self ._apify_client
862
+ client = self .new_client (token = token ) if token else self .apify_client
853
863
854
864
if status_message :
855
865
await client .run (run_id ).update (status_message = status_message )
@@ -902,7 +912,7 @@ async def call(
902
912
"""
903
913
self ._raise_if_not_initialized ()
904
914
905
- client = self .new_client (token = token ) if token else self ._apify_client
915
+ client = self .new_client (token = token ) if token else self .apify_client
906
916
907
917
if webhooks :
908
918
serialized_webhooks = [
@@ -974,7 +984,7 @@ async def call_task(
974
984
"""
975
985
self ._raise_if_not_initialized ()
976
986
977
- client = self .new_client (token = token ) if token else self ._apify_client
987
+ client = self .new_client (token = token ) if token else self .apify_client
978
988
979
989
if webhooks :
980
990
serialized_webhooks = [
@@ -1031,7 +1041,7 @@ async def metamorph(
1031
1041
if not self .config .actor_run_id :
1032
1042
raise RuntimeError ('actor_run_id cannot be None when running on the Apify platform.' )
1033
1043
1034
- await self ._apify_client .run (self .config .actor_run_id ).metamorph (
1044
+ await self .apify_client .run (self .config .actor_run_id ).metamorph (
1035
1045
target_actor_id = target_actor_id ,
1036
1046
run_input = run_input ,
1037
1047
target_actor_build = target_actor_build ,
@@ -1077,10 +1087,10 @@ async def reboot(
1077
1087
# We can't just emit the events and wait for all listeners to finish,
1078
1088
# because this method might be called from an event listener itself, and we would deadlock.
1079
1089
persist_state_listeners = flatten (
1080
- (self ._event_manager ._listeners_to_wrappers [Event .PERSIST_STATE ] or {}).values () # noqa: SLF001
1090
+ (self .event_manager ._listeners_to_wrappers [Event .PERSIST_STATE ] or {}).values () # noqa: SLF001
1081
1091
)
1082
1092
migrating_listeners = flatten (
1083
- (self ._event_manager ._listeners_to_wrappers [Event .MIGRATING ] or {}).values () # noqa: SLF001
1093
+ (self .event_manager ._listeners_to_wrappers [Event .MIGRATING ] or {}).values () # noqa: SLF001
1084
1094
)
1085
1095
1086
1096
await asyncio .gather (
@@ -1091,7 +1101,7 @@ async def reboot(
1091
1101
if not self .config .actor_run_id :
1092
1102
raise RuntimeError ('actor_run_id cannot be None when running on the Apify platform.' )
1093
1103
1094
- await self ._apify_client .run (self .config .actor_run_id ).reboot ()
1104
+ await self .apify_client .run (self .config .actor_run_id ).reboot ()
1095
1105
1096
1106
if custom_after_sleep :
1097
1107
await asyncio .sleep (custom_after_sleep .total_seconds ())
@@ -1133,7 +1143,7 @@ async def add_webhook(
1133
1143
if not self .config .actor_run_id :
1134
1144
raise RuntimeError ('actor_run_id cannot be None when running on the Apify platform.' )
1135
1145
1136
- await self ._apify_client .webhooks ().create (
1146
+ await self .apify_client .webhooks ().create (
1137
1147
actor_run_id = self .config .actor_run_id ,
1138
1148
event_types = webhook .event_types ,
1139
1149
request_url = webhook .request_url ,
@@ -1169,7 +1179,7 @@ async def set_status_message(
1169
1179
if not self .config .actor_run_id :
1170
1180
raise RuntimeError ('actor_run_id cannot be None when running on the Apify platform.' )
1171
1181
1172
- api_result = await self ._apify_client .run (self .config .actor_run_id ).update (
1182
+ api_result = await self .apify_client .run (self .config .actor_run_id ).update (
1173
1183
status_message = status_message , is_status_message_terminal = is_terminal
1174
1184
)
1175
1185
0 commit comments