1717from rich .text import Text
1818from rich .table import Table
1919
20- from ..managers .container_manager import ContainerManager , ServiceStatus , ServiceInfo , format_port_conflict_message
20+ from ..managers .container_manager import (
21+ ContainerManager ,
22+ ServiceStatus ,
23+ ServiceInfo ,
24+ format_port_conflict_message ,
25+ )
2126from ..managers .docling_manager import DoclingManager
2227from ..utils .platform import RuntimeType
2328from ..widgets .command_modal import CommandOutputModal
@@ -66,7 +71,6 @@ def container_manager(self) -> ContainerManager:
6671 self ._container_manager = self .app .container_manager
6772 return self ._container_manager
6873
69-
7074 def compose (self ) -> ComposeResult :
7175 """Create the monitoring screen layout."""
7276 # Just show the services content directly (no header, no tabs)
@@ -98,9 +102,7 @@ def _create_services_tab(self) -> ComposeResult:
98102 yield Horizontal (id = "services-controls" , classes = "button-row" )
99103 # Create services table with image + digest info
100104 self .services_table = DataTable (id = "services-table" )
101- self .services_table .add_columns (
102- "Service" , "Status" , "Health" , "Ports" , "Image" , "Digest"
103- )
105+ self .services_table .add_columns ("Service" , "Status" , "Health" , "Ports" , "Image" , "Digest" )
104106 yield self .services_table
105107 yield Static (" " )
106108
@@ -118,12 +120,8 @@ def _get_runtime_status(self) -> Text:
118120 status_text = Text ()
119121
120122 if not self .container_manager .is_available ():
121- status_text .append (
122- "WARNING: No container runtime available\n " , style = "bold red"
123- )
124- status_text .append (
125- "Please install Docker or Podman to continue.\n " , style = "dim"
126- )
123+ status_text .append ("WARNING: No container runtime available\n " , style = "bold red" )
124+ status_text .append ("Please install Docker or Podman to continue.\n " , style = "dim" )
127125 return status_text
128126
129127 runtime_info = self .container_manager .get_runtime_info ()
@@ -186,9 +184,7 @@ async def _refresh_services(self) -> None:
186184 images_set .add (img )
187185 # Ensure compose-declared images are also shown (e.g., langflow when stopped)
188186 try :
189- for img in (
190- self .container_manager ._parse_compose_images ()
191- ): # best-effort, no YAML dep
187+ for img in self .container_manager ._parse_compose_images (): # best-effort, no YAML dep
192188 if img :
193189 images_set .add (img )
194190 except Exception :
@@ -238,9 +234,7 @@ async def _refresh_services(self) -> None:
238234 if (docling_running or docling_starting )
239235 else "N/A"
240236 )
241- docling_pid = (
242- str (docling_status .get ("pid" )) if docling_status .get ("pid" ) else "N/A"
243- )
237+ docling_pid = str (docling_status .get ("pid" )) if docling_status .get ("pid" ) else "N/A"
244238
245239 if self .docling_table :
246240 self .docling_table .add_row (
@@ -365,6 +359,7 @@ async def _start_services(self, cpu_mode: Optional[bool] = None) -> None:
365359 # This ensures docker compose reads the correct version
366360 try :
367361 from ..managers .env_manager import EnvManager
362+
368363 env_manager = EnvManager ()
369364 env_manager .ensure_openrag_version ()
370365 # Small delay to ensure .env file is written and flushed
@@ -442,9 +437,7 @@ async def _upgrade_services(self) -> None:
442437 UpgradeInstructionsModal (current_version , latest_version )
443438 )
444439 except Exception as e :
445- self .notify (
446- f"Error checking version: { str (e )} " , severity = "error" , timeout = 10
447- )
440+ self .notify (f"Error checking version: { str (e )} " , severity = "error" , timeout = 10 )
448441 finally :
449442 self .operation_in_progress = False
450443
@@ -453,9 +446,7 @@ async def _reset_services(self) -> None:
453446 self .operation_in_progress = True
454447 try :
455448 # Show factory reset warning modal first
456- should_continue = await self .app .push_screen_wait (
457- FactoryResetWarningModal ()
458- )
449+ should_continue = await self .app .push_screen_wait (FactoryResetWarningModal ())
459450 if not should_continue :
460451 self .notify ("Factory reset cancelled" , severity = "information" )
461452 return
@@ -475,6 +466,7 @@ async def _reset_services(self) -> None:
475466 try :
476467 # Get paths from env config
477468 from ..managers .env_manager import EnvManager
469+
478470 env_manager = EnvManager ()
479471 env_manager .load_existing_env ()
480472
@@ -487,7 +479,9 @@ def expand_path(path_str: str) -> Path:
487479
488480 if config_path .exists ():
489481 # Use container to handle files owned by container user
490- success , msg = await self .container_manager .clear_directory_with_container (config_path )
482+ success , msg = await self .container_manager .clear_directory_with_container (
483+ config_path
484+ )
491485 if not success :
492486 # Fallback to regular rmtree if container method fails
493487 shutil .rmtree (config_path )
@@ -497,7 +491,9 @@ def expand_path(path_str: str) -> Path:
497491 # Also delete legacy TUI config folder if it exists (~/.openrag/tui/config/)
498492 tui_config_path = expand_path (env_manager .config .openrag_tui_config_path_legacy )
499493 if tui_config_path .exists ():
500- success , msg = await self .container_manager .clear_directory_with_container (tui_config_path )
494+ success , msg = await self .container_manager .clear_directory_with_container (
495+ tui_config_path
496+ )
501497 if not success :
502498 # Fallback to regular rmtree if container method fails
503499 shutil .rmtree (tui_config_path )
@@ -507,7 +503,9 @@ def expand_path(path_str: str) -> Path:
507503 # Clear backend data directory (database, session ownership, conversations, oauth tokens)
508504 data_path = expand_path (env_manager .config .openrag_data_path )
509505 if data_path .exists ():
510- success , msg = await self .container_manager .clear_directory_with_container (data_path )
506+ success , msg = await self .container_manager .clear_directory_with_container (
507+ data_path
508+ )
511509 if not success :
512510 shutil .rmtree (data_path )
513511 data_path .mkdir (parents = True , exist_ok = True )
@@ -516,16 +514,20 @@ def expand_path(path_str: str) -> Path:
516514 if self ._check_flow_backups ():
517515 if delete_backups :
518516 # Use container to handle files owned by container user
519- success , msg = await self .container_manager .clear_directory_with_container (flows_backup_path )
517+ success , msg = await self .container_manager .clear_directory_with_container (
518+ flows_backup_path
519+ )
520520 if not success :
521521 # Fallback to regular rmtree if container method fails
522522 shutil .rmtree (flows_backup_path )
523523 # Recreate empty backup directory
524524 flows_backup_path .mkdir (parents = True , exist_ok = True )
525525 self .notify ("Flow backups deleted" , severity = "information" )
526526 else :
527- self .notify (f"Flow backups preserved in { flows_backup_path } " , severity = "information" )
528-
527+ self .notify (
528+ f"Flow backups preserved in { flows_backup_path } " , severity = "information"
529+ )
530+
529531 except Exception as e :
530532 self .notify (
531533 f"Error clearing config: { str (e )} " ,
@@ -556,12 +558,14 @@ async def _factory_reset_with_data_clear(self) -> AsyncIterator[tuple[bool, str]
556558
557559 # Get data paths from env config
558560 from ..managers .env_manager import EnvManager
561+
559562 env_manager = EnvManager ()
560563 env_manager .load_existing_env ()
561564
562565 # Delete langflow-data directory (mirrors Makefile factory-reset behaviour)
563566 yield False , "Clearing Langflow data..."
564567 from tui .main import _resolve_langflow_data_path
568+
565569 langflow_data_path = _resolve_langflow_data_path (Path .home () / ".openrag" ).resolve ()
566570 home = Path .home ().resolve ()
567571 if not str (langflow_data_path ).startswith (str (home ) + "/" ):
@@ -583,13 +587,13 @@ async def _prune_images(self) -> None:
583587 try :
584588 # Show prune options modal
585589 from tui .widgets .prune_options_modal import PruneOptionsModal
586-
590+
587591 prune_choice = await self .app .push_screen_wait (PruneOptionsModal ())
588-
592+
589593 if prune_choice == "cancel" :
590594 self .notify ("Prune cancelled" , severity = "information" )
591595 return
592-
596+
593597 # Choose the appropriate pruning method based on user choice
594598 if prune_choice == "all" :
595599 # Stop services and prune all images
@@ -599,7 +603,7 @@ async def _prune_images(self) -> None:
599603 # Prune only unused images (default)
600604 command_generator = self .container_manager .prune_old_images ()
601605 modal_title = "Pruning Unused Images"
602-
606+
603607 # Show command output in modal dialog
604608 modal = CommandOutputModal (
605609 modal_title ,
@@ -618,7 +622,9 @@ def _check_flow_backups(self) -> bool:
618622 # Get flows path from env config
619623 env_manager = EnvManager ()
620624 env_manager .load_existing_env ()
621- flows_path = Path (env_manager .config .openrag_flows_path .replace ("$HOME" , str (Path .home ()))).expanduser ()
625+ flows_path = Path (
626+ env_manager .config .openrag_flows_path .replace ("$HOME" , str (Path .home ()))
627+ ).expanduser ()
622628 backup_dir = flows_path / "backup"
623629 if not backup_dir .exists ():
624630 return False
@@ -659,9 +665,7 @@ async def _start_docling_serve(self) -> None:
659665 if success :
660666 self .notify (message , severity = "information" )
661667 else :
662- self .notify (
663- f"Failed to start docling serve: { message } " , severity = "error"
664- )
668+ self .notify (f"Failed to start docling serve: { message } " , severity = "error" )
665669 # Refresh again to show final status (running or stopped)
666670 await self ._refresh_services ()
667671 except Exception as e :
@@ -679,9 +683,7 @@ async def _stop_docling_serve(self) -> None:
679683 if success :
680684 self .notify (message , severity = "information" )
681685 else :
682- self .notify (
683- f"Failed to stop docling serve: { message } " , severity = "error"
684- )
686+ self .notify (f"Failed to stop docling serve: { message } " , severity = "error" )
685687 # Refresh the services table to show updated status
686688 await self ._refresh_services ()
687689 except Exception as e :
@@ -697,9 +699,7 @@ async def _restart_docling_serve(self) -> None:
697699 if success :
698700 self .notify (message , severity = "information" )
699701 else :
700- self .notify (
701- f"Failed to restart docling serve: { message } " , severity = "error"
702- )
702+ self .notify (f"Failed to restart docling serve: { message } " , severity = "error" )
703703 # Refresh the services table to show updated status
704704 await self ._refresh_services ()
705705 except Exception as e :
@@ -788,9 +788,7 @@ async def _follow_logs(self) -> None:
788788 except Exception :
789789 pass
790790 except Exception as e :
791- notify_with_diagnostics (
792- self .app , f"Error following logs: { e } " , severity = "error"
793- )
791+ notify_with_diagnostics (self .app , f"Error following logs: { e } " , severity = "error" )
794792
795793 def action_refresh (self ) -> None :
796794 """Refresh services manually."""
@@ -869,9 +867,7 @@ def action_toggle_mode(self) -> None:
869867 self ._update_mode_row ()
870868 self .action_refresh ()
871869 except Exception as e :
872- notify_with_diagnostics (
873- self .app , f"Failed to toggle mode: { e } " , severity = "error"
874- )
870+ notify_with_diagnostics (self .app , f"Failed to toggle mode: { e } " , severity = "error" )
875871
876872 def _update_controls (self , services : list [ServiceInfo ]) -> None :
877873 """Update control buttons based on running state."""
@@ -894,31 +890,19 @@ def _update_controls(self, services: list[ServiceInfo]) -> None:
894890 # Add appropriate buttons based on service state
895891 if any_running :
896892 # When services are running, show stop and restart
897- controls .mount (
898- Button ("Stop Services" , variant = "error" , id = f"stop-btn{ suffix } " )
899- )
900- controls .mount (
901- Button ("Restart" , variant = "primary" , id = f"restart-btn{ suffix } " )
902- )
893+ controls .mount (Button ("Stop Services" , variant = "error" , id = f"stop-btn{ suffix } " ))
894+ controls .mount (Button ("Restart" , variant = "primary" , id = f"restart-btn{ suffix } " ))
903895 else :
904896 # When services are not running, show start
905- controls .mount (
906- Button ("Start Services" , variant = "success" , id = f"start-btn{ suffix } " )
907- )
897+ controls .mount (Button ("Start Services" , variant = "success" , id = f"start-btn{ suffix } " ))
908898
909899 # Always show upgrade, prune, and reset buttons
910- controls .mount (
911- Button ("Upgrade" , variant = "warning" , id = f"upgrade-btn{ suffix } " )
912- )
913- controls .mount (
914- Button ("Prune Images" , variant = "default" , id = f"prune-btn{ suffix } " )
915- )
900+ controls .mount (Button ("Upgrade" , variant = "warning" , id = f"upgrade-btn{ suffix } " ))
901+ controls .mount (Button ("Prune Images" , variant = "default" , id = f"prune-btn{ suffix } " ))
916902 controls .mount (Button ("Factory Reset" , variant = "error" , id = f"reset-btn{ suffix } " ))
917903
918904 except Exception as e :
919- notify_with_diagnostics (
920- self .app , f"Error updating controls: { e } " , severity = "error"
921- )
905+ notify_with_diagnostics (self .app , f"Error updating controls: { e } " , severity = "error" )
922906
923907 # Update docling controls separately
924908 self ._update_docling_controls ()
@@ -948,9 +932,7 @@ def _update_docling_controls(self) -> None:
948932 Button ("Stop" , variant = "error" , id = f"docling-stop-btn{ suffix } " )
949933 )
950934 docling_controls .mount (
951- Button (
952- "Restart" , variant = "primary" , id = f"docling-restart-btn{ suffix } "
953- )
935+ Button ("Restart" , variant = "primary" , id = f"docling-restart-btn{ suffix } " )
954936 )
955937 elif docling_starting :
956938 # Show disabled button or no button when starting
@@ -1119,9 +1101,7 @@ def _set_cursor_row(self, table: DataTable | None, row: int) -> None:
11191101 except Exception :
11201102 pass
11211103
1122- def _focus_services_table (
1123- self , row : str | None = None , set_last : bool = True
1124- ) -> None :
1104+ def _focus_services_table (self , row : str | None = None , set_last : bool = True ) -> None :
11251105 """Focus the services table and update selection."""
11261106 if not self .services_table :
11271107 return
0 commit comments