class documentation

This class handles a program ini file.

It keeps track of changed parameter values during program execution, if needed. Environment variables and secrets are expanded. Parameter values are accessed using dot notation.

If INI file validation fails during program startup, the program stops.

If an INI file change is detected when the program is running and the validation fails, the content is rejected and the old file content is restored, whilst the program keeps running.

Note

You should be aware of the consequences of changing values while the program is running. For example, changing path parameters is mostly a bad idea since the input path of this program might be the output path of another program. So changing file paths usually require a coordinated effort that results in changes to several INI files, while the programs are offline.

This goes for connection parameters as well. The program must have been programmed to handle disconnecting from the current connection and create a new connection using the new parameters, otherwise the change will have no effect.

Expanded parameter ini file parameter syntax:
  • @{<secrets-name>}
  • &{<environment-variable-name>}
  • ${<extended-interpolation-reference>}
There are three methods that are designed to be overridden when needed:
  • _add_default_parameters()
  • _add_platform_parameters()
  • _add_section_parameters()

That can be useful when you are referencing external values (in relation to the INI file content) in the ini file.

The way to do that is to use vars like this:

# In a *_ini_core.py file
class AsyncDeployIni(AsyncIniFileParser):
    def __init__(self, name: str, dest_server: str):
        self.var_params = {'server': dest_server}

    def _add_platform_parameters(self) -> dict:
        # Add external parameter(s) to the parameter interpolation.
        return dict(self.items(PLATFORM, vars=self.var_params))

And the INI file can look something like this:

[DEFAULT]
passwd: @{environment_prod_pwd}

[win32]
root_path: /export
local_path: ${root_path}/Prod/Pgm
dest_path: //${server}/Prod/Pgm
Method __getattr__ Dynamically return the value for the specified parameter.
Method __init__ Initialize IniFileHandler class attributes.
Async Method read_ini_file Read the ini file and parse existing parameters.
Async Method start Start the used resources in a controlled way.
Async Method stop Stop the used resources in a controlled way.
Async Method validate_ini_file Read ini file, check existence of required parameters and validate their types.
Method validate_ini_file_parameters Extract and validate ini file parameters.
Instance Variable default_params Default parameters defined.
Instance Variable default_paths Default paths defined.
Instance Variable error Validation errors.
Instance Variable file_timestamp Timestamp for last ini file modification.
Instance Variable filename Name if ini file.
Instance Variable orig_file_copied Is original ini file copied status.
Instance Variable status Parameter change status when supervision is active.
Instance Variable supervise_change Supervise parameter change when the program is running.
Instance Variable valid_params Validated INI file parameters.
Property file_is_changed Return INI file change status since the last check.
Method _add_default_parameters Return DEFAULT parameters.
Method _add_platform_parameters Return DEFAULT and platform parameters.
Method _add_section_parameters Return specified section parameters.
Async Method _handle_error_severity Handle validation error severity.
Method _handle_status Update parameter change status.
Async Method _restore_orig_file Restore original ini file since validation failed.
Method _update_change_status Update parameter supervision change status.
Async Method _validate_params Validate parameters against a pydantic validation model.
def __getattr__(self, name: str) -> Any: (source)

Dynamically return the value for the specified parameter.

Parameters
name:strParameter name.
Returns
AnyParameter value.
def __init__(self, name: Path, default_paths: list, default_params: list, supervise_change: bool = True): (source)

Initialize IniFileHandler class attributes.

Parameters
name:PathName of ini file.
default_paths:listDefault paths.
default_params:listDefault parameters.
supervise_change:boolSupervise parameter change (default is True).
async def read_ini_file(self): (source)

Read the ini file and parse existing parameters.

Expand environment variables and secrets before parsing starts.

async def start(self): (source)

Start the used resources in a controlled way.

async def stop(self): (source)

Stop the used resources in a controlled way.

async def validate_ini_file(self, validation_model: Callable, sections: Optional[list] = None, read_ini: bool = True): (source)

Read ini file, check existence of required parameters and validate their types.

Update parameter change status when the value is changed, if required.

Parameters
validation_model:CallablePydantic BaseModel.
sections:Optional[list]List of used section names (except DEFAULT).
read_ini:boolRead ini file (default is True).
@abstractmethod
def validate_ini_file_parameters(self): (source)

Extract and validate ini file parameters.

Abstract method that needs to be overridden.

default_params: list = (source)

Default parameters defined.

default_paths: list = (source)

Default paths defined.

Validation errors.

file_timestamp: float = (source)

Timestamp for last ini file modification.

filename: str = (source)

Name if ini file.

orig_file_copied: bool = (source)

Is original ini file copied status.

Parameter change status when supervision is active.

supervise_change: bool = (source)

Supervise parameter change when the program is running.

valid_params: pydantic.BaseModel = (source)

Validated INI file parameters.

@property
file_is_changed: bool = (source)

Return INI file change status since the last check.

def _add_default_parameters(self) -> dict: (source)

Return DEFAULT parameters.

This method exists, so it can be overridden in derived classes when needed (for example, when using vars).

Returns
dictDEFAULT parameters.
def _add_platform_parameters(self) -> dict: (source)

Return DEFAULT and platform parameters.

This method exists, so it can be overridden in derived classes when needed (for example, when using vars).

Returns
dictDEFAULT and platform parameters.
def _add_section_parameters(self, section: str) -> dict: (source)

Return specified section parameters.

This method exists, so it can be overridden in derived classes when needed (for example, when using vars).

Parameters
section:strSection name.
Returns
dictSection parameters.
async def _handle_error_severity(self): (source)

Handle validation error severity.

When you get a validation error during program startup, there's no valid original file that you can restore, so the consequence is to trigger a fatal stop by raising a IniValidationError exception.

When the program is running (after starting with a valid INI file), and a faulty INI file change happens, we can restore the valid original INI file and keep the program running after reporting the error by raising a RuntimeError exception.

Raises
IniValidationErrorWhen invalid ini file detected during startup.
RuntimeErrorWhen invalid ini file detected during running program.
def _handle_status(self, params: dict): (source)

Update parameter change status.

params structure:
{'<param name>':[<value>, False], ...}
Parameters
params:dictAll ini parameters
async def _restore_orig_file(self): (source)

Restore original ini file since validation failed.

Save faulty file with a .err extension.

def _update_change_status(self, sections: Optional[list] = None) -> dict: (source)

Update parameter supervision change status.

Parameters
sections:Optional[list]List of section names.
Returns
dictUndocumented
async def _validate_params(self, validation_model: Callable, sections: list): (source)

Validate parameters against a pydantic validation model.

Parameters
validation_model:CallablePydantic BaseModel.
sections:listList of used section names (except DEFAULT).