From 9a397c4512bdeb2def2bcc5b314a8143fb8307fb Mon Sep 17 00:00:00 2001 From: Peter Eichman Date: Fri, 28 Oct 2016 17:07:30 -0400 Subject: [PATCH] Support reading environment variables into config. (#246) Implemented by enabling interpolation in the "template" style (e.g., run_as_user='$USER'). When loading the config, the webapp.py copies the os.environ dictionary into the DEFAULT section of the config object. Consolidated the two places the ConfigObj is created into one read_config method. --- doc/configuration.md | 13 +++++++++++++ etc/loris2.conf | 5 ++++- loris/webapp.py | 19 +++++++++++++++---- 3 files changed, 32 insertions(+), 5 deletions(-) diff --git a/doc/configuration.md b/doc/configuration.md index 664390c5..2b96afee 100644 --- a/doc/configuration.md +++ b/doc/configuration.md @@ -7,6 +7,16 @@ In addition to a bunch of directory paths (items that end with `_dp`) which shou **Quick Start:** Nearly everything should fine with the default settings. As long as you're pointing to `kdu_expand` and the Kakadu libs (as discussed in the [previous](dependencies.md) section) you can proceed to [Cache Maintenance](cache_maintenance.md) and come back later. +Environment variables are loaded into the `[DEFAULT]` section of the config file in memory, and `Template`-style [string interpolation] is on. This means you can pull in config information from the environment instead of hardcoding it in the config file. For example: + +``` +... +# get user and group from the environment +run_as_user='$USER' +run_as_group='$GROUP' +... +``` + ### `[loris.Loris]` @@ -19,6 +29,7 @@ In addition to a bunch of directory paths (items that end with `_dp`) which shou * `max_size_above_full` A numerical value which restricts the maximum image size to `max_size_above_full` percent of the original image size. Setting this value to 100 disables server side interpolation of images. Default value is 200 (maximum double width or height allowed). To allow any size, set this value to 0. * `proxy_path` The path you would like loris to proxy to. This will override the default path to your info.json file. proxy_path defaults to None if not explicitly set. + ### `[logging]` Each module has its own logger and is chock-full of debug statements, so setting the level to to `INFO` or higher is highly recommended. @@ -56,3 +67,5 @@ Then Loris will, as the name of the option suggests, map the color profile that * * * Proceed to [Cache Maintenance](cache_maintenance.md) or go [Back to README](../README.md) + +[string interpolation]: http://www.voidspace.org.uk/python/configobj.html#string-interpolation diff --git a/etc/loris2.conf b/etc/loris2.conf index e64daa7b..d7c29b55 100644 --- a/etc/loris2.conf +++ b/etc/loris2.conf @@ -16,7 +16,10 @@ # # # -# String interpolation is disabled. +# String interpolation is enabled using the "template" style. OS environment +# variables are available for interpolation, e.g., run_as_user='$USER' +# +# # [loris.Loris] diff --git a/loris/webapp.py b/loris/webapp.py index 6538432d..2e383841 100755 --- a/loris/webapp.py +++ b/loris/webapp.py @@ -30,17 +30,19 @@ import re import string import transforms +import os getcontext().prec = 25 # Decimal precision. This should be plenty. def create_app(debug=False, debug_jp2_transformer='kdu', config_file_path=''): global logger if debug: - project_dp = path.dirname(path.dirname(path.realpath(__file__))) - # change a few things, read the config and set up logging + project_dp = path.dirname(path.dirname(path.realpath(__file__))) config_file_path = path.join(project_dp, 'etc', 'loris2.conf') - config = ConfigObj(config_file_path, unrepr=True, interpolation=False) + + config = read_config(config_file_path) + config['logging']['log_to'] = 'console' config['logging']['log_level'] = 'DEBUG' __configure_logging(config['logging']) @@ -71,7 +73,7 @@ def create_app(debug=False, debug_jp2_transformer='kdu', config_file_path=''): config['transforms']['jp2']['kdu_libs'] = path.join(project_dp, libkdu_dir) else: - config = ConfigObj(config_file_path, unrepr=True, interpolation=False) + config = read_config(config_file_path) __configure_logging(config['logging']) logger = logging.getLogger(__name__) logger.debug('Running in production mode.') @@ -97,6 +99,15 @@ def create_app(debug=False, debug_jp2_transformer='kdu', config_file_path=''): else: return Loris(config, debug) +def read_config(config_file_path): + config = ConfigObj(config_file_path, unrepr=True, interpolation='template') + # add the OS environment variables as the DEFAULT section to support + # interpolating their values into other keys + # make a copy of the os.environ dictionary so that the config object can't + # inadvertently modify the environment + config['DEFAULT'] = dict(os.environ) + return config + def __configure_logging(config): logger = logging.getLogger()