cmeta.utils.common module
Common reusable functions
cMeta author and developer: (C) 2025-2026 Grigori Fursin
See the cMeta COPYRIGHT and LICENSE files in the project root for details.
Functions
- cmeta.utils.common.build_sort_key(artifact, sort_keys)[source]
Build a stable tuple key for artifact sorting rules.
- Parameters:
artifact – Artifact reference.
sort_keys – Sort key definitions.
- Returns:
Operation result.
- Return type:
dict
- Raises:
Exception – Propagated runtime errors, if any.
- cmeta.utils.common.check_params(params, keys, name=None)[source]
Validate that input dictionary contains only expected keys.
- Parameters:
params – Input parameters dictionary.
keys – Collection of dictionary keys.
name – Object or artifact name.
- Returns:
Operation result.
- Return type:
dict
- Raises:
Exception – Propagated runtime errors, if any.
- cmeta.utils.common.compare_versions(version1: str, version2: str)[source]
Compare two version strings.
- Parameters:
version1 (str) – First version string (e.g., “0.3.1”, “1.2”, “3.2.0-dev”)
version2 (str) – Second version string
- Returns:
- {‘return’: 0, ‘comparison’: ‘<’ | ‘=’ | ‘>’}
- where ‘<’ means version1 < version2
’=’ means version1 == version2 ‘>’ means version1 > version2
or {‘return’: 1, ‘error’: str} on error
- Return type:
dict
- Raises:
Exception – Propagated runtime errors, if any.
- cmeta.utils.common.copy_text_to_clipboard(text: str = '', add_quotes: bool = False, do_not_fail: bool = False)[source]
Copy text to system clipboard using pyperclip.
- Parameters:
text (str) – Text string to copy to clipboard.
add_quotes (bool) – If True, wraps text in double quotes before copying.
do_not_fail (bool) – If True, returns warning instead of error if pyperclip not installed.
- Returns:
Dictionary with ‘return’: 0 on success, or ‘return’ > 0 and ‘error’/’warning’ on failure.
- Return type:
dict
- Raises:
Exception – Propagated runtime errors, if any.
- cmeta.utils.common.deep_merge(target: dict, source: dict, append_lists: bool = False, prepend_lists: bool = False, ignore_root_keys: list = [], skip_if_exist_in_list: bool = True)[source]
Recursively updates the target dictionary with values from the source dictionary.
- Parameters:
target (dict) – The original dictionary to be updated.
source (dict) – The new dictionary with updates.
append_lists (bool) – If True, lists will be appended instead of overwritten.
prepend_lists (bool) – If True and append_lists is True, insert new items at the start of existing lists instead of appending at the end.
ignore_root_keys (list) – List of keys to ignore from source at the root level.
- Returns:
Operation result.
- Return type:
dict
- Raises:
Exception – Propagated runtime errors, if any.
- cmeta.utils.common.deep_remove(target: dict, source: dict)[source]
Recursively removes keys/values from target dictionary based on source dictionary.
- Parameters:
target (dict) – The dictionary to remove keys/values from (modified in place).
source (dict) – The dictionary specifying what to remove. - If value is a dict, recursively remove nested keys - If value is a list, remove list elements from target list - Otherwise, remove the entire key from target
- Returns:
The modified target dictionary
- Return type:
dict
- Raises:
Exception – Propagated runtime errors, if any.
- cmeta.utils.common.detect_cid_in_the_current_directory(cmeta, path: str = None, debug: bool = False, logger=None)[source]
Detect CMeta repository, category, and artifact from current or specified directory.
Traverses the directory tree to find CMeta repository information and determine which artifact the current path corresponds to.
- Parameters:
cmeta – CMeta instance.
path (str | None) – Directory path to check. If None, uses current working directory.
debug (bool) – If True, enables debug logging.
logger – Logger instance for debug output.
- Returns:
- Dictionary with ‘return’: 0 and detected information including:
artifact_repo_name: Name of the artifact repository
artifact_path: Relative path within repository
category_alias, category_uid: Category identifiers
category_obj: Category object string
artifact_alias, artifact_uid, artifact_name: Artifact identifiers
Or ‘return’ > 0 and ‘error’ on failure.
- Return type:
dict
- Raises:
Exception – Propagated runtime errors, if any.
- cmeta.utils.common.expand_string(template: str, values: dict) str[source]
Expand template placeholders from a values dictionary.
- Parameters:
template – Value for template.
values – Input values.
- Returns:
Result string value. (value): Result non-string value only if only one and non string!
(useful for env dict for example)
- Return type:
string
- Raises:
Exception – Propagated runtime errors, if any.
- cmeta.utils.common.expand_strings_in_dict(data, values: dict) dict[source]
Recursively expand template strings in a dictionary/list structure.
Traverses dictionaries and lists, calling expand_string on any string values found. Updates the original data in-place if expansion succeeds.
- Parameters:
data – Dictionary or list to process (modified in-place)
values – Dictionary of values for template expansion
- Returns:
{‘return’: 0} on success, or {‘return’: 1, ‘error’: str} on failure
- Return type:
dict
- Raises:
Exception – Propagated runtime errors, if any.
- cmeta.utils.common.flatten_dict(d, parent_key='', sep='.')[source]
Flatten a nested dictionary into dotted keys.
- Parameters:
d – Value for d.
parent_key – Value for parent key.
sep – Value for sep.
- Returns:
Operation result.
- Return type:
dict
- Raises:
Exception – Propagated runtime errors, if any.
- cmeta.utils.common.generate_timestamp(cut: int = None, slices: list = None)[source]
Generate timestamp string and optionally create sharded path.
Creates a timestamp in format YYYYMMDD-MMSS and optionally creates a sharded directory path from it.
- Parameters:
cut (int | None) – If specified, truncates timestamp to this many characters.
slices (list | None) – List of slice sizes for creating sharded path.
- Returns:
Dictionary with ‘return’: 0, ‘timestamp’ (string), and ‘path’ (sharded if slices provided).
- Return type:
dict
- Raises:
Exception – Propagated runtime errors, if any.
- cmeta.utils.common.matches_query(data, query, match_version_func=None, match_empty_version=False)[source]
Check whether input data satisfies a query dictionary.
- Parameters:
data – Input data object.
query – Value for query.
match_version_func – Value for match version func.
match_empty_version – Value for match empty version.
- Returns:
Operation result.
- Return type:
dict
- Raises:
Exception – Propagated runtime errors, if any.
- cmeta.utils.common.normalize_tags(tags, fail_on_error: bool = False)[source]
Normalize tags from string or list format to clean list of strings.
Converts comma-separated string to list and strips whitespace from each tag.
- Parameters:
tags (str | list) – Tags as comma-separated string or list of strings.
fail_on_error (bool) – If True, raises exception on error instead of returning error dict.
- Returns:
Dictionary with ‘return’: 0 and ‘tags’ list, or ‘return’ > 0 and ‘error’ on failure.
- Return type:
dict
- Raises:
Exception – Propagated runtime errors, if any.
- cmeta.utils.common.print_module_vars(obj, indent: int = 2, sort: bool = True, private: bool = True)[source]
- cmeta.utils.common.restricted_bool_eval(expression: str, variables: dict = None) bool[source]
Safely evaluate a boolean expression using restricted eval.
- Parameters:
expression – Boolean expression as a string
variables – Allowed variables (name -> value)
expression – Value for expression.
variables – Value for variables.
- Returns:
True or False (False on any error)
- Returns:
Result value.
- Return type:
bool
- Raises:
Exception – Propagated runtime errors, if any.
- cmeta.utils.common.safe_print_json(obj, indent: int = 2, non_serializable_text: str = None, ignore_keys: list = [], sort: bool = True)[source]
Print object as JSON with safe serialization of non-serializable objects.
- Parameters:
obj – Python object to print as JSON.
indent (int) – Number of spaces for indentation. Default is 2.
non_serializable_text (str | None) – Text to use for non-serializable objects.
ignore_keys (list) – List of top-level keys to exclude from output.
sort (bool) – If True, sort dictionary keys. Default is True.
- Returns:
Dictionary with ‘return’: 0.
- Return type:
dict
- Raises:
Exception – Propagated runtime errors, if any.
- cmeta.utils.common.safe_print_json_to_str(obj, indent: int = 2, non_serializable_text: str = None, ignore_keys: list = [], sort: bool = True)[source]
Convert object to JSON string with safe serialization.
- Parameters:
obj – Python object to convert to JSON string.
indent (int) – Number of spaces for indentation. Default is 2.
non_serializable_text (str | None) – Text to use for non-serializable objects.
ignore_keys (list) – List of top-level keys to exclude from output.
sort (bool) – If True, sort dictionary keys. Default is True.
- Returns:
JSON string representation of obj.
- Return type:
str
- Raises:
Exception – Propagated runtime errors, if any.
- cmeta.utils.common.safe_serialize_json(obj, non_serializable_text: str = None)[source]
Recursively serialize Python objects to JSON-compatible format.
Handles objects that are not JSON serializable by converting them to strings or nested structures. Sets, tuples, and non-serializable objects are handled.
- Parameters:
obj – Python object to serialize.
non_serializable_text (str | None) – Text to use for non-serializable objects. Default is “#NON-SERIALIZABLE#”.
- Returns:
JSON-serializable version of obj (dict, list, str, int, float, bool, None).
- Raises:
Exception – Propagated runtime errors, if any.
- cmeta.utils.common.smart_get(d: dict, key: str, default=None)[source]
Retrieve a value from a nested dictionary using a dot-separated key.
- Parameters:
d (dict) – The dictionary to query.
key (str) – Dot-separated key string (e.g., “a.b.c”).
default (Any, optional) – Value to return if any key is not found. Defaults to None.
- Returns:
The value found at the nested key path, or
defaultif the path does not exist.- Return type:
Any
Examples
>>> data = {'x': {'y': 'z'}} >>> smart_get(data, 'x.y') 'z' >>> smart_get(data, 'x') {'y': 'z'} >>> smart_get(data, 'a.b', 'NA') 'NA'
- cmeta.utils.common.sort_versions(versions, reverse=False)[source]
Sort version-like strings using numeric-aware comparison.
- Parameters:
versions – Value for versions.
reverse – Value for reverse.
- Returns:
Operation result.
- Return type:
dict
- Raises:
Exception – Propagated runtime errors, if any.
- cmeta.utils.common.value_matches(data_value, query_value, match_version_func=None, match_empty_version=False)[source]
Evaluate a single query value against a data value.
- Parameters:
data_value – Value for data value.
query_value – Value for query value.
match_version_func – Value for match version func.
match_empty_version – Value for match empty version.
- Returns:
Operation result.
- Return type:
dict
- Raises:
Exception – Propagated runtime errors, if any.