DEV Community

Ashish Mishra
Ashish Mishra

Posted on • Originally published at arglee.Medium on

Python Dynamic Configuration — Python-Trick

Python Dynamic Configuration — Python-Trick

In this blog, we will discuss one easy-to-use python trick that could be very handy for a quick program or repository you are creating for your individual project or for your organization.


Photo by Jantine Doornbos on Unsplash

I am sure you are already aware of the importance of configuration files in any programming language. Managing configuration files is the most important part of any software development process.

In order to understand this, we will first discuss the traditional approach and then we will discuss how a small class in python can help you avoid multiple iterations in your config file.

Traditional Approach

In order to make both approaches more intelligible, we will take an example code and will implement both approaches to see the impact of the trick.

Let’s create a folder configuration and add these 2 files inside it.

settings.ini file looks something like this:

[RUN]
num_cores = 2
num_files = -1
Enter fullscreen mode Exit fullscreen mode

Now to parse the configuration, we use another file. let’s say config.py

import os
import configparser

parser = configparser.ConfigParser()
parser.read_file(open(os.path.join(os.path.dirname(os.path.abspath( __file__ )), "settings.ini")))

NUM_CORES = parser.get('RUN','num_cores')

print ("Number of cores available : ", parser.get('RUN','num_cores'))
Enter fullscreen mode Exit fullscreen mode

The output of the above script will look something like this:

➜ configuration python config.py
Number of cores available : 2
Enter fullscreen mode Exit fullscreen mode

This is straightforward and easy, now every time, we want to add a new config, there is an easy way just to add a new variable and use that inside code. so, let’s consider now we also want the value of NUM_FILES in the code, then new code will look something like this:

import os
import configparser

parser = configparser.ConfigParser()
parser.read_file(open(os.path.join(os.path.dirname(os.path.abspath( __file__ )), "settings.ini")))

NUM_CORES = parser.get('RUN','num_cores')
NUM_FILES = parser.get('RUN','num_files')

print ("Number of cores available : ", parser.get('RUN','num_cores'))
print ("Number of cores available : ", parser.get('RUN','num_files'))
Enter fullscreen mode Exit fullscreen mode

and now the NUM_FILES variable can be used across your project to get the value of this variable.

But how many times has this happened to you that you have to add these same lines every time you want to add a new variable, you would agree that this could be painful sometimes and it could halt your train of thought.

Dynamic configuration:

What if I tell you there is an easy way out and you can initialize the whole .ini file dynamically and there is no need to parse every variable explicitly.

Now, in order to do that, I have added a new file dynamic_config_parser.py and its content will look something like this:

import configparser

class DynamicConfig:
    def __init__ (self, conf):
        if not isinstance(conf, dict):
            raise TypeError(f'dict expected, found {type(conf). __name__ }')

        self._raw = conf
        for key, value in self._raw.items():
            setattr(self, key, value)

class DynamicConfigInit:
    """
    This class is used to dynamically load static variables from the settings.ini file. Any va
    variable declared in the settings.ini can be parsed directly.
    """
    def __init__ (self, conf):
        if not isinstance(conf, configparser.ConfigParser):
            raise TypeError(f'ConfigParser expected, found {type(conf). __name__ }')

        self._raw = conf
        for key, value in self._raw.items():
            setattr(self, key, DynamicConfig(dict(value.items())))
Enter fullscreen mode Exit fullscreen mode

and now your config.py will look something like this:

import os
import configparser
from dynamic_config_parser import DynamicConfigInit

parser = configparser.ConfigParser()
parser.read_file(open(os.path.join(os.path.dirname(os.path.abspath( __file__ )), "settings.ini")))
STATIC_CONFIG = DynamicConfigInit(parser)

print("Number of cores from dynamic config: ", STATIC_CONFIG.RUN.num_cores)
Enter fullscreen mode Exit fullscreen mode

Viola! That’s it. We are done.

As you see, now there is no requirement to add every variable every time into config.py, and dynamic config initialization is handling this for you and you can save a long repetitive file with a huge configuration.

Originally published at https://singlequote.blog on April 4, 2023.

Top comments (0)