Source code for hardware_properties

"""
A module to load hardware properties from a json file. This information
is then accessible through class attributes.

The json file contains an object for a corresponding physical device.
Within these objects each property is characterized with an array
containing the information in following order: [value, type, unit,
comment]

Warning:
    Make sure that all keys within the json file are 'legal'/valid
    variables names in Python! Else the property is going to be assigned
    to an attribute name that cannot be accessed with the
    instance.attribute syntax. 

Example: 
    A json file containing following information:

    .. code-block::

        {...
            "device1":{
                "property1": [15, "int", "mm", "interesting comment and information"]
                "subdevice1": {
                    "subproperty1": [0.6, "float", "hectopascal", "interesting comment and information2"]
                    "subproperty2": ["foo", "str", "dimensionless", "interesting comment and information3"]
                }
            }
        ...}

    would be accessible through:

    .. code-block::

        >>> path = "path/to/hardware_properties.json"
        >>> hw = HardwareProperties(path)
        >>> hw.device1.property1
        >>> hw.device1.subdevice1.subproperty2

"""

# Helper modules
import logging
import typing
import os

# Essential modules
import json

# Set up logger
logger = logging.getLogger(__name__)

# Set up 'path'-like type
Path = typing.Union[str, bytes, os.PathLike]


[docs]class HardwareProperties: """ This class has attributes containing attributes to relevant hardware properties. Each json-object is instantiated as an Attribute-object. The properties/attributes of this json–object are then assigned as attribute to the instance. Args: path (Path): Path to json file containing properties of the hardware in the setup. """ def __init__(self, path: Path): with open(path) as json_file: # Load json file into dictionary self.hardware_properties = json.load(json_file) # Create attributes or classes that have attributes that hold # all properties create_class_and_attributes(self, self.hardware_properties)
[docs]def create_class_and_attributes(instance, dictionary: dict): """ Assigns the 0th entry of the values in dictionary as attributes to instance. The name of the attribute corresponds to the key of the value. If the value itself is a dictionary a new object is instantiated to which the values of the dictionary within value are assigned. (recursive algorithm) Args: instance (object): Instance of an object to which the values should be assigned dictionary (dict): Dictionary containing the values that should be assigned as attributes to the instance. The keys are the names of the attribute. Warning: Make sure that all keys are valid python variable names! Spaces in keys will automatically be replaced with underscores. """ # Iterate over entries in dictionary for key, value in dictionary.items(): key = key.replace(" ", "_") # Replace space character with underscore if type(value) == dict: # If value is itself a dictionary create an 'Attribute' # instance (subinstance) that holds all the entries of # 'value' as attributes. sub_instance = Attribute() create_class_and_attributes(sub_instance, value) # Assign 'Attribute' instance (subinstance) as attribute to # the actual instance that is of interest setattr(instance, key, sub_instance) elif type(value) == str: # mainly for the setup name attribute, where the dictionary # value is _not_ a list. This is more or less the only case # so far setattr(instance, key, value) else: # If value is not a dictionary, assign the 0th entry of the # array as attribute to instance with the name key setattr(instance, key, value[0])
[docs]class Attribute: pass
if __name__ == "__main__": path = "hardware_config_files/i-lab_hardware_properties.json" hw = HardwareProperties(path)