mirror of
https://github.com/spiral-project/ihatemoney.git
synced 2025-04-28 17:32:38 +02:00
Externalize the settings (#193)
Default settings from app's root path are loaded first Settings are then overriden by /etc/ihatemoney/ihatemoney.cfg or by another file which path is set in an env var Fixes #187
This commit is contained in:
parent
fb84135fe5
commit
e3da3b3b7f
6 changed files with 101 additions and 29 deletions
48
README.rst
48
README.rst
|
@ -25,16 +25,6 @@ you just have to run the following command::
|
||||||
|
|
||||||
This will run a Flask app available at `http://localhost:5000`.
|
This will run a Flask app available at `http://localhost:5000`.
|
||||||
|
|
||||||
It is also better to actually turn the debugging mode on when you're
|
|
||||||
developing. You can create a `settings.py` file in the `budget` directory, with
|
|
||||||
the following content::
|
|
||||||
|
|
||||||
DEBUG = True
|
|
||||||
SQLACHEMY_ECHO = DEBUG
|
|
||||||
|
|
||||||
You can also set the `TESTING` flag to `True` so no mails are sent
|
|
||||||
(and no exception is raised) while you're on development mode.
|
|
||||||
|
|
||||||
Deploy it
|
Deploy it
|
||||||
=========
|
=========
|
||||||
|
|
||||||
|
@ -62,13 +52,43 @@ With Nginx, Gunicorn and Supervisord
|
||||||
|
|
||||||
Don't forget to set the right permission for your files !
|
Don't forget to set the right permission for your files !
|
||||||
|
|
||||||
Also, create a `settings.py` file with the appropriate values if you need to
|
Configure it
|
||||||
use a different database for instance. You can also set `APPLICATION_ROOT` if
|
============
|
||||||
you want to prefix your URLs to serve ihatemonney in the *folder* of a domain,
|
|
||||||
e.g:
|
In a production environment
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
Make a copy of ``budget/default_settings.py`` and name it ``ihatemoney.cfg``.
|
||||||
|
Then adjust the settings to your needs and move this file to
|
||||||
|
``/etc/ihatemoney/ihatemoney.cfg``.
|
||||||
|
This is the default path of the settings but you can also place it
|
||||||
|
elsewhere and pass the configuration file path to the application using
|
||||||
|
the IHATEMONEY_SETTINGS_FILE_PATH environment variable.
|
||||||
|
e.g.::
|
||||||
|
|
||||||
|
$ export IHATEMONEY_SETTINGS_FILE_PATH="/path/to/your/conf/file.cfg"
|
||||||
|
|
||||||
|
Note that you can also pass additional flask parameters with this file.
|
||||||
|
e.g. If you want to prefix your URLs to serve ihatemonney in the *folder*
|
||||||
|
of a domain, use the following: ::
|
||||||
|
|
||||||
APPLICATION_ROOT='/budget'
|
APPLICATION_ROOT='/budget'
|
||||||
|
|
||||||
|
In a dev environment
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
It is better to actually turn the debugging mode on when you're developing.
|
||||||
|
You can create a ``settings.cfg`` file, with the following content::
|
||||||
|
|
||||||
|
DEBUG = True
|
||||||
|
SQLACHEMY_ECHO = DEBUG
|
||||||
|
|
||||||
|
You can also set the `TESTING` flag to `True` so no mails are sent
|
||||||
|
(and no exception is raised) while you're on development mode.
|
||||||
|
Then before running the application, declare its path with ::
|
||||||
|
|
||||||
|
$ export IHATEMONEY_SETTINGS_FILE_PATH="$(pwd)/settings.cfg"
|
||||||
|
|
||||||
The REST API?
|
The REST API?
|
||||||
=============
|
=============
|
||||||
|
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
"""
|
|
||||||
Merges default settings with user-defined settings
|
|
||||||
"""
|
|
||||||
|
|
||||||
from default_settings import *
|
|
||||||
|
|
||||||
try:
|
|
||||||
from settings import *
|
|
||||||
except ImportError:
|
|
||||||
pass
|
|
|
@ -12,7 +12,7 @@ from api import api
|
||||||
from utils import PrefixedWSGI
|
from utils import PrefixedWSGI
|
||||||
from utils import minimal_round
|
from utils import minimal_round
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__, instance_path='/etc/ihatemoney', instance_relative_config=True)
|
||||||
|
|
||||||
|
|
||||||
def pre_alembic_db():
|
def pre_alembic_db():
|
||||||
|
@ -27,8 +27,18 @@ def pre_alembic_db():
|
||||||
def configure():
|
def configure():
|
||||||
""" A way to (re)configure the app, specially reset the settings
|
""" A way to (re)configure the app, specially reset the settings
|
||||||
"""
|
"""
|
||||||
config_obj = os.environ.get('FLASK_SETTINGS_MODULE', 'merged_settings')
|
default_config_file = os.path.join(app.root_path, 'default_settings.py')
|
||||||
app.config.from_object(config_obj)
|
config_file = os.environ.get('IHATEMONEY_SETTINGS_FILE_PATH')
|
||||||
|
|
||||||
|
# Load default settings first
|
||||||
|
# Then load the settings from the path set in IHATEMONEY_SETTINGS_FILE_PATH var
|
||||||
|
# If not set, default to /etc/ihatemoney/ihatemoney.cfg
|
||||||
|
# If the latter doesn't exist no error is raised and the default settings are used
|
||||||
|
app.config.from_pyfile(default_config_file)
|
||||||
|
if config_file:
|
||||||
|
app.config.from_pyfile(config_file)
|
||||||
|
else:
|
||||||
|
app.config.from_pyfile('ihatemoney.cfg', silent=True)
|
||||||
app.wsgi_app = PrefixedWSGI(app)
|
app.wsgi_app = PrefixedWSGI(app)
|
||||||
|
|
||||||
# Deprecations
|
# Deprecations
|
||||||
|
|
7
budget/tests/ihatemoney.cfg
Normal file
7
budget/tests/ihatemoney.cfg
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
DEBUG = False
|
||||||
|
SQLALCHEMY_DATABASE_URI = 'sqlite:///budget.db'
|
||||||
|
SQLACHEMY_ECHO = DEBUG
|
||||||
|
|
||||||
|
SECRET_KEY = "supersecret"
|
||||||
|
|
||||||
|
MAIL_DEFAULT_SENDER = ("Budget manager", "budget@notmyidea.org")
|
7
budget/tests/ihatemoney_envvar.cfg
Normal file
7
budget/tests/ihatemoney_envvar.cfg
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
DEBUG = False
|
||||||
|
SQLALCHEMY_DATABASE_URI = 'sqlite:///budget.db'
|
||||||
|
SQLACHEMY_ECHO = DEBUG
|
||||||
|
|
||||||
|
SECRET_KEY = "lalatra"
|
||||||
|
|
||||||
|
MAIL_DEFAULT_SENDER = ("Budget manager", "budget@notmyidea.org")
|
|
@ -10,14 +10,18 @@ import json
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
import six
|
import six
|
||||||
|
|
||||||
os.environ['FLASK_SETTINGS_MODULE'] = 'default_settings'
|
|
||||||
|
|
||||||
from flask import session
|
from flask import session
|
||||||
|
|
||||||
|
# Unset configuration file env var if previously set
|
||||||
|
if 'IHATEMONEY_SETTINGS_FILE_PATH' in os.environ:
|
||||||
|
del os.environ['IHATEMONEY_SETTINGS_FILE_PATH']
|
||||||
|
|
||||||
import run
|
import run
|
||||||
import models
|
import models
|
||||||
import utils
|
import utils
|
||||||
|
|
||||||
|
__HERE__ = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
|
||||||
|
|
||||||
class TestCase(unittest.TestCase):
|
class TestCase(unittest.TestCase):
|
||||||
|
|
||||||
|
@ -65,6 +69,40 @@ class TestCase(unittest.TestCase):
|
||||||
|
|
||||||
class BudgetTestCase(TestCase):
|
class BudgetTestCase(TestCase):
|
||||||
|
|
||||||
|
def test_default_configuration(self):
|
||||||
|
"""Test that default settings are loaded when no other configuration file is specified"""
|
||||||
|
run.configure()
|
||||||
|
self.assertFalse(run.app.config['DEBUG'])
|
||||||
|
self.assertEqual(run.app.config['SQLALCHEMY_DATABASE_URI'], 'sqlite:///budget.db')
|
||||||
|
self.assertFalse(run.app.config['SQLALCHEMY_TRACK_MODIFICATIONS'])
|
||||||
|
self.assertEqual(run.app.config['SECRET_KEY'], 'tralala')
|
||||||
|
self.assertEqual(run.app.config['MAIL_DEFAULT_SENDER'],
|
||||||
|
("Budget manager", "budget@notmyidea.org"))
|
||||||
|
|
||||||
|
def test_env_var_configuration_file(self):
|
||||||
|
"""Test that settings are loaded from the specified configuration file"""
|
||||||
|
os.environ['IHATEMONEY_SETTINGS_FILE_PATH'] = os.path.join(__HERE__,
|
||||||
|
"ihatemoney_envvar.cfg")
|
||||||
|
run.configure()
|
||||||
|
self.assertEqual(run.app.config['SECRET_KEY'], 'lalatra')
|
||||||
|
|
||||||
|
# Test that the specified configuration file is loaded
|
||||||
|
# even if the default configuration file ihatemoney.cfg exists
|
||||||
|
os.environ['IHATEMONEY_SETTINGS_FILE_PATH'] = os.path.join(__HERE__,
|
||||||
|
"ihatemoney_envvar.cfg")
|
||||||
|
run.app.config.root_path = __HERE__
|
||||||
|
run.configure()
|
||||||
|
self.assertEqual(run.app.config['SECRET_KEY'], 'lalatra')
|
||||||
|
|
||||||
|
if 'IHATEMONEY_SETTINGS_FILE_PATH' in os.environ:
|
||||||
|
del os.environ['IHATEMONEY_SETTINGS_FILE_PATH']
|
||||||
|
|
||||||
|
def test_default_configuration_file(self):
|
||||||
|
"""Test that settings are loaded from the default configuration file"""
|
||||||
|
run.app.config.root_path = __HERE__
|
||||||
|
run.configure()
|
||||||
|
self.assertEqual(run.app.config['SECRET_KEY'], 'supersecret')
|
||||||
|
|
||||||
def test_notifications(self):
|
def test_notifications(self):
|
||||||
"""Test that the notifications are sent, and that email adresses
|
"""Test that the notifications are sent, and that email adresses
|
||||||
are checked properly.
|
are checked properly.
|
||||||
|
|
Loading…
Reference in a new issue