Source code for idmtools.plugins.item_sequence
"""
Defines a id generator plugin that generates ids in sequence by item type.
To configure, set 'id_generator' in .ini configuration file to 'item_sequence':
[COMMON]
id_generator = item_sequence
You can also customize the sequence_file that stores the sequential ids per item type
as well as the id format using the following parameters in the .ini configuration file:
[item_sequence]
sequence_file = <file_name>.json ex: index.json
id_format_str = <custom_str_format> ex: {item_name}{data[item_name]:06d}
Copyright 2021, Bill & Melinda Gates Foundation. All rights reserved.
"""
import shutil
import json
import time
import warnings
from functools import lru_cache
from json import JSONDecodeError
from logging import getLogger, INFO, DEBUG
from pathlib import Path
from random import randint
import jinja2
from filelock import FileLock
from idmtools import IdmConfigParser
from idmtools.core import IDMTOOLS_USER_HOME
from idmtools.registry.hook_specs import function_hook_impl
from idmtools.core.interfaces.ientity import IEntity
logger = getLogger(__name__)
SEQUENCE_FILE_DEFAULT_PATH = IDMTOOLS_USER_HOME.joinpath("itemsequence", "index.json")
[docs]def load_existing_sequence_data(sequence_file):
"""
Loads item sequence data from sequence_file into a dictionary.
Args:
sequence_file: File that user has indicated to store the sequential ids of items
Returns:
Data loaded from sequence_file as a dictionary
"""
data = dict()
if Path(sequence_file).exists():
with open(sequence_file, 'r') as file:
try:
data = json.load(file)
except JSONDecodeError as e:
if logger.isEnabledFor(DEBUG):
logger.error("Trouble loading data from sequence_file. Verify that designated sequence_file is "
"not corrupted or deleted.")
logger.exception(e)
return dict()
return data
[docs]@lru_cache(maxsize=None)
def get_plugin_config():
"""
Retrieves the sequence file and format string (for id generation) from the .ini config file.
Returns:
sequence_file: specified json file in .ini config in which id generator keeps track of sequential id's
id_format_str: string specified in .ini config by which id's are formatted when assigned to sequential items
"""
warnings.warn('This feature is currently under development')
sequence_file = Path(IdmConfigParser.get_option("item_sequence", "sequence_file", SEQUENCE_FILE_DEFAULT_PATH))
id_format_str = IdmConfigParser.get_option("item_sequence", "id_format_str", None)
return sequence_file, id_format_str
@lru_cache(maxsize=None)
def _get_template(id_format_str):
"""
Get our jinja template. Cache this to reduce work.
Args:
id_format_str: Format string
Returns:
Jinja2 template
"""
environment = jinja2.Environment()
template = environment.from_string(id_format_str)
return template
[docs]@function_hook_impl
def idmtools_platform_post_run(item: 'IEntity', kwargs) -> 'IEntity':
"""
Do a backup of sequence file if it is the id generator.
Args:
item: Item(we only save on experiments/suites at the moment)
kwargs: extra args
Returns:
None
"""
from idmtools.entities.suite import Suite
from idmtools.entities.experiment import Experiment
if IdmConfigParser.get_option(None, "id_generator", "uuid").lower() == "item_sequence":
if isinstance(item, (Suite, Experiment)):
sequence_file = Path(IdmConfigParser.get_option("item_sequence", "sequence_file", SEQUENCE_FILE_DEFAULT_PATH))
sequence_file_bk = f'{sequence_file}.bak'
shutil.copy(sequence_file, sequence_file_bk)