Skip to content
This repository
Newer
Older
100644 233 lines (185 sloc) 8.654 kb
4f8ee8f1 »
2010-07-04 Added missing comments, fixed setup.py and made tests pass
1 # -*- coding: utf-8 -*-
2 """
3 flask.config
4 ~~~~~~~~~~~~
5
6 Implements the configuration related objects.
7
52098e1e » DasIch
2014-01-02 Happy New Year 2014
8 :copyright: (c) 2014 by Armin Ronacher.
4f8ee8f1 »
2010-07-04 Added missing comments, fixed setup.py and made tests pass
9 :license: BSD, see LICENSE for more details.
10 """
11
405c2992 » jbweber
2010-10-18 Updated from_pyfile so its dynamic module creation uses the imp modul…
12 import imp
c4f64c1c » justquick
2010-07-02 working import layout for module
13 import os
fa981777 » akavlie
2011-03-14 Test passes.
14 import errno
c4f64c1c » justquick
2010-07-02 working import layout for module
15
2866ccda »
2011-07-15 Switch to explicit Werkzeug imports
16 from werkzeug.utils import import_string
ba80e1e3 » DasIch
2014-03-13 Fix Python 3 compat issue in Config.get_namespace
17 from ._compat import string_types, iteritems
b290bf40 » mattupstate
2013-08-07 Add ability to config from a JSON file
18 from . import json
d0dc89ea » justquick
2010-07-02 in with the new. i have the bits in places where i think they should …
19
20
21 class ConfigAttribute(object):
22 """Makes an attribute forward to the config"""
23
8da8a21b »
2011-09-25 Moved the conversion thing into the ConfigAttribute.
24 def __init__(self, name, get_converter=None):
d0dc89ea » justquick
2010-07-02 in with the new. i have the bits in places where i think they should …
25 self.__name__ = name
8da8a21b »
2011-09-25 Moved the conversion thing into the ConfigAttribute.
26 self.get_converter = get_converter
d0dc89ea » justquick
2010-07-02 in with the new. i have the bits in places where i think they should …
27
28 def __get__(self, obj, type=None):
29 if obj is None:
30 return self
8da8a21b »
2011-09-25 Moved the conversion thing into the ConfigAttribute.
31 rv = obj.config[self.__name__]
32 if self.get_converter is not None:
33 rv = self.get_converter(rv)
34 return rv
d0dc89ea » justquick
2010-07-02 in with the new. i have the bits in places where i think they should …
35
36 def __set__(self, obj, value):
37 obj.config[self.__name__] = value
38
39
40 class Config(dict):
41 """Works exactly like a dict but provides ways to fill it from files
42 or special dictionaries. There are two common patterns to populate the
43 config.
44
45 Either you can fill the config from a config file::
46
47 app.config.from_pyfile('yourconfig.cfg')
48
49 Or alternatively you can define the configuration options in the
50 module that calls :meth:`from_object` or provide an import path to
51 a module that should be loaded. It is also possible to tell it to
52 use the same module and with that provide the configuration values
53 just before the call::
54
55 DEBUG = True
56 SECRET_KEY = 'development key'
57 app.config.from_object(__name__)
58
59 In both cases (loading from any Python file or loading from modules),
60 only uppercase keys are added to the config. This makes it possible to use
61 lowercase values in the config file for temporary values that are not added
62 to the config or to define the config keys in the same file that implements
63 the application.
64
65 Probably the most interesting way to load configurations is from an
66 environment variable pointing to a file::
67
68 app.config.from_envvar('YOURAPPLICATION_SETTINGS')
69
70 In this case before launching the application you have to set this
71 environment variable to the file you want to use. On Linux and OS X
72 use the export statement::
73
74 export YOURAPPLICATION_SETTINGS='/path/to/config/file'
75
76 On windows use `set` instead.
77
78 :param root_path: path to which files are read relative from. When the
79 config object is created by the application, this is
80 the application's :attr:`~flask.Flask.root_path`.
81 :param defaults: an optional dictionary of default values
82 """
83
84 def __init__(self, root_path, defaults=None):
85 dict.__init__(self, defaults or {})
86 self.root_path = root_path
87
88 def from_envvar(self, variable_name, silent=False):
89 """Loads a configuration from an environment variable pointing to
5cc40f47 » akavlie
2011-03-14 silent option added to 'from_pyfile' to mirror 'from_envvar'.
90 a configuration file. This is basically just a shortcut with nicer
d0dc89ea » justquick
2010-07-02 in with the new. i have the bits in places where i think they should …
91 error messages for this line of code::
92
93 app.config.from_pyfile(os.environ['YOURAPPLICATION_SETTINGS'])
94
95 :param variable_name: name of the environment variable
67581795 » akavlie
2011-03-14 Improved botched docstring wording for silent failure.
96 :param silent: set to `True` if you want silent failure for missing
d0dc89ea » justquick
2010-07-02 in with the new. i have the bits in places where i think they should …
97 files.
98 :return: bool. `True` if able to load config, `False` otherwise.
99 """
100 rv = os.environ.get(variable_name)
101 if not rv:
102 if silent:
103 return False
104 raise RuntimeError('The environment variable %r is not set '
105 'and as such configuration could not be '
106 'loaded. Set this variable and make it '
107 'point to a configuration file' %
108 variable_name)
76773e1d » dave-shawley
2012-03-01 Fixed silent keyword arg to config.from_envvar.
109 return self.from_pyfile(rv, silent=silent)
d0dc89ea » justquick
2010-07-02 in with the new. i have the bits in places where i think they should …
110
5cc40f47 » akavlie
2011-03-14 silent option added to 'from_pyfile' to mirror 'from_envvar'.
111 def from_pyfile(self, filename, silent=False):
d0dc89ea » justquick
2010-07-02 in with the new. i have the bits in places where i think they should …
112 """Updates the values in the config from a Python file. This function
113 behaves as if the file was imported as module with the
114 :meth:`from_object` function.
115
116 :param filename: the filename of the config. This can either be an
117 absolute filename or a filename relative to the
118 root path.
67581795 » akavlie
2011-03-14 Improved botched docstring wording for silent failure.
119 :param silent: set to `True` if you want silent failure for missing
5cc40f47 » akavlie
2011-03-14 silent option added to 'from_pyfile' to mirror 'from_envvar'.
120 files.
34a49471 »
2011-03-14 Documented some changes in config handling.
121
122 .. versionadded:: 0.7
123 `silent` parameter.
d0dc89ea » justquick
2010-07-02 in with the new. i have the bits in places where i think they should …
124 """
125 filename = os.path.join(self.root_path, filename)
405c2992 » jbweber
2010-10-18 Updated from_pyfile so its dynamic module creation uses the imp modul…
126 d = imp.new_module('config')
d0dc89ea » justquick
2010-07-02 in with the new. i have the bits in places where i think they should …
127 d.__file__ = filename
778e44e3 »
2010-07-30 Improved error message for configuration files
128 try:
43b6d0a6 » DasIch
2013-05-22 Ensure that config file is closed immediately
129 with open(filename) as config_file:
130 exec(compile(config_file.read(), filename, 'exec'), d.__dict__)
6caaa8a5 » ThomasWaldmann
2013-05-18 automated change using python-modernize: use 'as' in except
131 except IOError as e:
5cc40f47 » akavlie
2011-03-14 silent option added to 'from_pyfile' to mirror 'from_envvar'.
132 if silent and e.errno in (errno.ENOENT, errno.EISDIR):
133 return False
778e44e3 »
2010-07-30 Improved error message for configuration files
134 e.strerror = 'Unable to load configuration file (%s)' % e.strerror
135 raise
d0dc89ea » justquick
2010-07-02 in with the new. i have the bits in places where i think they should …
136 self.from_object(d)
5cc40f47 » akavlie
2011-03-14 silent option added to 'from_pyfile' to mirror 'from_envvar'.
137 return True
d0dc89ea » justquick
2010-07-02 in with the new. i have the bits in places where i think they should …
138
139 def from_object(self, obj):
140 """Updates the values from the given object. An object can be of one
141 of the following two types:
142
143 - a string: in this case the object with that name will be imported
144 - an actual object reference: that object is used directly
145
146 Objects are usually either modules or classes.
147
ea77d5e1 » rduplain
2011-05-19 Touch up docs according to user feedback.
148 Just the uppercase variables in that object are stored in the config.
149 Example usage::
d0dc89ea » justquick
2010-07-02 in with the new. i have the bits in places where i think they should …
150
151 app.config.from_object('yourapplication.default_config')
152 from yourapplication import default_config
153 app.config.from_object(default_config)
154
155 You should not use this function to load the actual configuration but
156 rather configuration defaults. The actual config should be loaded
157 with :meth:`from_pyfile` and ideally from a location not within the
158 package because the package might be installed system wide.
159
160 :param obj: an import name or object
161 """
e1d356fb » ThomasWaldmann
2013-05-22 ported some more stuff to py 3.3
162 if isinstance(obj, string_types):
d0dc89ea » justquick
2010-07-02 in with the new. i have the bits in places where i think they should …
163 obj = import_string(obj)
164 for key in dir(obj):
165 if key.isupper():
166 self[key] = getattr(obj, key)
167
b290bf40 » mattupstate
2013-08-07 Add ability to config from a JSON file
168 def from_json(self, filename, silent=False):
169 """Updates the values in the config from a JSON file. This function
170 behaves as if the JSON object was a dictionary and passed ot the
171 :meth:`from_object` function.
172
173 :param filename: the filename of the JSON file. This can either be an
174 absolute filename or a filename relative to the
175 root path.
176 :param silent: set to `True` if you want silent failure for missing
177 files.
97411295 » DasIch
2014-02-12 Add Config.from_json to changelog
178
179 .. versionadded:: 1.0
b290bf40 » mattupstate
2013-08-07 Add ability to config from a JSON file
180 """
181 filename = os.path.join(self.root_path, filename)
182
183 try:
184 with open(filename) as json_file:
185 obj = json.loads(json_file.read())
186 except IOError as e:
187 if silent and e.errno in (errno.ENOENT, errno.EISDIR):
188 return False
189 e.strerror = 'Unable to load configuration file (%s)' % e.strerror
190 raise
191 for key in obj.keys():
192 if key.isupper():
193 self[key] = obj[key]
194 return True
195
90a50f8b » mattupstate
2014-01-23 Add `get_namespace` method on `Config` object for convenient access o…
196 def get_namespace(self, namespace, lowercase=True):
197 """Returns a dictionary containing a subset of configuration options
198 that match the specified namespace/prefix. Example usage::
199
200 app.config['IMAGE_STORE_TYPE'] = 'fs'
201 app.config['IMAGE_STORE_PATH'] = '/var/app/images'
202 app.config['IMAGE_STORE_BASE_URL'] = 'http://img.website.com'
203 image_store_config = app.config.get_namespace('IMAGE_STORE_')
204
205 The resulting dictionary `image_store` would look like::
206
207 {
208 'type': 'fs',
209 'path': '/var/app/images',
210 'base_url': 'http://img.website.com'
211 }
212
213 This is often useful when configuration options map directly to
214 keyword arguments in functions or class constructors.
215
216 :param namespace: a configuration namespace
217 :param lowercase: a flag indicating if the keys of the resulting
218 dictionary should be lowercase
06857c9b » DasIch
2014-03-13 Add Config.get_namespace to CHANGES
219
220 .. versionadded:: 1.0
90a50f8b » mattupstate
2014-01-23 Add `get_namespace` method on `Config` object for convenient access o…
221 """
222 rv = {}
ba80e1e3 » DasIch
2014-03-13 Fix Python 3 compat issue in Config.get_namespace
223 for k, v in iteritems(self):
90a50f8b » mattupstate
2014-01-23 Add `get_namespace` method on `Config` object for convenient access o…
224 if not k.startswith(namespace):
225 continue
226 key = k[len(namespace):]
227 if lowercase:
228 key = key.lower()
229 rv[key] = v
230 return rv
231
d0dc89ea » justquick
2010-07-02 in with the new. i have the bits in places where i think they should …
232 def __repr__(self):
233 return '<%s %s>' % (self.__class__.__name__, dict.__repr__(self))
Something went wrong with that request. Please try again.