unified command line args, environment variables, .conf file settings.

Ben Finney bignose+hates-spam at benfinney.id.au
Fri May 2 23:29:23 EDT 2008


smitty1e <smitty1e at gmail.com> writes:

> Just a fun exercise to unify some of the major input methods for a
> script into a single dictionary.
> Here is the output, given a gr.conf file in the same directory with
> the contents stated below:
> 
> smitty at localhost ~/proj/mddl4/test $ ./inputs.py
> {'source_db': '/home/sweet/home.db'}
> smitty at localhost ~/proj/mddl4/test $ source_db="test_env" ./inputs.py
> {'source_db': 'test_env'}
> smitty at localhost ~/proj/mddl4/test $ ./inputs.py -f "test_cli"
> {'source_db': 'test_cli'}

A good start. However, you need to account for two conventions with
configuration of programs via environment variables:

* Environment variables that will be inherited by subprocesses are
  conventionally distinguished from variables that will not be
  inherited by using an UPPER_CASE name for variables (like process
  config variables) that will be inherited, and a lower_case name for
  variables (like local state variables) that will not be inherited.

* The process environment is a flat namespace, so config environment
  variables need to be named to reduce the risk of namespace collision
  with variables used by other programs. This is often done by
  prefixing the name with the name of the program or system that will
  consume it. e.g. The search path for Python imports is configured
  via an attribute named 'path', but in the environment by a variable
  named 'PYTHONPATH' (yes, I know that's not exactly equivalent, but
  it's a good example).

Neither of these distinctions need to be made in a program-specific
configuration file, so these conventions don't apply there and would
be inappropriate. So you then need to deal with a configuration
setting being named one way in the environment, and another way in the
configuration file and elsewhere in the program.

This is probably best done by a mapping specifically for the
environment variable names:

    config_env_names = {
        'source_db': 'GR_SOURCE_DB',
        }

and then referencing that dictionary when inspecting the environment:

    for key in config.keys():
        # ...
        environ_name = config_env_names[key]
        environ_value = os.environ.get(environ_name)
        if environ_value is not None:
            config[key] = environ_value
        #...

-- 
 \         "Pinky, are you pondering what I'm pondering?" "I think so, |
  `\     Brain, but how will we get a pair of Abe Vigoda's pants?"  -- |
_o__)                                            _Pinky and The Brain_ |
Ben Finney



More information about the Python-list mailing list