.. _CONFIG:
Configuration
#############
Module :mod:`~pyTooling.Configuration` provides an abstract configuration reader.
.. #contents:: Table of Contents
:local:
:depth: 1
It supports any configuration file syntax, which provides:
* scalar elements (integer, string, ...),
* sequences (ordered lists), and
* dictionaries (key-value-pairs).
The abstracted data model is based on a common :class:`~pyTooling.Configuration.Node` class, which is derived to a
:class:`~pyTooling.Configuration.Sequence`, :class:`~pyTooling.Configuration.Dictionary` and
:class:`~pyTooling.Configuration.Configuration` class.
.. rubric:: Inheritance diagram:
.. inheritance-diagram:: pyTooling.Configuration
:parts: 1
Dictionary
**********
A :class:`~pyTooling.Configuration.Dictionary` represents key-value-pairs of information.
.. tab-set::
.. tab-item:: JSON
:sync: JSON
.. code-block:: JSON
// one-liner style
{"key1": "item1", "key2": "item2", "key3": "item3"}
// multi-line style
{
"key1": "item1",
"key2": "item2",
"key3": "item3"
}
.. tab-item:: TOML
:sync: TOML
.. code-block:: TOML
# one-liner style
section_1 = {key1 = "item1", key2 = "item2", key3 = "item3"}
# section style
[section_2]
key1 = "item1"
key2 = "item2"
key3 = "item3"
.. tab-item:: YAML
:sync: YAML
.. code-block:: YAML
# one-liner style
{key1: item1, key2: item2, key3: item3}
# multi-line style
key1: item1
key2: item2
key3: item3
.. tab-item:: XML
:sync: XML
.. code-block:: XML
- item1
- item2
- item3
.. todo:: CONFIG:: Needs documentation for Dictionary
Sequences
*********
A :class:`~pyTooling.Configuration.Sequence` represents ordered information items.
.. tab-set::
.. tab-item:: JSON
:sync: JSON
.. code-block:: JSON
// one-liner style
["item1", "item2", "item3"]
// multi-line style
[
"item1",
"item2",
"item3"
]
.. tab-item:: TOML
:sync: TOML
.. code-block:: TOML
# one-liner style
section_1 = ["item1", "item2", "item3"]
# multi-line style
section_2 = [
"item1",
"item2",
"item3"
]
.. tab-item:: YAML
:sync: YAML
.. code-block:: YAML
# one-liner style
[item1, item2, item3]
# multi-line style
- item1
- item2
- item3
.. tab-item:: XML
:sync: XML
.. code-block:: XML
- item1
- item2
- item3
.. todo:: CONFIG:: Needs documentation for Sequences
Configuration
*************
A :class:`~pyTooling.Configuration.Configuration` represents the whole configuration (file) made of sequences,
dictionaries and scalar information items.
.. tab-set::
.. tab-item:: JSON
:sync: JSON
.. code-block:: JSON
{ "version": "1.0",
"settings": {
"key1": "item1",
"key2": "item2"
},
"files": [
"path/to/file1.ext",
"path/to/file2.ext",
"path/to/file3.ext"
]
}
.. tab-item:: TOML
:sync: TOML
.. attention:: Not yet implemented.
.. code-block:: TOML
version = "1.0"
[settings]
key1 = "item1"
key2 = "item2"
files = [
"path/to/file1.ext",
"path/to/file2.ext",
"path/to/file3.ext"
]
.. tab-item:: YAML
:sync: YAML
.. code-block:: YAML
version: "1.0"
settings:
key1: item1
key2: item2
files:
- path/to/file1.ext
- path/to/file2.ext
- path/to/file3.ext
.. tab-item:: XML
:sync: XML
.. attention:: Not yet implemented.
.. code-block:: XML
item1
item2
path/to/file1.ext
path/to/file2.ext
path/to/file3.ext
.. todo:: CONFIG:: Needs documentation for Configuration
Data Model
**********
.. todo:: CONFIG:: Needs documentation for Data Model
.. mermaid::
flowchart TD
Configuration --> Dictionary
Configuration --> Sequence
Dictionary --> Dictionary
Sequence --> Sequence
Dictionary --> Sequence
Sequence --> Dictionary
Creating a Concrete Implementation
**********************************
Follow these steps to derive a concrete implementation of the abstract configuration data model.
1. Import classes from abstract data model
.. code-block:: python
from . import (
Node as Abstract_Node,
Dictionary as Abstract_Dict,
Sequence as Abstract_Seq,
Configuration as Abstract_Configuration,
KeyT, NodeT, ValueT
)
2. Derive a node, which might hold references to nodes in the source file's parser for later usage.
.. code-block:: python
@export
class Node(Abstract_Node):
_configNode: Union[CommentedMap, CommentedSeq]
# further local fields
def __init__(self, root: "Configuration", parent: NodeT, key: KeyT, configNode: Union[CommentedMap, CommentedSeq]) -> None:
Abstract_Node.__init__(self, root, parent)
self._configNode = configNode
# Implement mandatory methods and properties
3. Derive a dictionary class:
.. code-block:: python
@export
class Dictionary(Node, Abstract_Dict):
def __init__(self, root: "Configuration", parent: NodeT, key: KeyT, configNode: CommentedMap) -> None:
Node.__init__(self, root, parent, key, configNode)
# Implement mandatory methods and properties
4. Derive a sequence class:
.. code-block:: python
@export
class Sequence(Node, Abstract_Seq):
def __init__(self, root: "Configuration", parent: NodeT, key: KeyT, configNode: CommentedSeq) -> None:
Node.__init__(self, root, parent, key, configNode)
# Implement mandatory methods and properties
5. Set new dictionary and sequence classes as types in the abstract node class.
.. code-block:: python
setattr(Abstract_Node, "DICT_TYPE", Dictionary)
setattr(Abstract_Node, "SEQ_TYPE", Sequence)
6. Derive a configuration class:
.. code-block:: python
@export
class Configuration(Dictionary, Abstract_Configuration):
def __init__(self, configFile: Path) -> None:
with configFile.open() as file:
self._config = ...
Dictionary.__init__(self, self, self, None, self._config)
# Implement mandatory methods and properties