# -*- coding: utf-8 -*-"""flask.config~~~~~~~~~~~~Implements the configuration related objects.:copyright: © 2010 by the Pallets team.:license: BSD, see LICENSE for more details."""import osimport typesimport errnofrom werkzeug.utils import import_stringfrom ._compat import string_types, iteritemsfrom . import jsonclass ConfigAttribute(object):"""Makes an attribute forward to the config"""def __init__(self, name, get_converter=None):self.__name__ = nameself.get_converter = get_converterdef __get__(self, obj, type=None):if obj is None:return selfrv = obj.config[self.__name__]if self.get_converter is not None:rv = self.get_converter(rv)return rvdef __set__(self, obj, value):obj.config[self.__name__] = valueclass Config(dict):"""Works exactly like a dict but provides ways to fill it from filesor special dictionaries. There are two common patterns to populate theconfig.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 themodule that calls :meth:`from_object` or provide an import path toa module that should be loaded. It is also possible to tell it touse the same module and with that provide the configuration valuesjust before the call::DEBUG = TrueSECRET_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 uselowercase values in the config file for temporary values that are not addedto the config or to define the config keys in the same file that implementsthe application.Probably the most interesting way to load configurations is from anenvironment variable pointing to a file::app.config.from_envvar('YOURAPPLICATION_SETTINGS')In this case before launching the application you have to set thisenvironment variable to the file you want to use. On Linux and OS Xuse 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 theconfig object is created by the application, this isthe 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_pathdef from_envvar(self, variable_name, silent=False):"""Loads a configuration from an environment variable pointing toa configuration file. This is basically just a shortcut with nicererror 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 missingfiles.:return: bool. ``True`` if able to load config, ``False`` otherwise."""rv = os.environ.get(variable_name)if not rv:if silent:return Falseraise 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 functionbehaves 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 anabsolute filename or a filename relative to theroot path.:param silent: set to ``True`` if you want silent failure for missingfiles... versionadded:: 0.7`silent` parameter."""filename = os.path.join(self.root_path, filename)d = types.ModuleType('config')d.__file__ = filenametry:with open(filename, mode='rb') 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, errno.ENOTDIR):return Falsee.strerror = 'Unable to load configuration file (%s)' % e.strerrorraiseself.from_object(d)return Truedef from_object(self, obj):"""Updates the values from the given object. An object can be of oneof 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 directlyObjects are usually either modules or classes. :meth:`from_object`loads only the uppercase attributes of the module/class. A ``dict``object will not work with :meth:`from_object` because the keys of a``dict`` are not attributes of the ``dict`` class.Example of module-based configuration::app.config.from_object('yourapplication.default_config')from yourapplication import default_configapp.config.from_object(default_config)You should not use this function to load the actual configuration butrather configuration defaults. The actual config should be loadedwith :meth:`from_pyfile` and ideally from a location not within thepackage because the package might be installed system wide.See :ref:`config-dev-prod` for an example of class-based configurationusing :meth:`from_object`.: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 from_json(self, filename, silent=False):"""Updates the values in the config from a JSON file. This functionbehaves as if the JSON object was a dictionary and passed to the:meth:`from_mapping` function.:param filename: the filename of the JSON file. This can either be anabsolute filename or a filename relative to theroot path.:param silent: set to ``True`` if you want silent failure for missingfiles... versionadded:: 0.11"""filename = os.path.join(self.root_path, filename)try:with open(filename) as json_file:obj = json.loads(json_file.read())except IOError as e:if silent and e.errno in (errno.ENOENT, errno.EISDIR):return Falsee.strerror = 'Unable to load configuration file (%s)' % e.strerrorraisereturn self.from_mapping(obj)def from_mapping(self, *mapping, **kwargs):"""Updates the config like :meth:`update` ignoring items with non-upperkeys... versionadded:: 0.11"""mappings = []if len(mapping) == 1:if hasattr(mapping[0], 'items'):mappings.append(mapping[0].items())else:mappings.append(mapping[0])elif len(mapping) > 1:raise TypeError('expected at most 1 positional argument, got %d' % len(mapping))mappings.append(kwargs.items())for mapping in mappings:for (key, value) in mapping:if key.isupper():self[key] = valuereturn Truedef get_namespace(self, namespace, lowercase=True, trim_namespace=True):"""Returns a dictionary containing a subset of configuration optionsthat match the specified namespace/prefix. Example usage::app.config['IMAGE_STORE_TYPE'] = 'fs'app.config['IMAGE_STORE_PATH'] = '/var/app/images'app.config['IMAGE_STORE_BASE_URL'] = 'http://img.website.com'image_store_config = app.config.get_namespace('IMAGE_STORE_')The resulting dictionary `image_store_config` would look like::{'type': 'fs','path': '/var/app/images','base_url': 'http://img.website.com'}This is often useful when configuration options map directly tokeyword arguments in functions or class constructors.:param namespace: a configuration namespace:param lowercase: a flag indicating if the keys of the resultingdictionary should be lowercase:param trim_namespace: a flag indicating if the keys of the resultingdictionary should not include the namespace.. versionadded:: 0.11"""rv = {}for k, v in iteritems(self):if not k.startswith(namespace):continueif trim_namespace:key = k[len(namespace):]else:key = kif lowercase:key = key.lower()rv[key] = vreturn rvdef __repr__(self):return '<%s %s>' % (self.__class__.__name__, dict.__repr__(self))
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。