3535 _should_dispatch_app ,
3636 Logger ,
3737)
38+ from lightning_app .utilities .app_status import AppStatus
3839from lightning_app .utilities .commands .base import _process_requests
3940from lightning_app .utilities .component import _convert_paths_after_init , _validate_root_flow
4041from lightning_app .utilities .enum import AppStage , CacheCallsKeys
@@ -140,6 +141,7 @@ def __init__(
140141 self .exception = None
141142 self .collect_changes : bool = True
142143
144+ self .status : Optional [AppStatus ] = None
143145 # TODO: Enable ready locally for opening the UI.
144146 self .ready = False
145147
@@ -150,6 +152,7 @@ def __init__(
150152 self .checkpointing : bool = False
151153
152154 self ._update_layout ()
155+ self ._update_status ()
153156
154157 self .is_headless : Optional [bool ] = None
155158
@@ -418,6 +421,7 @@ def run_once(self):
418421
419422 self ._update_layout ()
420423 self ._update_is_headless ()
424+ self ._update_status ()
421425 self .maybe_apply_changes ()
422426
423427 if self .checkpointing and self ._should_snapshot ():
@@ -485,19 +489,12 @@ def _run(self) -> bool:
485489 self ._original_state = deepcopy (self .state )
486490 done = False
487491
488- # TODO: Re-enable the `ready` property once issues are resolved
489- if not self .root .ready :
490- warnings .warn (
491- "One of your Flows returned `.ready` as `False`. "
492- "This feature is not yet enabled so this will be ignored." ,
493- UserWarning ,
494- )
495- self .ready = True
492+ self .ready = self .root .ready
496493
497494 self ._start_with_flow_works ()
498495
499- if self .ready and self . should_publish_changes_to_api and self .api_publish_state_queue :
500- self .api_publish_state_queue .put (self .state_vars )
496+ if self .should_publish_changes_to_api and self .api_publish_state_queue is not None :
497+ self .api_publish_state_queue .put (( self .state_vars , self . status ) )
501498
502499 self ._reset_run_time_monitor ()
503500
@@ -506,8 +503,8 @@ def _run(self) -> bool:
506503
507504 self ._update_run_time_monitor ()
508505
509- if self .ready and self . _has_updated and self .should_publish_changes_to_api and self .api_publish_state_queue :
510- self .api_publish_state_queue .put (self .state_vars )
506+ if self ._has_updated and self .should_publish_changes_to_api and self .api_publish_state_queue is not None :
507+ self .api_publish_state_queue .put (( self .state_vars , self . status ) )
511508
512509 self ._has_updated = False
513510
@@ -532,6 +529,23 @@ def _update_is_headless(self) -> None:
532529 # This ensures support for apps which dynamically add a UI at runtime.
533530 _handle_is_headless (self )
534531
532+ def _update_status (self ) -> None :
533+ old_status = self .status
534+
535+ work_statuses = {}
536+ for work in breadth_first (self .root , types = (lightning_app .LightningWork ,)):
537+ work_statuses [work .name ] = work .status
538+
539+ self .status = AppStatus (
540+ is_ui_ready = self .ready ,
541+ work_statuses = work_statuses ,
542+ )
543+
544+ # If the work statuses changed, the state delta will trigger an update.
545+ # If ready has changed, we trigger an update manually.
546+ if self .status != old_status :
547+ self ._has_updated = True
548+
535549 def _apply_restarting (self ) -> bool :
536550 self ._reset_original_state ()
537551 # apply stage after restoring the original state.
0 commit comments