Utils
A collection of more general utility functions.
LoggerUtility
Utility class for setting up logging consistently.
Source code in maestrowf/utils.py
__init__(logger)
Initialize a new LoggerUtility class instance.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
logger |
An instance of a logger to configure. |
required |
add_file_handler(log_path, log_format, log_lvl=2)
Add a file handler to logging.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
log_path |
String containing the file path to store logging. |
required | |
log_format |
String containing the desired logging format. |
required | |
log_lvl |
Integer level (1-5) to set the logger to. |
2
|
Source code in maestrowf/utils.py
add_stream_handler(log_format, log_lvl=2)
Add a stream handler to logging.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
log_format |
String containing the desired logging format. |
required | |
log_lvl |
Integer level (1-5) to set the logger to. |
2
|
Source code in maestrowf/utils.py
configure(log_format, log_lvl=2, colors=True)
Configures the general logging facility.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
log_format |
String containing the desired logging format. |
required | |
log_lvl |
Integer level (1-5) to set the logger to. |
2
|
Source code in maestrowf/utils.py
map_level(log_lvl)
staticmethod
Map level 1-5 to their respective logging enumerations.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
log_lvl |
Integer level (1-5) representing logging verbosity. |
required |
Source code in maestrowf/utils.py
apply_function(item, func)
Apply a function to items depending on type.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
item |
A Python primitive to apply a function to. |
required | |
func |
Function that returns takes item as a parameter and returns item modified in some way. |
required |
Source code in maestrowf/utils.py
coerce_dict_values(obj_to_transform, transform)
Recursively apply a transformation function to all values in a nested mapping.
Traverses the input object, recursively applying the given transformation function to each leaf value. If the input is a mapping (such as a dictionary), the function will process each value in the mapping. Non-mapping values are transformed directly.
This is useful for cases where you need to sanitize or coerce certain values
throughout a deeply nested dictionary structure. For example, the Flux CLI
converts None values to 1 for treedict inputs that represent flags.
This function can be used to replicate that behavior in the Python API.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
obj_to_transform |
Any
|
The object to transform. Can be a mapping or any other value. |
required |
transform |
Callable
|
A callable that takes a single value and returns the transformed value. |
required |
Returns:
| Type | Description |
|---|---|
dict
|
A new mapping with the same structure as the input, but with all leaf values transformed. |
Source code in maestrowf/utils.py
create_dictionary(list_keyvalues, token=':')
Create a dictionary from a list of key-value pairs.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
list_keyvalues |
List of token separates key-values. |
required | |
token |
The token to split each key-value by. |
':'
|
Returns:
| Type | Description |
|---|---|
|
A dictionary containing the key-value pairings in list_keyvalues. |
Source code in maestrowf/utils.py
create_parentdir(path)
Recursively create parent directories.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path |
Path to a directory to be created. |
required |
Source code in maestrowf/utils.py
csvtable_to_dict(fstream)
Convert a csv file stream into an in memory dictionary.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
fstream |
An open file stream to a csv table (with header) |
required |
Returns:
| Type | Description |
|---|---|
|
A dictionary with a key for each column header and a list of column values for each key. |
Source code in maestrowf/utils.py
dict_to_dot_strings(dictionary, prefix='', result=None, print_none=True)
Helper to convert dictionaries into dot syntax strings, e.g. converting from maestro's yaml into flux's treedict style syntax for more concise batch directives.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dictionary |
dict
|
Dictionary of args to flatten |
required |
prefix |
str
|
Prefix to use at current level (used for recursion) |
''
|
result |
list | None
|
Accumulated result list (used for recursion) |
None
|
print_none |
bool
|
Flag to print =None literal if value=None, or "" |
True
|
Returns:
| Type | Description |
|---|---|
list Example >>> dict_to_dot_strings({"foo": {"bar": 2, "foo2": 42}}) ['foo.bar=2', 'foo.foo2=42']
|
list of string views of dictionary in 'key.value' syntax |
Source code in maestrowf/utils.py
generate_filename(path, append_time=True)
Generate a non-conflicting file name.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path |
Path to file. |
required | |
append_time |
Setting to append a timestamp. |
True
|
Source code in maestrowf/utils.py
get_duration(time_delta)
Convert durations to HH:MM:SS format.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
time_delta |
A time difference in datatime format. |
required |
Returns:
| Type | Description |
|---|---|
|
A formatted string in HH:MM:SS |
Source code in maestrowf/utils.py
iter_dotpath_items(mapping, sep='.', prefix=None)
Yield (dotpath, value) pairs for all leaves in a nested mapping/dictionary. Leaves are any non-mapping objects.
:yields: Tuples of (dotpath, value) :ytype: tuple[str, any]
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
mapping |
Mapping[str, Any]
|
Mapping to flatten into list of dotpath strings |
required |
sep |
str
|
Optional separator used to join keys. Default = '.' |
'.'
|
Source code in maestrowf/utils.py
make_safe_path(base_path, *args)
Construct a subpath that is path safe.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
base_path |
The base path to append args to. |
required | |
args |
Path components to join into a path. |
()
|
Returns:
| Type | Description |
|---|---|
|
A joined subpath with invalid characters stripped. |
Source code in maestrowf/utils.py
parse_version(version_string)
Attempts using pep440 compliant version format and then falls back to a semver format to handle things like flux's version formats which can be a combination of the two.
Note: only major/minor/patch returned from semver parser; additional modifiers currently ignored for comparison purposes.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
version_string |
version string to parse |
required |
Returns:
| Type | Description |
|---|---|
|
Version object, or None |
Source code in maestrowf/utils.py
ping_url(url)
Load a webpage to test that it is accessible.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
url |
URL string to be loaded. |
required |
Source code in maestrowf/utils.py
round_datetime_seconds(input_datetime)
Round datetime to the nearest whole second.
Solution referenced from: https://stackoverflow.com/questions/47792242/ rounding-time-off-to-the-nearest-second-python.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
input_datetime |
A datetime in datatime format. |
required |
Returns:
| Type | Description |
|---|---|
|
|
Source code in maestrowf/utils.py
start_process(cmd, cwd=None, env=None, shell=True)
Start a new process using a specified command.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
cmd |
A string or a list representing the command to be run. |
required | |
cwd |
Current working path that the process will be started in. |
None
|
|
env |
A dictionary containing the environment the process will use. |
None
|
|
shell |
Boolean that determines if the process will run a shell. |
True
|
Source code in maestrowf/utils.py
unflatten_dotpath_dict(dotpath_dict, sep='.')
Flatten a dictionary that may contain dotpath encoded keys into a pure nested dictionary.
Note this does not account for '=value' being in the strings as the source of this is expected to be dictionaries from the study spec in yaml, not a fully rendered cli directives.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dotpaths |
Tuple[str, Any]
|
Tuple of dotpath string flattend dicts and values |
required |
sep |
str
|
Separator used to split dotpath strings into nested keys. Default = "." |
'.'
|
Returns:
| Type | Description |
|---|---|
Dict[str, Any]
|
nested dictionary view of the dotpath flattened input |
Source code in maestrowf/utils.py
unflatten_dotpath_tuples(dotpaths, sep='.')
Flatten a list of (dotpath_string, value) back into a nested dictionary.
Note this does not account for '=value' being in the strings as the source of this is expected to be dictionaries from the study spec in yaml, not a fully rendered cli directives.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dotpaths |
List[Tuple[str, Any]]
|
Tuple of dotpath string flattend dicts and values |
required |
sep |
str
|
Separator used to split dotpath strings into nested keys. Default = "." |
'.'
|
Returns:
| Type | Description |
|---|---|
Dict[str, Any]
|
nested dictionary view of the dotpath flattened input |
Source code in maestrowf/utils.py
update_recursive(base_dict, update_dict)
Recursively update a dictionary with values from another dictionary.
For each key in update_dict, updates the corresponding value in base_dict.
If both values for a given key are dictionaries, the update is performed recursively.
Otherwise, the value from update_dict overwrites the value in base_dict.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
base_dict |
dict
|
The dictionary to update in-place. |
required |
update_dict |
dict
|
The dictionary containing updates. |
required |
Returns:
| Type | Description |
|---|---|
dict .. note:: If a key exists in both dictionaries but the values are not both dicts, the value from ``update_dict`` will overwrite the value in ``base_dict``.
|
The updated base dictionary. |