pythonconfigurationconfig

Python - How to change parameters at run time using of config file


Can someone tell what is the best way to change parameters from a config file while script is running?.. I need to be able to change those parameters while script is running...

If you use the usual way using an .ini, yaml, toml, etc... file, the configuration is loaded at the beginning when the script is first executed and if you change those parameters while the script is already running the parameters do not get "loaded"


Solution

  • You can write a config parser to load config from yaml, toml etc. and store it in memory as a singleton object and add a handy method to it to reload values. Then in any function whenever you want fresh values to be available just call the reload method.

    Here's an example configurator.py:

    # Filename: configurator.py
    
    import typing as t
    
    import os
    import yaml
    from yaml.parser import ParserError
    
    
    class ConfigError(Exception):
        """A Configuration error"""
        pass
    
    
    class Configurator:
        """A simple configuration loader class"""
    
        def __init__(self, cfg_file_path):
            self.cfg = self.load_yaml_config(cfg_file_path)
            self.cfg_file_path = cfg_file_path
    
        def reload(self):
            """Reloads configuration from existing config file"""
            del self.cfg
            self.cfg = self.load_yaml_config(self.cfg_file_path)
    
        def load_yaml_config(self, cfg: t.Optional[str] = None):
            """Loads configuration from a yaml file
    
            Args:
                cfg: Path to config file
            """
    
            # If no cfg file is provided then proceed to load
            # from environment variable.
            if not cfg:
                cfg = os.getenv("CONFIG_FILE")
    
            if not cfg:
                raise ConfigError("CONFIG_FILE env is not set")
    
            # Test if an absolute path has been given
            if not os.path.exists(cfg):
                raise ConfigError("Couldn't load config file")
    
            # Load config
            with open(cfg, "r") as f:
                try:
                    config = yaml.safe_load(f)
                except ParserError as err:
                    raise ConfigError(f"Couldn't load configuration - {err}")
    
            return config
    
    

    And then use it follows:

    # Filename: hello.py
    
    from configurator import Configurator
    
    def hello():
        config = Configurator('default_cfg.yaml')
    
        print(config.cfg.get('name', 'John'))
    
        # Now go ahead and change the name in the yaml file
        config.reload()
    
        # print(config.cfg.get('name', 'Jane'))
    
    

    You can have config = Configurator('default_cfg.yaml') declared at a global level and then import the instance everywhere.