Utils#

Dictionaries#

load_dict_from_file(file_path: Path) dict[source]#

Safely load metadata from .yml or .json files.

exist_dict_in_list(d, ls)[source]#

Check if an identical dictionary exists in the list.

append_replace_dict_in_list(ls, d, compare_key, list_dict_deep_update: bool = True, remove_repeats: bool = True)[source]#

Update the list ls with the dict d.

Cases:

  1. If d is a dict and ls a list of dicts and ints/str, then for a given compare key, if for any element of ls (which is a dict) say: ls[3][compare_key] == d[compare_key], then it will dict_deep_update these instead of appending d to list ls. Only if compare_key is not present in any of dicts in the list ls, then d is simply appended to ls.

  2. If d is of immutable types like str, int etc., the ls is either appended with d or not. This depends on the value of remove_repeats. If remove_repeats is False, then ls is always appended with d. If remove_repeats is True, then if value d is present then it is not appended else it is.

Parameters
  • ls (list) – list of a dicts or int/str or a combination. This is the object to update

  • d (list/str/int) – this is the object from which ls is updated.

  • compare_key (str) – name of the key for which to check the presence of dicts in ls which need dict_deep_update

  • list_dict_deep_update (bool) – whether to update a dict in ls with compare_key present OR simply replace it.

  • remove_repeats (bool) – keep repeated values in the updated ls

Returns

ls – updated list

Return type

list

dict_deep_update(d: Mapping, u: Mapping, append_list: bool = True, remove_repeats: bool = True, copy: bool = True, compare_key: str = 'name', list_dict_deep_update: bool = True) Mapping[source]#

Perform an update to all nested keys of dictionary d(input) from dictionary u(updating dict).

Parameters
  • d (dict) – dictionary to update

  • u (dict) – dictionary to update from

  • append_list (bool) – if the item to update is a list, whether to append the lists or replace the list in d e.g. d = dict(key1=[1,2,3]), u = dict(key1=[3,4,5]). If True then updated dictionary d=dict(key1=[1,2,3,4,5]) else d=dict(key1=[3,4,5])

  • remove_repeats (bool) – for updating list in d[key] with list in u[key]: if true then remove repeats: list(set(ls))

  • copy (bool) – whether to deepcopy the input dict d

  • compare_key (str) – the key that is used to compare dicts (and perform update op) and update d[key] when it is a list if dicts. example:

    d = {
        [
            {"name": "timeseries1", "desc": "desc1 of d", "starting_time": 0.0},
            {"name": "timeseries2", "desc": "desc2"},
        ]
    }
    u = [{"name": "timeseries1", "desc": "desc2 of u", "unit": "n.a."}]
    # if compare_key='name' output is below
    output = [
        {"name": "timeseries1", "desc": "desc2 of u", "starting_time": 0.0, "unit": "n.a."},
        {"name": "timeseries2", "desc": "desc2"},
    ]
    # else the output is:
    # dict with the same key will be updated instead of being appended to the list
    output = [
        {"name": "timeseries1", "desc": "desc1 of d", "starting_time": 0.0},
        {"name": "timeseries2", "desc": "desc2"},
        {"name": "timeseries1", "desc": "desc2 of u", "unit": "n.a."},
    ]
    
  • list_dict_deep_update (bool) – for back compatibility, if False, this would work as before: example: if True then for the compare_key example, the output would be:

    output = [
        {"name": "timeseries1", "desc": "desc2 of u", "starting_time": 0.0, "unit": "n.a."},
        {"name": "timeseries2", "desc": "desc2"},
    ]
    # if False:
    output = [
        {"name": "timeseries1", "desc": "desc2 of u", "starting_time": 0.0},
        {"name": "timeseries2", "desc": "desc2"},
    ]  # unit key is absent since it is a replacement
    
Returns

d – return the updated dictionary

Return type

dict

class DeepDict(*args: Any, **kwargs: Any) None[source]#

Bases: defaultdict

A defaultdict of defaultdicts

A defaultdict of defaultdicts

deep_update(other: Optional[Union[dict, DeepDict]] = None, **kwargs) None[source]#

Recursively update the DeepDict with another dictionary or DeepDict.

Parameters
  • other (dict or DeepDict, optional) – The dictionary or DeepDict to update the current instance with.

  • **kwargs (Any) – Additional keyword arguments representing key-value pairs to update the DeepDict.

Notes

For any keys that exist in both the current instance and the provided dictionary, the values are merged recursively if both are dictionaries. Otherwise, the value from other or kwargs will overwrite the existing value.

to_dict() dict[source]#

Turn a DeepDict into a normal dictionary

__deepcopy__(memodict={})[source]#
Parameters

memodict (dict) – unused

Return type

DeepDict

JSON Schema#

get_base_schema(tag: Optional[str] = None, root: bool = False, id_: Optional[str] = None, required: Optional[list[str]] = None, properties: Optional[dict] = None, **kwargs) dict[source]#

Return the base schema used for all other schemas.

Parameters
  • tag (str, optional) – Tag to identify the schema.

  • root (bool, default: False) – Whether this schema is a root schema.

  • id_ (str, optional) – Schema identifier.

  • required (list of str, optional) – List of required property names.

  • properties (dict, optional) – Dictionary of property definitions.

  • **kwargs – Additional schema properties.

Returns

Base JSON schema with the following structure: {

”required”: List of required properties (empty if not provided) “properties”: Dictionary of property definitions (empty if not provided) “type”: “object” “additionalProperties”: False “tag”: Optional tag if provided “$schema”: Schema version if root is True “$id”: Schema ID if provided **kwargs: Any additional properties

}

Return type

dict

get_json_schema_from_method_signature(method: Callable, exclude: Optional[list[str]] = None) dict[source]#

Get the equivalent JSON schema for a signature of a method.

Also uses docstring_parser (NumPy style) to attempt to find descriptions for the arguments.

Parameters
  • method (callable) – The method to generate the JSON schema from.

  • exclude (list of str, optional) – List of arguments to exclude from the schema generation. Always includes ‘self’ and ‘cls’.

Returns

json_schema – The JSON schema corresponding to the method signature.

Return type

dict

fill_defaults(schema: dict, defaults: dict, overwrite: bool = True)[source]#

Insert the values of the defaults dict as default values in the schema in place.

Parameters
  • schema (dict)

  • defaults (dict)

  • overwrite (bool)

unroot_schema(schema: dict)[source]#

Modify a json-schema dictionary to make it not root.

Parameters

schema (dict)

get_schema_from_hdmf_class(hdmf_class)[source]#

Get metadata schema from hdmf class.

Parameters

hdmf_class (type) – The HDMF class to generate a schema from.

Returns

JSON schema derived from the HDMF class, containing: - tag: Full class path (module.name) - required: List of required fields - properties: Dictionary of field definitions including types and descriptions - additionalProperties: Whether extra fields are allowed

Return type

dict

get_metadata_schema_for_icephys() dict[source]#

Returns the metadata schema for icephys data.

Returns

The metadata schema for icephys data, containing definitions for Device, Electrode, and Session configurations.

Return type

dict

validate_metadata(metadata: dict[str, dict], schema: dict[str, dict], verbose: bool = False)[source]#

Validate metadata against a schema.

Common Reused Types#