103 lines
2.9 KiB
Python
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')
|
|
|