bigchaindb/bigchaindb/config_utils.py

103 lines
2.9 KiB
Python

"""Utils to configure Bigchain.
By calling `file_config`, the global configuration (stored in
`bigchain.config`) will be updated with the values contained in the
configuration file.
Note that there is a precedence in reading configuration values:
- [not yet] command line;
- local config file;
- environment vars;
- default config file (contained in `bigchain.__init__`).
"""
import os
import copy
import json
import logging
import collections
import bigchaindb
logger = logging.getLogger(__name__)
CONFIG_DEFAULT_PATH = os.environ.setdefault(
'BIGCHAINDB_CONFIG_PATH',
os.path.join(os.path.expanduser('~'), '.bigchaindb'),
)
# Thanks Alex <3
# http://stackoverflow.com/a/3233356/597097
def update(d, u):
"""Recursively update a mapping."""
for k, v in u.items():
if isinstance(v, collections.Mapping):
r = update(d.get(k, {}), v)
d[k] = r
else:
d[k] = u[k]
return d
def file_config(filename=None):
"""Read a configuration file and merge it with the default configuration.
Args:
filename (str): the JSON file with the configuration. Defaults to ``None``.
If ``None``, the HOME of the current user and the string ``.bigchaindb`` will be used.
Note:
The function merges the values in ``filename`` with the **default configuration**,
so any update made to ``bigchaindb.config`` will be lost.
"""
if not filename:
filename = CONFIG_DEFAULT_PATH
with open(filename) as f:
newconfig = json.load(f)
dict_config(newconfig)
logger.info('Configuration loaded from `{}`'.format(filename))
def dict_config(newconfig):
"""Merge the provided configuration with the default one.
Args:
newconfig (dict): a dictionary with the configuration to load.
Note:
The function merges ``newconfig`` with the **default configuration**, so any
update made to ``bigchaindb.config`` will be lost.
"""
bigchaindb.config = copy.deepcopy(bigchaindb._config)
update(bigchaindb.config, newconfig)
bigchaindb.config['CONFIGURED'] = True
def write_config(newconfig, filename=None):
"""Write the provided configuration to a specific location.
Args:
newconfig (dict): a dictionary with the configuration to load.
filename (str): the name of the file that will store the new configuration. Defaults to ``None``.
If ``None``, the HOME of the current user and the string ``.bigchaindb`` will be used.
"""
if not filename:
filename = CONFIG_DEFAULT_PATH
with open(filename, 'w') as f:
json.dump(newconfig, f)
def autoconfigure():
"""Run ``file_config`` if the module has not been initialized.
"""
if bigchaindb.config.get('CONFIGURED'):
return
try:
file_config()
except FileNotFoundError:
logger.warning('Cannot find your config file. Run `bigchaindb configure` to create one')