Source code for idmtools_platform_container.utils.status
"""
Here we implement the ContainerPlatform status utils.
Copyright 2021, Bill & Melinda Gates Foundation. All rights reserved.
"""
import os
from rich.console import Console
from typing import List, NoReturn
from logging import getLogger
from idmtools_platform_container.utils.general import normalize_path
logger = getLogger(__name__)
user_logger = getLogger('user')
#############################
# Check Status
#############################
status_mapping = {
'0': 'SUCCEEDED',
'100': 'RUNNING',
'-1': 'FAILED'
}
FILE_NAME = 'job_status.txt'
[docs]def get_simulation_status(sim_path: str) -> str:
"""
Get the status of a simulation.
Args:
sim_path: Simulation Directory Path
Returns:
simulation status
"""
status_file_path = os.path.join(sim_path, FILE_NAME)
if os.path.isfile(status_file_path):
with open(status_file_path, 'r') as file:
content = file.read().strip()
status = status_mapping.get(content, 'Pending')
return status
else:
return 'Pending'
[docs]def append_with_limit(lst: List, item: str, limit: int) -> List:
"""
Append an item to a list with a limit.
Args:
lst: list of items
item: item to be added
limit: max number of items in the list
Returns:
list: updated list
"""
if len(lst) < limit:
lst.append(item)
elif len(lst) == limit:
lst.append('...')
return lst
[docs]def summarize_status_files(exp_dir: str, max_display: int = 10, verbose: bool = False) -> NoReturn:
"""
Summarize the status of simulations.
Args:
exp_dir: Experiment Directory Path
max_display: the maximum number of items to display
verbose: whether to display the simulation details
Returns:
None
"""
summary = {
'SUCCEEDED': [],
'RUNNING': [],
'FAILED': [],
'PENDING': []
}
counter = {
'SUCCEEDED': 0,
'RUNNING': 0,
'FAILED': 0,
'PENDING': 0
}
total_simulation_count = 0
# Traverse through all sub-folders in the given folder path
for sub_folder in os.listdir(exp_dir):
sub_folder_path = os.path.join(exp_dir, sub_folder)
if os.path.isdir(sub_folder_path):
# Check if the sub-folder contains metadata.json
if not os.path.exists(os.path.join(sub_folder_path, 'metadata.json')):
continue
total_simulation_count += 1
status_file_path = os.path.join(sub_folder_path, FILE_NAME)
if os.path.isfile(status_file_path):
with open(status_file_path, 'r') as file:
content = file.read().strip()
status = status_mapping.get(content, 'PENDING')
summary[status] = append_with_limit(summary[status], sub_folder, max_display)
counter[status] += 1
else:
summary['PENDING'] = append_with_limit(summary['PENDING'], sub_folder, max_display)
counter['PENDING'] += 1
# Print out the results
console = Console()
console.print(f'\n[bold][cyan]Experiment Directory[/][/]: \n{normalize_path(exp_dir)}\n')
console.print(f"[bold][cyan]Simulation Count[/][/]: [yellow]{total_simulation_count}[/]\n")
for status in ['SUCCEEDED', 'FAILED', 'RUNNING', 'PENDING']:
# console.print(f"{status} ({counter[status]})")
if status == 'SUCCEEDED':
console.print(f"[bold][green]{status}[/][/] ({counter[status]})")
elif status == 'FAILED':
console.print(f"[bold][red]{status}[/][/] ({counter[status]})")
elif status == 'RUNNING':
console.print(f"[bold][cyan]{status}[/][/] ({counter[status]})")
elif status == 'PENDING':
console.print(f"[bold][grey69]{status}[/][/] ({counter[status]})")
if verbose:
for sim in summary[status]:
console.print(f"{sim:>40}")