@@ -301,6 +301,7 @@ async def exit(
301
301
* ,
302
302
exit_code : int = 0 ,
303
303
event_listeners_timeout_secs : Optional [float ] = EVENT_LISTENERS_TIMEOUT_SECS ,
304
+ status_message : Optional [str ] = None ,
304
305
) -> None :
305
306
"""Exit the actor instance.
306
307
@@ -312,18 +313,21 @@ async def exit(
312
313
313
314
Args:
314
315
exit_code (int, optional): The exit code with which the actor should fail (defaults to `0`).
315
- event_listeners_timeout_secs (float, optional): How long should the actor wait for actor event listeners to finish before exiting
316
+ event_listeners_timeout_secs (float, optional): How long should the actor wait for actor event listeners to finish before exiting.
317
+ status_message (str, optional): The final status message that the actor should display.
316
318
"""
317
319
return await cls ._get_default_instance ().exit (
318
320
exit_code = exit_code ,
319
321
event_listeners_timeout_secs = event_listeners_timeout_secs ,
322
+ status_message = status_message ,
320
323
)
321
324
322
325
async def _exit_internal (
323
326
self ,
324
327
* ,
325
328
exit_code : int = 0 ,
326
329
event_listeners_timeout_secs : Optional [float ] = EVENT_LISTENERS_TIMEOUT_SECS ,
330
+ status_message : Optional [str ] = None ,
327
331
) -> None :
328
332
self ._raise_if_not_initialized ()
329
333
@@ -340,6 +344,9 @@ async def _exit_internal(
340
344
self ._event_manager .emit (ActorEventTypes .PERSIST_STATE , {'isMigrating' : False })
341
345
self ._was_final_persist_state_emitted = True
342
346
347
+ if status_message is not None :
348
+ await self .set_status_message (status_message , is_terminal = True )
349
+
343
350
# Sleep for a bit so that the listeners have a chance to trigger
344
351
await asyncio .sleep (0.1 )
345
352
@@ -362,6 +369,7 @@ async def fail(
362
369
* ,
363
370
exit_code : int = 1 ,
364
371
exception : Optional [BaseException ] = None ,
372
+ status_message : Optional [str ] = None ,
365
373
) -> None :
366
374
"""Fail the actor instance.
367
375
@@ -371,17 +379,20 @@ async def fail(
371
379
Args:
372
380
exit_code (int, optional): The exit code with which the actor should fail (defaults to `1`).
373
381
exception (BaseException, optional): The exception with which the actor failed.
382
+ status_message (str, optional): The final status message that the actor should display.
374
383
"""
375
384
return await cls ._get_default_instance ().fail (
376
385
exit_code = exit_code ,
377
386
exception = exception ,
387
+ status_message = status_message ,
378
388
)
379
389
380
390
async def _fail_internal (
381
391
self ,
382
392
* ,
383
393
exit_code : int = 1 ,
384
394
exception : Optional [BaseException ] = None ,
395
+ status_message : Optional [str ] = None ,
385
396
) -> None :
386
397
self ._raise_if_not_initialized ()
387
398
@@ -390,7 +401,7 @@ async def _fail_internal(
390
401
if exception and not _is_running_in_ipython ():
391
402
self .log .exception ('Actor failed with an exception' , exc_info = exception )
392
403
393
- await self .exit (exit_code = exit_code )
404
+ await self .exit (exit_code = exit_code , status_message = status_message )
394
405
395
406
@classmethod
396
407
async def main (cls , main_actor_function : Callable [[], MainReturnType ]) -> Optional [MainReturnType ]:
@@ -1210,28 +1221,30 @@ async def _add_webhook_internal(
1210
1221
)
1211
1222
1212
1223
@classmethod
1213
- async def set_status_message (cls , status_message : str ) -> Optional [Dict ]:
1224
+ async def set_status_message (cls , status_message : str , * , is_terminal : Optional [ bool ] = None ) -> Optional [Dict ]:
1214
1225
"""Set the status message for the current actor run.
1215
1226
1216
1227
Args:
1217
1228
status_message (str): The status message to set to the run.
1229
+ is_terminal (bool, optional): Set this flag to True if this is the final status message of the Actor run.
1218
1230
1219
1231
Returns:
1220
1232
dict: The updated actor run object
1221
1233
"""
1222
- return await cls ._get_default_instance ().set_status_message (status_message = status_message )
1234
+ return await cls ._get_default_instance ().set_status_message (status_message = status_message , is_terminal = is_terminal )
1223
1235
1224
- async def _set_status_message_internal (self , status_message : str ) -> Optional [Dict ]:
1236
+ async def _set_status_message_internal (self , status_message : str , * , is_terminal : Optional [ bool ] = None ) -> Optional [Dict ]:
1225
1237
self ._raise_if_not_initialized ()
1226
1238
1227
1239
if not self .is_at_home ():
1228
- self .log .error ('Actor.set_status_message() is only supported when running on the Apify platform.' )
1240
+ title = 'Terminal status message' if is_terminal else 'Status message'
1241
+ self .log .info (f'[{ title } ]: { status_message } ' )
1229
1242
return None
1230
1243
1231
1244
# If is_at_home() is True, config.actor_run_id is always set
1232
1245
assert self ._config .actor_run_id is not None
1233
1246
1234
- return await self ._apify_client .run (self ._config .actor_run_id ).update (status_message = status_message )
1247
+ return await self ._apify_client .run (self ._config .actor_run_id ).update (status_message = status_message , is_status_message_terminal = is_terminal )
1235
1248
1236
1249
@classmethod
1237
1250
async def create_proxy_configuration (
0 commit comments