Skip to content

Commit baca7ae

Browse files
mklappirnicolaiarocci
authored andcommitted
better locating of settings.py
Addresses pyeve#137. Addresses pyeve#209. Addresses pyeve#713. Addresses pyeve#918. Closes pyeve#820.
1 parent d565606 commit baca7ae

File tree

6 files changed

+65
-19
lines changed

6 files changed

+65
-19
lines changed

.gitignore

+5
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ Include
5151
Lib
5252
Scripts
5353

54+
#pyenv
55+
.python-version
56+
5457
#OSX
5558
.Python
5659
.DS_Store
@@ -60,3 +63,5 @@ _build
6063

6164
# PyCharm
6265
.idea
66+
67+
.cache

AUTHORS

+1
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ Patches and Contributions
8888
- Marc Abramowitz
8989
- Marcus Cobden
9090
- Marica Odagaki
91+
- Mario Kralj
9192
- Massimo Scamarcia
9293
- Mateusz Łoskot
9394
- Matt Creenan

docs/config.rst

+21-9
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,22 @@
33
Configuration
44
=============
55
Generally Eve configuration is best done with configuration files. The
6-
configuration files themselves are actual Python files.
6+
configuration files themselves are actual Python files. However, Eve will
7+
give precedence to dictionary-based settings first, then it will try to
8+
locate a file passed in :envvar:`EVE_SETTINGS` environmental variable (if
9+
set) and finally it will try to locate `settings.py` or a file with filename
10+
passed to `settings` flag in constructor.
711

8-
Configuration with Files
12+
Configuration With Files
913
------------------------
10-
On startup, Eve will look for a `settings.py` file in the application folder.
11-
You can choose an alternative filename/path. Just pass it as an argument when
12-
you instantiate the application.
14+
On startup, if `settings` flag is omitted in constructor, Eve will try to locate
15+
file named `settings.py`, first in the application folder and then in one of the
16+
application's subfolders. You can choose an alternative filename/path, just pass
17+
it as an argument when you instantiate the application. If the file path is
18+
relative, Eve will try to locate it recursively in one of the folders in your
19+
`sys.path`, therefore you have to be sure that your application root is appended
20+
to it. This is useful, for example, in testing environments, when settings file
21+
is not necessarily located in the root of your application.
1322

1423
.. code-block:: python
1524
@@ -18,21 +27,24 @@ you instantiate the application.
1827
app = Eve(settings='my_settings.py')
1928
app.run()
2029
21-
Configuration with a Dictionary
30+
Configuration With a Dictionary
2231
-------------------------------
23-
Alternatively, you can choose to provide a settings dictionary:
32+
Alternatively, you can choose to provide a settings dictionary. Unlike
33+
configuring Eve with the settings file, dictionary-based approach will only
34+
update Eve's default settings with your own values, rather than overwriting
35+
all the settings.
2436

2537
.. code-block:: python
2638
39+
from eve import Eve
40+
2741
my_settings = {
2842
'MONGO_HOST': 'localhost',
2943
'MONGO_PORT': 27017,
3044
'MONGO_DBNAME': 'the_db_name',
3145
'DOMAIN': {'contacts': {}}
3246
}
3347
34-
from eve import Eve
35-
3648
app = Eve(settings=my_settings)
3749
app.run()
3850

eve/flaskapp.py

+24-10
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
:copyright: (c) 2017 by Nicola Iarocci.
1010
:license: BSD, see LICENSE for more details.
1111
"""
12+
import fnmatch
1213
import os
1314
import sys
1415

@@ -227,21 +228,34 @@ def load_config(self):
227228
if os.path.isabs(self.settings):
228229
pyfile = self.settings
229230
else:
230-
abspath = os.path.abspath(os.path.dirname(sys.argv[0]))
231-
pyfile = os.path.join(abspath, self.settings)
231+
def find_settings_file(file_name):
232+
# check if we can locate the file from sys.argv[0]
233+
abspath = os.path.abspath(os.path.dirname(sys.argv[0]))
234+
settings_file = os.path.join(abspath, file_name)
235+
if os.path.isfile(settings_file):
236+
return settings_file
237+
else:
238+
# try to find settings.py in one of the
239+
# paths in sys.path
240+
for p in sys.path:
241+
for root, dirs, files in os.walk(p):
242+
for f in fnmatch.filter(files, file_name):
243+
if os.path.isfile(os.path.join(root, f)):
244+
return os.path.join(root, file_name)
245+
246+
# try to load file from environment variable or settings.py
247+
pyfile = find_settings_file(
248+
os.environ.get('EVE_SETTINGS') or self.settings
249+
)
250+
251+
if not pyfile:
252+
raise IOError('Could not load settings.')
253+
232254
try:
233255
self.config.from_pyfile(pyfile)
234-
except IOError:
235-
# assume envvar is going to be used exclusively
236-
pass
237256
except:
238257
raise
239258

240-
# overwrite settings with custom environment variable
241-
envvar = 'EVE_SETTINGS'
242-
if os.environ.get(envvar):
243-
self.config.from_envvar(envvar)
244-
245259
# flask-pymongo compatibility
246260
self.config['MONGO_CONNECT'] = self.config['MONGO_OPTIONS'].get(
247261
'connect', True

eve/tests/config.py

+7
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,13 @@ def test_settings_as_dict(self):
9595
# did not reset other defaults
9696
self.assertEqual(self.app.config['MONGO_WRITE_CONCERN'], {'w': 1})
9797

98+
def test_existing_env_config(self):
99+
env = os.environ
100+
os.environ = {'EVE_SETTINGS': 'test_settings_env.py'}
101+
self.app = Eve()
102+
self.assertTrue('env_domain' in self.app.config['DOMAIN'])
103+
os.environ = env
104+
98105
def test_unexisting_env_config(self):
99106
env = os.environ
100107
try:

eve/tests/test_settings_env.py

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# -*- coding: utf-8 -*-
2+
3+
# this is just a helper file which we are going
4+
# to try to load with environmental variable in
5+
# test_existing_env_config() test case
6+
7+
DOMAIN = {'env_domain': {}}

0 commit comments

Comments
 (0)