123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187 |
- import imp
- import os
- import errno
- import sys
- string_types = (str,)
- def get_config():
- if get_config.instance is None:
- get_config.instance = Config(os.getcwd())
- return get_config.instance
- get_config.instance = None
- ## Stolen from flask.config
- class Config(dict):
- """Works exactly like a dict but provides ways to fill it from files
- or special dictionaries. There are two common patterns to populate the
- config.
- Either you can fill the config from a config file::
- app.config.from_pyfile('yourconfig.cfg')
- Or alternatively you can define the configuration options in the
- module that calls :meth:`from_object` or provide an import path to
- a module that should be loaded. It is also possible to tell it to
- use the same module and with that provide the configuration values
- just before the call::
- DEBUG = True
- SECRET_KEY = 'development key'
- app.config.from_object(__name__)
- In both cases (loading from any Python file or loading from modules),
- only uppercase keys are added to the config. This makes it possible to use
- lowercase values in the config file for temporary values that are not added
- to the config or to define the config keys in the same file that implements
- the application.
- Probably the most interesting way to load configurations is from an
- environment variable pointing to a file::
- app.config.from_envvar('YOURAPPLICATION_SETTINGS')
- In this case before launching the application you have to set this
- environment variable to the file you want to use. On Linux and OS X
- use the export statement::
- export YOURAPPLICATION_SETTINGS='/path/to/config/file'
- On windows use `set` instead.
- :param root_path: path to which files are read relative from. When the
- config object is created by the application, this is
- the application's :attr:`~flask.Flask.root_path`.
- :param defaults: an optional dictionary of default values
- """
- def __init__(self, root_path, defaults=None):
- dict.__init__(self, defaults or {})
- self.root_path = root_path
- def from_envvar(self, variable_name, silent=False):
- """Loads a configuration from an environment variable pointing to
- a configuration file. This is basically just a shortcut with nicer
- error messages for this line of code::
- app.config.from_pyfile(os.environ['YOURAPPLICATION_SETTINGS'])
- :param variable_name: name of the environment variable
- :param silent: set to `True` if you want silent failure for missing
- files.
- :return: bool. `True` if able to load config, `False` otherwise.
- """
- rv = os.environ.get(variable_name)
- if not rv:
- if silent:
- return False
- raise RuntimeError('The environment variable %r is not set '
- 'and as such configuration could not be '
- 'loaded. Set this variable and make it '
- 'point to a configuration file' %
- variable_name)
- return self.from_pyfile(rv, silent=silent)
- def from_pyfile(self, filename, silent=False):
- """Updates the values in the config from a Python file. This function
- behaves as if the file was imported as module with the
- :meth:`from_object` function.
- :param filename: the filename of the config. This can either be an
- absolute filename or a filename relative to the
- root path.
- :param silent: set to `True` if you want silent failure for missing
- files.
- .. versionadded:: 0.7
- `silent` parameter.
- """
- filename = os.path.join(self.root_path, filename)
- d = imp.new_module('config')
- d.__file__ = filename
- try:
- with open(filename) as config_file:
- exec(compile(config_file.read(), filename, 'exec'), d.__dict__)
- except IOError as e:
- if silent and e.errno in (errno.ENOENT, errno.EISDIR):
- return False
- e.strerror = 'Unable to load configuration file (%s)' % e.strerror
- raise
- self.from_object(d)
- return True
- def from_object(self, obj):
- """Updates the values from the given object. An object can be of one
- of the following two types:
- - a string: in this case the object with that name will be imported
- - an actual object reference: that object is used directly
- Objects are usually either modules or classes.
- Just the uppercase variables in that object are stored in the config.
- Example usage::
- app.config.from_object('yourapplication.default_config')
- from yourapplication import default_config
- app.config.from_object(default_config)
- You should not use this function to load the actual configuration but
- rather configuration defaults. The actual config should be loaded
- with :meth:`from_pyfile` and ideally from a location not within the
- package because the package might be installed system wide.
- :param obj: an import name or object
- """
- if isinstance(obj, string_types):
- obj = import_string(obj)
- for key in dir(obj):
- if key.isupper():
- self[key] = getattr(obj, key)
- def __repr__(self):
- return '<%s %s>' % (self.__class__.__name__, dict.__repr__(self))
- def import_string(import_name, silent=False):
- """Imports an object based on a string. This is useful if you want to
- use import paths as endpoints or something similar. An import path can
- be specified either in dotted notation (``xml.sax.saxutils.escape``)
- or with a colon as object delimiter (``xml.sax.saxutils:escape``).
- If `silent` is True the return value will be `None` if the import fails.
- :param import_name: the dotted name for the object to import.
- :param silent: if set to `True` import errors are ignored and
- `None` is returned instead.
- :return: imported object
- """
- #XXX: py3 review needed
- assert isinstance(import_name, string_types)
- # force the import name to automatically convert to strings
- import_name = str(import_name)
- try:
- if ':' in import_name:
- module, obj = import_name.split(':', 1)
- elif '.' in import_name:
- module, obj = import_name.rsplit('.', 1)
- else:
- return __import__(import_name)
- # __import__ is not able to handle unicode strings in the fromlist
- # if the module is a package
- if sys.version_info[0] == 2 and isinstance(obj, unicode):
- obj = obj.encode('utf-8')
- try:
- return getattr(__import__(module, None, None, [obj]), obj)
- except (ImportError, AttributeError):
- # support importing modules not yet set up by the parent module
- # (or package for that matter)
- modname = module + '.' + obj
- __import__(modname)
- return sys.modules[modname]
- except ImportError as e:
- if not silent:
- raise e
|