3.4. Code Documentation

This section describes a number of primary classes that are used widely in the application, and need to be understood in order to implement any plugins.

3.4.1. Database Implementation

3.4.1.1. Top-level Database object

This class defines how to create and open a device’s configuration data. Note that a particular device might define plugins that can save this database format into some other format - such as XML or YAML - and that is independent of this database format.

The data that is manipulated in the PyConfigTool is held in a “model” object (think Model-View-Controller paradigm). This package defines the implementation of this object tree. It is held in a ZODB database, which makes these objects magically persistent, and subject to transactional semmantics.

class configurationmodel.DatabaseLocation[source]

This implements the IDatabaseLocation marker interface.

class configurationmodel.DeviceDatabase(pth: pathlib.Path)[source]

This class holds the reference to the database file that has been opened. The open() method returns the root domain object.

See the documentation on the persistent objects that are used in this database connection.

This class can be used as a context manager, which provides the root ConfigDomain object:

with DeviceDatabase('some_file') as root_domain:
    assert isinstance(root_domain, ConfigDomain)
    ...

and the database will be correctly closed and cleaned up after the context closes.

close() → None[source]

Close the connection and the database, and delete the ZODB temporary working files for the db file.

commit() → None[source]

Commit the current model transaction.

Before calling commit on the global transaction manager, this method attaches callbacks to its pre- and post-commit hooks. These hooks have to be attached for every new transaction, which is a bit irritating. These hooks then set and clear the ISavingModelState variable, which the user interface can use to indicate the saving of the model data.

find_attr_by_key(attr_key: str) → Optional[configurationmodel.configdomain.ConfigAttributeBase][source]

Find the attribute in the database which has the key name provided. This method uses the search_database generic method to perform this search.

Returns:The ConfigAttributeBase-derived object if it’s found, or None.
find_attr_by_value(attr_value: str) → Optional[configurationmodel.configdomain.ConfigAttributeBase][source]

Find the attribute in the database which has the value provided. This method uses the search_database generic method to perform this search.

Returns:The ConfigAttributeBase-derived object if it’s found, or None.
find_by_url(url: str)[source]

Find the object of a requested type by its object id. This method uses the search_database generic method to perform this search.

Returns:The object if it’s found, or None.
find_domain_by_name(domain_name: str) → Optional[configurationmodel.configdomain.ConfigDomain][source]

Find the domain with a particular name. This method uses the search_database generic method to perform this search.

Returns:The ConfigDomain object if it’s found, or None.
open(create_if_needed=True) → configurationmodel.configdomain.ConfigDomain[source]

Open the file that was passed to the constructor of this class. If the file doesn’t exist then the database file is created with a root object.

Returns:The root ConfigDomain object.
search_database(callback: Callable[[Any], Any]) → Any[source]

Search through the instance objects that are in the database tree, calling the callback function with each object instance found. If the callback function returns a non-None value, then the recursive walk is abandoned and this value is returned.

The objects in the tree for which the callback will be called are of type ConfigDomain, ConfigContainer, and various classes derived from ConfigAttributeBase.

Returns:Whatever first non-None value that a call to the callback function returned.
walk_database(callback: Callable[[Any], None]) → None[source]

Walk all the instance objects that are in the database tree and call on the callback function with each object instance found. The objects in the tree for which the callback will be called are of type ConfigDomain, ConfigContainer, and various classes derived from ConfigAttributeBase.

3.4.1.2. ConfigDomain

Inheritance diagram of configurationmodel.configdomain.ConfigDomain

This module defines the objects that can appear in the Device configuration object database.

class configurationmodel.configdomain.ConfigAttributeBase(key: str, name: str, description: str, attr_type: str, attr_default: object = None, attr_value: object = None, view: str = 'default-view', **kwargs)[source]

The base class for all single-value attribute elements.

dump_attr(depth: int)[source]

Debug utility.

class configurationmodel.configdomain.ConfigAttributeCheckItem(key: str, name: str, description: str, checked: bool = False, **kwargs)[source]

This data model item represents a boolean value, which is normally displayed as a checkbox item.

checked

Return the value of the attribute, which should be a boolean.

class configurationmodel.configdomain.ConfigAttributeComboboxItem(key: str, name: str, description: str, value: str, choices: Tuple[Tuple[str]], **kwargs)[source]

This data model item represents a single choice from a specified list of options. The options should be expressed as a tuple, where each option is a two-tuple: a key, followed by the visible string that is presented in the user interface for that option. The value of the currently-selected option is the corresponding key, not the value that is displayed in the user interface.

set_index(idx)[source]

Set the value of this attrbute to the idx-th one in the list of choices for the combobox.

value

Return the value of the attribute, which should be one of the choice keys.

class configurationmodel.configdomain.ConfigAttributeFloatItem(key: str, name: str, description: str, value: float = 0.0, precision: int = 1, min_value=None, max_value=None, **kwargs)[source]

This data model item represents an integer value, which is normally displayed as a spinner box item.

value

Return the value of the attribute, which should be an integer.

class configurationmodel.configdomain.ConfigAttributeIntegerItem(key: str, name: str, description: str, value: int = 0, min_value=None, max_value=None, **kwargs)[source]

This data model item represents an integer value, which is normally displayed as a spinner box item.

value

Return the value of the attribute, which should be an integer.

class configurationmodel.configdomain.ConfigAttributeStruct(key: str, name: str, description: str, value: persistent.list.PersistentList, **kwargs)[source]

This data model item represents a table. Tables contain a list of other ConfigAttributes which have been initialized with PersistentList type values. Each column displays a different ConfigAttribute and each row is populated with the indexed element from the PersistentList held by the ConfigAttributes value property.

domain

Return the value of the attribute, which should be the list of structure instances.

dump_attr(depth: int)[source]

Debug utility.

class configurationmodel.configdomain.ConfigAttributeTableItem(key: str, name: str, description: str, value: persistent.list.PersistentList, **kwargs)[source]

This data model item represents a table. Tables contain a list of other ConfigAttributes which have been initialized with PersistentList type values. Each column displays a different ConfigAttribute and each row is populated with the indexed element from the PersistentList held by the ConfigAttributes value property.

dump_attr(depth: int)[source]

Debug utility.

table

Return the value of the attribute, which should be the list of other attributes.

class configurationmodel.configdomain.ConfigAttributeTextItem(key: str, name: str, description: str, value: str, **kwargs)[source]

This data model item represents a single unicode string which is usually displayed as a single line editor box.

value

Return the value of the attribute, which should be the input text string.

class configurationmodel.configdomain.ConfigDomain(name: str, description: str = '', key: str = None)[source]

This class defines the container of a set of configuration attributes that relevant to one domain. Each ConfigDomain contains attributes and child ConfigDomain objects.

The UI usually represents a domain as a node in the tree of data, with an associated panel of individual data values, which are held in a ConfigDomainContainer object.

add_attribute(attr) → None[source]

Add an attribute to the container.

add_child_domain(child)[source]

Add a ConfigDomain object to be the child of this one. The child’s parent is updated to refer to this domain.

add_dummy_data() → None[source]

Debug and test utility that adds a few dummy child ConfigDomain nodes to the current domain node, and then a transaction is committed.

dump_domains(depth: int = 0) → None[source]

Dump the ConfigDomain, useful for debugging.

owned_by(parent)[source]

Take ownership of this ConfigDomain, which just sets the _parent attribute.

parent

Returns the parent ConfigDomain object, or None if this is the root of the tree.

parents()[source]

This generator method returns all the parents of the current ConfigDomain, starting with the root object and ending with the immediate parent of this instance.

search_domains(callback: Callable[[Any], None]) → None[source]

This method will walk all object under it calling the callback with a reference to that object. If the callback returns a non-None result, the recursive walk is stopped, and that value is returned.

walk_domains(callback: Callable[[Any], None]) → None[source]

This method will call the callback supplying this domain object first. Then it will call ConfigContainer.walk_attributes() if this domain has a ConfigContainer, and then finally call this method recursively on any child domains.

class configurationmodel.configdomain.ConfigDomainContainer[source]

This container object contains all the attributes that should be displayed on the right-hand-side pane when the tree item to which this container is attached is clicked on.

add_attribute(attr: configurationmodel.configdomain.ConfigAttributeBase) → None[source]

Add an attribute to the container.

dump_container(depth: int) → None[source]

Debug utility method.

search_attributes(callback: Callable[[Any], Any]) → Any[source]

This method will first call the callback with this container instance as the only argument. If a non-None result is returned, this this result is returned immediately. If not then it will then call the callback for each of the attributes that are contained in this container, stoping whenever the callback returns a non-None value.

walk_attributes(callback: Callable[[Any], None]) → None[source]

This method will first call the callback with this container instance as the only argument, and then it will call the callback for each of the attributes that are contained in this container.

class configurationmodel.configdomain.DependencyReferenceSpec(depends_on: str, condition_test: object = None, invert: bool = False)[source]

The class describes a dependency between one attribute and the current value of some other attribute in the database. For example, it is used to define a link between the enablement of one attribute with the value of some other check box.

check() → bool[source]

Perform the dependency check on the referenced attribute. The sense of the test is inverted if the invert=True was passed into the constructor.

depends_on_attribute

Lazy evaluation to find the attribute to which this object describes a dependency on. This read-only property searches the database for an attribute of a particular key, and returns that.

Given that this could be an expensive operation, the attibute that is found is cached in the this object. In order that this cached value is not persisted, its name has to start with _v_, which is the indication to the ZODB persistence layer that this is a volatile attribute.

class configurationmodel.configdomain.StructDomain(name: str, description: str = '', key: str = None)[source]

StructDomain defines a set of configuration structures each containing lists of attributes that are relevant to a single struct instance.

The UI typically represents a struct domain as a tabbed set of data values, which are held in a QTabWidget object.

add_attribute(attr: configurationmodel.configdomain.ConfigAttributeBase) → None[source]

Add an attribute to the container.

add_child_domain(child)[source]

Structs cannot have subdomains.

add_dummy_data() → None[source]

Debug and test utility that adds some dummy child attributes to the structure domain, clones it and then a transaction is committed.

add_struct() → object[source]

Add a ConfigDomainContainer to the list.

clone_struct(index) → None[source]

Add a copy of a ConfigDomainContainer to the list.

delete_struct(index) → None[source]

Add a ConfigDomainContainer to the list.

dump_domains(depth: int = 0) → None[source]

Dump the StructDomain, useful for debugging.

search_attributes(callback: Callable[[Any], Any]) → Any[source]

This method will first call the callback with this container instance as the only argument. If a non-None result is returned, this this result is returned immediately. If not then it will then call the callback for each of the attributes that are contained in this container, stoping whenever the callback returns a non-None value.

search_domains(callback: Callable[[Any], None]) → None[source]

This method will walk all object under it calling the callback with a reference to that object. If the callback returns a non-None result, the recursive walk is stopped, and that value is returned.

walk_attributes(callback: Callable[[Any], None]) → None[source]

This method will first call the callback with this container instance as the only argument, and then it will call the callback for each of the attributes that are contained in this container.

class configurationmodel.configdomain.TableDomain(name: str, description: str = '', key: str = None)[source]

This class defines the container of a set of configuration attributes that are relevant to one table. Each TableDomain contains attributes.

The UI represents a table domain as a table of data values, which are held in a QTableWidget object.

add_attribute(attr: configurationmodel.configdomain.ConfigAttributeBase) → None[source]

Add an attribute to the container.

add_child_domain(child)[source]

Tables cannot have subdomains.

add_dummy_data() → None[source]

Debug and test utility that adds some dummy child attributes to the current table domain, and then a transaction is committed.

dump_domains(depth: int = 0) → None[source]

Dump the TableDomain, useful for debugging.

extend_attributes(minimum=0)[source]

Extend all table attributes to the length of the longest attribute or the minimum :param minimum: Minimum number of entries for each data item :return: None

search_attributes(callback: Callable[[Any], Any]) → Any[source]

This method will first call the callback with this container instance as the only argument. If a non-None result is returned, this this result is returned immediately. If not then it will then call the callback for each of the attributes that are contained in this container, stoping whenever the callback returns a non-None value.

search_domains(callback: Callable[[Any], None]) → None[source]

This method will walk all object under it calling the callback with a reference to that object. If the callback returns a non-None result, the recursive walk is stopped, and that value is returned.

walk_attributes(callback: Callable[[Any], None]) → None[source]

This method will first call the callback with this container instance as the only argument, and then it will call the callback for each of the attributes that are contained in this container.

configurationmodel.configdomain.get_metadata(config_item, key=None)[source]

Return a python object containing the contents of the json decoded metadata associated with a config item. If there is no metadata or the metadata is empty or the metadata of the requested key is empty, or the metadata is just “default” then return a python list ["default"]

Optionally a metadata key name can be provided to acess a top-level key. e.g. writers = get_attribute_metadata(attr, “writers”) on attr.attr_meta_data = ‘{“writers”:[“this”,”that”]}’ returns the python list [“this”, “that”]

3.4.1.3. Config Command Line Tool

This command line tool creates all the files for a chosen device that would normally be either pushed to that device or created locally in an output directory specified by the command line parameters.

By default, the tool will use the unmodified default device configuration, but this can optionally be modified by supplying a valid import database source. Initially only XML import with optional Kajiki template statements is supported.

example: -x my.xml

Properties can be defined on the command line to support passing text definitions to Kajiki and similar templating engines.

example: -p variant=soundbar colour=blue

class scripts.pyconfigcmd.Properties(option_strings, dest, nargs=None, const=None, default=None, type=None, choices=None, required=False, help=None, metavar=None)[source]

Argparse action to accept a readable file.

Raises:ArgumentTypeError
class scripts.pyconfigcmd.ReadableFile(option_strings, dest, nargs=None, const=None, default=None, type=None, choices=None, required=False, help=None, metavar=None)[source]

Argparse action to accept a readable file path.

Raises:ArgumentTypeError
class scripts.pyconfigcmd.WriteableDir(option_strings, dest, nargs=None, const=None, default=None, type=None, choices=None, required=False, help=None, metavar=None)[source]

Argparse action to accept a writeable directory.

scripts.pyconfigcmd.arg_parser() → None[source]

Parse command line arguments. Use –help to see usage at the command line to see help.

scripts.pyconfigcmd.main() → int[source]

Generates all the files that would normally be pushed to a device or created locally in the output directory specified on the command line. Also exports the database in supported export formats.

Returns:Success code