2

When I try to get the values using ConfigParser,

  • I am not able to get certain values from environment variables in my .ini file

  • Interpolating variable names are printing variables as it is without value substitution.

Below is my code,

config_parse.py:

import os
import configparser

myConf = configparser.ConfigParser(interpolation=configparser.ExtendedInterpolation())
myConf.read('config_data.ini')

print( myConf.get('server_details', 'hostName', vars=os.environ))
print( myConf.get('server_details', 'userName', vars=os.environ))
print( myConf.get('log_path', 'mntPath', vars=os.environ))
exit(0)

config_data.ini:

[server_details]
  hostName: %(HOSTNAME)
  ; Below value are not getting substituted from environment variable
  userName: %(USER)
  password: passw0rd

[log_path]
  instance: %(SERVER_INSTANCE)
  mntPath: /net/server1/mnt/data0
  ; server_details:hostname and instance values are not getting substituted
  testbedMntPath: ${mntPath}/${server_details:userName}/my_logs/${server_details:hostName}${instance}

I am getting the following output,

$] python config_parse.py

server1

%(USER)

/net/server1/mnt/data0/%(USER)/my_logs/%(HOSTNAME)%(SERVER_INSTANCE)

$]

Community
  • 1
  • 1
Ashwin
  • 993
  • 1
  • 16
  • 41

1 Answers1

2

You're using ExtendedInterpolation, which uses ${section:option} syntax.

The reason why you get server1 for myConf.get('server_details', 'hostName', vars=os.environ) isn't because hostName = %(HOSTNAME) is interpolated, but because HOSTNAME from vars takes precedence.

It's easier to see with an example:

>>> myConf.get('server_details', 'foo', vars={'FOO': 'BAR'})
'BAR'

If vars contains an entry for FOO, the get call for foo (case insensitive) will return its value, the value from the config file is actually ignored.

So that means that for hostName you acutally get the value of the HOSTNAME environment variable. userName does not exist in os.environ, so you get the value from the config file: %(USER).

So if you use ExtendedInterpolations, use ${...} style, if you use BasicInterpolation use %(...)s style. You can't mix both. And if you blindly pass vars=os.environ, be aware that the envionment variables will override all options in all sections with the same name. Depending on the context the application runs in, that may be relevant for security.

mata
  • 67,110
  • 10
  • 163
  • 162
  • But if I print os.environ values, it is having `USER` variable defined properly. Why am I not able to see that value in my `[server_details]` section ? – Ashwin Jun 09 '17 at 05:13
  • 1
    Because with extended interpolation `%(HOME)` isn't special, it's just a string (and with basic interplolation it should be `%(HOME)s`). It doesn't matter that os.environ has a key `USER`, it's not used. If the environment variable `USERNAME` you would get that instead bekause lookup is always performed in `vars` first. None of the `%(...)` options use anything from the environment in your case. You use extended interpolation, so change it to `${USER}`, then it should work. – mata Jun 09 '17 at 08:01