Introduction¶
pyconfigreader not only makes it easier to work with ini files but also to migrate between JSON and the OS environment. It is possible to transfer variables from one to the other.
The following code examples assume the following sample content in the settings.ini:
[main]
reader = configreader
name = pyconfigreader
language = python
versions = [2.7, 3.4, 3.5, 3.6]
[DATA]
language = English
development = None
path = /home/ubuntu/
user = Ubuntu
groups = 1000
Getting Values¶
ConfigReader
creates a default main section from which key-value pairs are read if no section is specified.
>>> from pyconfigreader import ConfigReader
>>> config = ConfigReader(filename='config.ini')
>>> name = config.get('name')
>>> versions = config.get('versions')
>>> agency = config.get('agency') # agency is None, it doesn't exist
>>> name
'pyconfigreader'
>>> versions
[2.7, 3.4, 3.5, 3.6]
>>> agency
>>> config.sections # Get a list of sections
['main', 'DATA']
To get the value of a key in a different section, use the section
parameter
>>> config.get('groups', section='DATA')
1000
>>> config.get('language', section='DATA')
'English'
By default, ConfigReader
tries to evaluate the values into Python literals
(int, None, list, etc..). In the example above, groups from the DATA section has been
evaluated into an integer. To get a string, set the parameter evaluate
to False.
>>> config.get('groups', section='DATA', evaluate=False)
'1000'
If a key does not exist, ConfigReader
will raise MissingOptionError
>>> config.get('last_name')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/path/to/pyconfigreader/pyconfigreader/reader.py", line 336, in get
raise MissingOptionError(key, section)
pyconfigreader.exceptions.MissingOptionError: No option 'last_name' in section: 'main'
>>>
If, instead, you prefer to get a specific value if none exists, use default
>>> config.get('last_name', default='Some Name')
'Some Name'
From the Python console, it is possible to get a preview of the contents in the
settings file. show()
previews the contents and also
returns an OrderedDict of all the data.
>>> config.show()
-------------------settings.ini-------------------
main
reader: configreader
name: pyconfigreader
language: python
version: [2.7, 3.4, 3.5, 3.6]
DATA
language: English
development: None
path: /home/ubuntu/
user: Ubuntu
groups: 1000
-----------------------end------------------------
OrderedDict([('main', OrderedDict([('reader', 'configreader'), ('name', 'pyconfigreader'), ('language', 'python'), ('version', [2.7, 3.4, 3.5, 3.6])])), ('DATA', OrderedDict([('language', 'English'), ('development', None), ('path', '/home/ubuntu/'), ('user', 'Ubuntu'), ('groups', 1000)]))])
To hide the preview, set output
to False
>>> config.show(output=False)
OrderedDict([('main', OrderedDict([('reader', 'configreader'), ('name', 'pyconfigreader'), ('language', 'python'), ('version', [2.7, 3.4, 3.5, 3.6])])), ('DATA', OrderedDict([('language', 'English'), ('development', None), ('path', '/home/ubuntu/'), ('user', 'Ubuntu'), ('groups', 1000)]))])
Setting Values¶
Setting values is done by passing a key and value to set()
. This
saves the value to section main unless section
is specified. Unlike Python’s ConfigParser order of section then key then value, pyconfigreader
uses the key then value then section order.
>>> config.set('key', 'value')
>>> config.set('version', '2') # Saved to section `main`
>>> config.set('user', 'root', section='DATA') # Updates user in section DATA
If a section does not exist, it is created on-the-fly and the key-value pair is written to it.
>>> config.set('key', 'value', section='Section')
>>> name = config.get('name')
As at the moment, the changes are in-memory. To write these changes to the file on the disk close the ConfigReader
instance with save
as True or call save()
which does not close the ConfigReader
instance.
>>> config.close(save=True) # Save on close
>>> # Or explicitly call
>>> # config.save()
>>> # then later, call
>>> # config.close()
In any case you want the changes to be written directly to the file on disk upon setting a value, then set the parameter commit
to True
>>> config.set('name', None, section='DATA', commit=True)
In order for ConfigReader
to be used, the settings.ini file does not have to pre-exist. If the file cannot be found then a new file will be created in the specified path
>>> config = ConfigReader()
>>> config.set('tests', 'unit')
>>> config.set('runner', 'default')
>>> config.set('count', 1, section='RUNNER')
>>> config.close(save=True)
To set many values at once, it is more convenient to use set_many()
>>> config = ConfigReader()
>>> data = {'population': 'people', 'sample': True, 'count': 20}
>>> config.set_many(data, section='geography')
>>> config.close(save=True)
Removing Keys¶
Keys can be removed permanently by calling remove_key()
>>> from pyconfigreader import ConfigReader
>>> config = ConfigReader(filename='config.ini')
>>> config.remove_key('reader') # the reader option is always set by default
>>> # or config.remove_option('reader')
>>> config.set('name', 'first', section='Details')
>>> config.remove_key('name', section='Details')
>>> config.close(save=True)
remove_key()
is aliased by remove_option()
taking the same arguments.
Sections¶
You can derive all keys and their values from sections using get_items()
. This
returns an OrderedDict.
>>> from pyconfigreader import ConfigReader
>>> config = ConfigReader(filename='config.ini')
>>> config.set('name', 'first', section='Details')
>>> config.get_items('Details')
OrderedDict([('name', 'first')])
>>> config.close() # Or config.close(save=True)
Section are created on-the-fly when keys and values are set.
>>> from pyconfigreader import ConfigReader
>>> config = ConfigReader(filename='config.ini')
>>> config.set('name', 'first', section='Details') # Save key `name` with value `first` in section `Details`
>>> config.close()
Sections can also be explicitly remove by calling remove_section()
>>> from pyconfigreader import ConfigReader
>>> config = ConfigReader(filename='config.ini')
>>> config.set('name', 'first', section='Details') # Creates section `Details`
>>> config.remove_section('Details') # Removes section `Details` plus all the keys and values
>>> config.close()
Environment Variables¶
Get Environment Variables¶
pyconfigreader makes it possible to load most environment variables into
the settings.ini. To achieve this, use load_env()
>>> from pyconfigreader import ConfigReader
>>> config = ConfigReader('settings.ini')
>>> config.load_env()
Dump to Environment¶
With pyconfigreader, it is easy to pass values to the environment.
>>> import os
>>> from pyconfigreader import ConfigReader
>>> config = ConfigReader(filename='config.ini')
>>> config.set('name', 'first', section='Details')
>>> config.to_env()
>>> os.environ['DETAILS_NAME']
'first'
>>> os.environ['MAIN_READER']
'configreader'
By default, ConfigReader
prepends the key with the section name
and then transforms to uppercase before dumping to the environment. For instance,
in the above example, name in section Details generated the environment key
DETAILS_NAME
. If you do not prefer this behaviour and want the key to be saved
as is then set prepend
to False.
>>> config.to_env(prepend=False)
Alternatively, you can pass your instance of an environment to which the key-value pairs will be dumped.
>>> environment = os.environ.copy()
>>> config.to_env(environment=environment)
JSON Files¶
Load JSON Files¶
pyconfigreader makes it convenient to load configuration from JSON files.
This can be done by calling load_json()
>>> from pyconfigreader import ConfigReader
>>> config = ConfigReader(filename='config.ini')
>>> config.load_json('config.json') # Load from file config.json
As always, a full path to the JSON file is better than just a file name.
By default, load_json()
loads the JSON configuration
to the main section. It is possible to set the JSON data to be dumped to a
different section - the parameter section
makes this possible.
>>> from pyconfigreader import ConfigReader
>>> with ConfigReader(filename='config.ini') as config:
... config.load_json('config.json', section='JSONDATA')
If you prefer some values to be loaded to a different
section in the settings.ini then use the identifier
parameter. For example,
with identifier
as @ and the following JSON configuration:
'@counters': {
'start': {
'name': 'scrollers',
'count': 15
},
'end': {
'name': 'keepers',
'count': 5
}
}
One should expect a section named counters
that looks like:
[counters]
start = {'name': 'scrollers', 'count': 15}
end = {'name': 'keepers', 'count': 5}
load_json()
looks for first-level keys which are
prefixed with the identifier
and turns them into section names with their values
being assigned to the same section.
The JSON file encoding can be set using the encoding
parameter.
Dump JSON¶
The settings.ini configuration can be dumped as JSON by calling to_json()
.
>>> from pyconfigreader import ConfigReader
>>> config = ConfigReader(filename='config.ini')
>>> json_dump = config.to_json()
To dump the data to a JSON file, pass an open writable file to to_json()
.
>>> from pyconfigreader import ConfigReader
>>> config = ConfigReader(filename='config.ini')
>>> with open('config.json', 'w') as f:
... config.to_json(f)
Essentially, any file-like object can have the JSON data dumped into it.
>>> from io import StringIO
>>> s_io = StringIO()
>>> with ConfigReader('data.ini') as config:
... config.to_json(s_io)