Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Add ability to configure app with a JSON file #827

Merged
merged 1 commit into from

4 participants

@mattupstate

Thought this would be useful for some people.

My use case stems from the fact that its not trivial to generate a Python file with a deployment tool like Chef. But it is trivial to render a JSON file.

@ericmanlol

very interesting matt!

@ghost

Nice idea!
Why don't you add error handling for not valid JSON? And what about loading from a string?

@untitaker
Collaborator

IMO the default exception messages are good enough, even for IOError.

@untitaker
Collaborator

But it looks cool to me, +1.

@mattupstate

@gioi I thought mimicking the same behavior as from_pyfile would be appropriate

@DasIch DasIch merged commit b290bf4 into mitsuhiko:master
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Aug 7, 2013
  1. @mattupstate
This page is out of date. Refresh to see the latest.
View
27 flask/config.py
@@ -15,6 +15,7 @@
from werkzeug.utils import import_string
from ._compat import string_types
+from . import json
class ConfigAttribute(object):
@@ -164,5 +165,31 @@ def from_object(self, 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 function
+ behaves as if the JSON object was a dictionary and passed ot the
+ :meth:`from_object` function.
+
+ :param filename: the filename of the JSON file. 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.
+ """
+ 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 False
+ e.strerror = 'Unable to load configuration file (%s)' % e.strerror
+ raise
+ for key in obj.keys():
+ if key.isupper():
+ self[key] = obj[key]
+ return True
+
def __repr__(self):
return '<%s %s>' % (self.__class__.__name__, dict.__repr__(self))
View
19 flask/testsuite/config.py
@@ -40,6 +40,12 @@ def test_config_from_object(self):
app.config.from_object(__name__)
self.common_object_test(app)
+ def test_config_from_json(self):
+ app = flask.Flask(__name__)
+ current_dir = os.path.dirname(os.path.abspath(__file__))
+ app.config.from_json(os.path.join(current_dir, 'static', 'config.json'))
+ self.common_object_test(app)
+
def test_config_from_class(self):
class Base(object):
TEST_KEY = 'foo'
@@ -99,6 +105,19 @@ def test_config_missing(self):
self.assert_true(0, 'expected config')
self.assert_false(app.config.from_pyfile('missing.cfg', silent=True))
+ def test_config_missing_json(self):
+ app = flask.Flask(__name__)
+ try:
+ app.config.from_json('missing.json')
+ except IOError as e:
+ msg = str(e)
+ self.assert_true(msg.startswith('[Errno 2] Unable to load configuration '
+ 'file (No such file or directory):'))
+ self.assert_true(msg.endswith("missing.json'"))
+ else:
+ self.assert_true(0, 'expected config')
+ self.assert_false(app.config.from_json('missing.json', silent=True))
+
def test_session_lifetime(self):
app = flask.Flask(__name__)
app.config['PERMANENT_SESSION_LIFETIME'] = 42
View
4 flask/testsuite/static/config.json
@@ -0,0 +1,4 @@
+{
+ "TEST_KEY": "foo",
+ "SECRET_KEY": "devkey"
+}
Something went wrong with that request. Please try again.