summaryrefslogtreecommitdiff
path: root/pecan/configuration.py
diff options
context:
space:
mode:
Diffstat (limited to 'pecan/configuration.py')
-rw-r--r--pecan/configuration.py254
1 files changed, 0 insertions, 254 deletions
diff --git a/pecan/configuration.py b/pecan/configuration.py
deleted file mode 100644
index 6260723..0000000
--- a/pecan/configuration.py
+++ /dev/null
@@ -1,254 +0,0 @@
-import re
-import inspect
-import os
-import sys
-
-import six
-
-if six.PY3:
- from importlib.machinery import SourceFileLoader
-else:
- import imp
-
-
-IDENTIFIER = re.compile(r'[a-z_](\w)*$', re.IGNORECASE)
-
-DEFAULT = {
- # Server Specific Configurations
- 'server': {
- 'port': '8080',
- 'host': '0.0.0.0'
- },
-
- # Pecan Application Configurations
- 'app': {
- 'root': None,
- 'modules': [],
- 'static_root': 'public',
- 'template_path': '',
- 'force_canonical': True
- }
-}
-
-
-class ConfigDict(dict):
- pass
-
-
-class Config(object):
- '''
- Base class for Pecan configurations.
-
- Create a Pecan configuration object from a dictionary or a
- filename.
-
- :param conf_dict: A python dictionary to use for the configuration.
- :param filename: A filename to use for the configuration.
- '''
-
- def __init__(self, conf_dict={}, filename=''):
-
- self.__values__ = {}
- self.__file__ = filename
- self.update(conf_dict)
-
- def empty(self):
- self.__values__ = {}
-
- def update(self, conf_dict):
- '''
- Updates this configuration with a dictionary.
-
- :param conf_dict: A python dictionary to update this configuration
- with.
- '''
-
- if isinstance(conf_dict, dict):
- iterator = six.iteritems(conf_dict)
- else:
- iterator = iter(conf_dict)
-
- for k, v in iterator:
- if not IDENTIFIER.match(k):
- raise ValueError('\'%s\' is not a valid indentifier' % k)
-
- cur_val = self.__values__.get(k)
-
- if isinstance(cur_val, Config):
- cur_val.update(conf_dict[k])
- else:
- self[k] = conf_dict[k]
-
- def get(self, attribute, default=None):
- try:
- return self[attribute]
- except KeyError:
- return default
-
- def __dictify__(self, obj, prefix):
- '''
- Private helper method for to_dict.
- '''
- for k, v in obj.copy().items():
- if prefix:
- del obj[k]
- k = "%s%s" % (prefix, k)
- if isinstance(v, Config):
- v = self.__dictify__(dict(v), prefix)
- obj[k] = v
- return obj
-
- def to_dict(self, prefix=None):
- '''
- Converts recursively the Config object into a valid dictionary.
-
- :param prefix: A string to optionally prefix all key elements in the
- returned dictonary.
- '''
-
- conf_obj = dict(self)
- return self.__dictify__(conf_obj, prefix)
-
- def __getattr__(self, name):
- try:
- return self.__values__[name]
- except KeyError:
- msg = "'pecan.conf' object has no attribute '%s'" % name
- raise AttributeError(msg)
-
- def __getitem__(self, key):
- return self.__values__[key]
-
- def __setitem__(self, key, value):
- if isinstance(value, dict) and not isinstance(value, ConfigDict):
- if value.get('__force_dict__'):
- del value['__force_dict__']
- self.__values__[key] = ConfigDict(value)
- else:
- self.__values__[key] = Config(value, filename=self.__file__)
- elif isinstance(value, six.string_types) and '%(confdir)s' in value:
- confdir = os.path.dirname(self.__file__) or os.getcwd()
- self.__values__[key] = value.replace('%(confdir)s', confdir)
- else:
- self.__values__[key] = value
-
- def __iter__(self):
- return six.iteritems(self.__values__)
-
- def __dir__(self):
- """
- When using dir() returns a list of the values in the config. Note:
- This function only works in Python2.6 or later.
- """
- return list(self.__values__.keys())
-
- def __repr__(self):
- return 'Config(%s)' % str(self.__values__)
-
-
-def conf_from_file(filepath):
- '''
- Creates a configuration dictionary from a file.
-
- :param filepath: The path to the file.
- '''
-
- abspath = os.path.abspath(os.path.expanduser(filepath))
- conf_dict = {}
- if not os.path.isfile(abspath):
- raise RuntimeError('`%s` is not a file.' % abspath)
-
- # First, make sure the code will actually compile (and has no SyntaxErrors)
- with open(abspath, 'rb') as f:
- compiled = compile(f.read(), abspath, 'exec')
-
- # Next, attempt to actually import the file as a module.
- # This provides more verbose import-related error reporting than exec()
- absname, _ = os.path.splitext(abspath)
- basepath, module_name = absname.rsplit(os.sep, 1)
- if six.PY3:
- SourceFileLoader(module_name, abspath).load_module(module_name)
- else:
- imp.load_module(
- module_name,
- *imp.find_module(module_name, [basepath])
- )
-
- # If we were able to import as a module, actually exec the compiled code
- exec(compiled, globals(), conf_dict)
- conf_dict['__file__'] = abspath
-
- return conf_from_dict(conf_dict)
-
-
-def get_conf_path_from_env():
- '''
- If the ``PECAN_CONFIG`` environment variable exists and it points to
- a valid path it will return that, otherwise it will raise
- a ``RuntimeError``.
- '''
- config_path = os.environ.get('PECAN_CONFIG')
- if not config_path:
- error = "PECAN_CONFIG is not set and " \
- "no config file was passed as an argument."
- elif not os.path.isfile(config_path):
- error = "PECAN_CONFIG was set to an invalid path: %s" % config_path
- else:
- return config_path
-
- raise RuntimeError(error)
-
-
-def conf_from_dict(conf_dict):
- '''
- Creates a configuration dictionary from a dictionary.
-
- :param conf_dict: The configuration dictionary.
- '''
- conf = Config(filename=conf_dict.get('__file__', ''))
-
- for k, v in six.iteritems(conf_dict):
- if k.startswith('__'):
- continue
- elif inspect.ismodule(v):
- continue
-
- conf[k] = v
- return conf
-
-
-def initconf():
- '''
- Initializes the default configuration and exposes it at
- ``pecan.configuration.conf``, which is also exposed at ``pecan.conf``.
- '''
- return conf_from_dict(DEFAULT)
-
-
-def set_config(config, overwrite=False):
- '''
- Updates the global configuration.
-
- :param config: Can be a dictionary containing configuration, or a string
- which represents a (relative) configuration filename.
- '''
-
- if config is None:
- config = get_conf_path_from_env()
-
- # must be after the fallback other a bad fallback will incorrectly clear
- if overwrite is True:
- _runtime_conf.empty()
-
- if isinstance(config, six.string_types):
- config = conf_from_file(config)
- _runtime_conf.update(config)
- if config.__file__:
- _runtime_conf.__file__ = config.__file__
- elif isinstance(config, dict):
- _runtime_conf.update(conf_from_dict(config))
- else:
- raise TypeError('%s is neither a dictionary or a string.' % config)
-
-
-_runtime_conf = initconf()