Arijit Panda
Arijit Panda

Reputation: 1665

how to create dynamic configuration file using python

I have a python script which is controlled by a config file called system.config .the structure of config file is like bellow with some default values.

[company]
companyname: XYZ

[profile]
name: ABC
joining: 1/1/2014

the code for config file is : config_parser_details.py

import ConfigParser
import sys

Config = ConfigParser.ConfigParser()
Config.read("system.config")
filename = "system.config"

def ConfigSectionMap(section):
  dict1 = {}
  options = Config.options(section)
  for option in options:    
    try:
      dict1[option] = Config.get(section, option)
      if dict1[option] == -1:
         DebugPrint("skip: %s" % option)
    except:
      print("exception on %s!" % option)
      dict1[option] = None
  return dict1

company = ConfigSectionMap("company")['companyname']
name = ConfigSectionMap("profile")['name']
joindate = ConfigSectionMap("profile")['joining']

now the code for my script is : test.py

import config_parser_details as p
import sys
import warnings
import os

company = p.company

name = p.name
date = p.joindate


print("%s\n" %company)
print("%s\n" %name)

output is

XYZ
ABC

now I want to give input in the config file through command line. like

python test.py --compname ="testing"

if any argument is missing in the command line than default value will be the input.

Upvotes: 1

Views: 8268

Answers (3)

lorenzog
lorenzog

Reputation: 3609

First of all, I'd move code into a main section so that you can import config_parser_details without executing code:

if __name__ == '__main__':
    main()

def main():
    Config = ConfigParser.ConfigParser()
    Config.read("system.config")
    filename = "system.config"

    company = ConfigSectionMap("company")['companyname']
    name = ConfigSectionMap("profile")['name']
    joindate = ConfigSectionMap("profile")['joining']

Secondly, I'd use STB land's suggestion of parsing the command line with argparse, something like:

def main():
    # do the parsing thing first, then:
    filename = args.filename
    do_stuff(filename)

This way you can neatly use python's own unit test framework or nosetests to write test file that don't require you to manually specify parameters:

def test_basic():
    # create a temporary file with tempfile.NamedTemporaryFile
    tmpfile = tempfile.NamedTemporaryFile()
    # add test data to tmpfile
    do_stuff(tmpfile)

    # check the output
    assert .... 

This comes with the added benefit of not having global variables, which will complicate your life later.

Upvotes: 0

Stéphane B.
Stéphane B.

Reputation: 3290

You could use argparse library to parse command line arguments.

So your test.py file looks like below :

import config_parser_details as p
import sys
import warnings
import os
import argparse

commandLineArgumentParser = argparse.ArgumentParser()
commandLineArgumentParser.add_argument("-c", "--compname", help="Company name", default=p.company)
commandLineArguments = commandLineArgumentParser.parse_args()

company = commandLineArguments.compname

name = p.name
date = p.joindate

print("%s\n" %company)
print("%s\n" %name)

Upvotes: 1

manicphase
manicphase

Reputation: 618

I'd advise looking into a tool like docopt.

For a quick fix though, you can try doing this

def ConfigSectionMap(section):
  options = Config.options(section)

  arg_dict = {}
  for command_line_argument in sys.argv[1:]:
    arg = command_line_argument.split("=")
    arg_dict[arg[0][2:]] = arg[1]

  for key in arg_dict:
    options[key] = arg_dict[key]

  return options

This will load up all the default option. Any options put on the command line will override or add to the options dict.

Upvotes: 1

Related Questions