def test_empty(): def run_test(subject): assert subject.key is NotConfigured assert subject.deeper.key is NotConfigured run_test(Configuration()) run_test(Configuration({}))
def test_assignments(): subject = Configuration({'key1': 'value', 'key2': 5, 'namespace.key3': False}) subject._private = 42 subject.__very_private = 43 assert subject._private == 42 assert subject.__very_private == 43 with pytest.raises(AttributeError) as e: subject.non_existent = True assert 'assignment not supported' in str(e.value) and 'non_existent' in str(e.value) with pytest.raises(AttributeError) as e: subject.key1 = True assert 'assignment not supported' in str(e.value) and 'key1' in str(e.value) with pytest.raises(AttributeError) as e: subject.namespace.key3 = True assert 'assignment not supported' in str(e.value) and 'key3' in str(e.value) with pytest.raises(AttributeError) as e: subject.namespace.key4 = True assert 'assignment not supported' in str(e.value) and 'key4' in str(e.value) with pytest.raises(AttributeError) as e: subject.non_existent.key6 = True assert 'assignment not supported' in str(e.value) and 'key6' in str(e.value) with pytest.raises(AttributeError) as e: subject.we.must.go.deeper = True assert 'assignment not supported' in str(e.value) and 'deeper' in str(e.value)
def test_as_type(): subject = Configuration({'as_int': 5, 'as_str': '5'}) assert subject.get('as_int') == 5 assert subject.get('as_str') == '5' assert subject.get('as_str', as_type=str) == '5' assert subject.get('as_str', as_type=int) == 5 assert subject.get('as_str', as_type=bool) is True assert subject.get('as_str', as_type=lambda value: int(value) - 2) == 3
def handle(self, *args, **options): config = Configuration(settings.BASE_DIR) result = config.cleanup() if result: print_formatted( f'Deleted directory and all files in {config.workdir}.') else: print_formatted( f'Confidence working directory doesn\'t exist at {config.workdir}.' )
def handle(self, *args, **options): config = Configuration(settings.BASE_DIR) result = config.replicate() if result: print_formatted( f'Created configuration file at {config.filepath} from blueprint.' ) else: print_formatted( f'Blueprint doesn\'t exist. You may need to run `python manage.py configure` first.' )
def test_empty(): def run_test(subject): assert subject.get('path.without.value', default=None) is None assert subject.get('another.path.without.value', default=4) == 4 with pytest.raises(ConfigurationError) as e: subject.get('some_long.path') assert 'some_long' in str(e.value) with pytest.raises(KeyError) as e: subject['some_long'] assert 'some_long' in str(e.value) with pytest.raises(KeyError) as e: subject['some_long.path'] assert 'path' not in str(e.value) run_test(Configuration()) run_test(Configuration({}))
def test_multiple_sources(): subject = Configuration({'key': 'value'}, {'another.key': 42}) assert len(subject) == 2 assert subject.key == 'value' assert subject.another.key == 42
def test_sub_config_reference(): config = Configuration({ 'key': 'string', 'ns.test1': '${key}', 'ns.test2': '${ns.test1}', }) assert config.key == 'string' ns = config.ns assert ns.test1 == ns.get('test1') == 'string' assert ns.test2 == ns.get('test2') == 'string' ns = config.get('ns') assert ns.test1 == ns.get('test1') == 'string' assert ns.test2 == ns.get('test2') == 'string'
def test_overlapping_sources(): subject = Configuration({'namespace.key': 'value'}, {'namespace.another.key': 42}) assert len(subject) == 1 assert subject.namespace.key == 'value' assert subject.namespace.another.key == 42
def test_reference_syntax(): config = Configuration({ 'key1': '$(reference)', 'key2': '${reference)', 'key3': '${}', 'key4': '$ {reference}', 'key5': '#{reference}', 'key_with_space ': 'value', 'key with spaces': 'value2', 'key6': '${key_with_space }', 'key7': '${key with spaces}', 'key8': '${key_with_space}', }) assert config.reference is NotConfigured assert '$' in config.key1 assert '$' in config.key2 assert '$' in config.key3 assert '$' in config.key4 assert '#' in config.key5 assert config.key6 == 'value' assert config.key7 == 'value2' with pytest.raises(ConfiguredReferenceError): assert not config.key8
def test_sub_config_reference(): config = Configuration({ 'key': 'string', 'ns.test1': '${key}', 'ns.test2': '${ns.test1}', }) assert config.key == 'string' ns = config.ns assert ns.test1 == ns.get('test1') == 'string' assert ns.test2 == ns.get('test2') == 'string' ns = config.get('ns') assert ns.test1 == ns.get('test1') == 'string' assert ns.test2 == ns.get('test2') == 'string'
def test_value_types(): config = Configuration({ 'ns.str': 'string', 'ns.int': 42, 'ns.float': 2.0, 'ns.bool': True, 'ns.ref1': 'prefix ${ns.str} suffix', 'ns.ref2': 'p${ns.int}s', 'ns.ref3': '${ns.float}', 'ns.ref4': '${ns.bool}', }) assert config.ns.str == 'string' assert config.ns.ref1 == config.get('ns.ref1') == 'prefix string suffix' assert config.ns.ref2 == config.get('ns.ref2') == 'p42s' assert config.ns.ref3 == config.get('ns.ref3') == 2.0 assert config.ns.ref4 == config.get('ns.ref4') is True
def test_multiple_references(): config = Configuration({ 'key': 'A seemingly ${ns.word1}, ${ns.word2} sentence.', 'ns.word1': 'full', 'ns.word2': 'complete', }) assert config.key == 'A seemingly full, complete sentence.'
def test_value_types(): config = Configuration({ 'ns.str': 'string', 'ns.int': 42, 'ns.float': 2.0, 'ns.bool': True, 'ns.ref1': 'prefix ${ns.str} suffix', 'ns.ref2': 'p${ns.int}s', 'ns.ref3': '${ns.float}', 'ns.ref4': '${ns.bool}', }) assert config.ns.str == 'string' assert config.ns.ref1 == config.get('ns.ref1') == 'prefix string suffix' assert config.ns.ref2 == config.get('ns.ref2') == 'p42s' assert config.ns.ref3 == config.get('ns.ref3') == 2.0 assert config.ns.ref4 == config.get('ns.ref4') is True
def test_missing_reference(): config = Configuration({ 'key': 'string', 'template.working': '${key}', 'template.missing': '${ns.key}', }) assert config.key == 'string' assert config.template.working == 'string' with pytest.raises(ConfiguredReferenceError) as e: assert not config.template.missing assert 'ns.key' in str(e.value) with pytest.raises(ConfiguredReferenceError) as e: assert not config.get('template.missing') assert 'ns.key' in str(e.value)
def test_overwrite_value_with_namespace(): subject = Configuration({'key2': 2, 'namespace': 'namespace'}, {'key1': 1, 'namespace.key1': 1}) assert len(subject) == 3 assert subject.key1 == 1 assert subject.key2 == 2 assert subject.namespace.key1 == 1
def test_single_overwrite(): subject = Configuration({'key1': 1, 'key2': 2}, {'key2': 4, 'key3': 3}) assert len(subject) == 3 assert subject.key1 == 1 assert subject.key2 == 4 assert subject.key3 == 3
def test_missing_reference(): config = Configuration({ 'key': 'string', 'template.working': '${key}', 'template.missing': '${ns.key}', }) assert config.key == 'string' assert config.template.working == 'string' with pytest.raises(ConfiguredReferenceError) as e: assert not config.template.missing assert 'ns.key' in str(e.value) with pytest.raises(ConfiguredReferenceError) as e: assert not config.get('template.missing') assert 'ns.key' in str(e.value)
def test_self_recursion(): config = Configuration({ 'ns.key': '${ns.key}', }) with pytest.raises(ConfigurationError) as e: assert not config.ns.key assert 'ns.key' in str(e.value) and 'recursive' in str(e.value)
def test_multi_level_reference(): config = Configuration({ 'key': 'A ${ns.part1}', 'ns.part1': 'seemingly full, ${ns.part2}.', 'ns.part2': 'complete sentence', }) assert config.ns.part2 == 'complete sentence' assert config.ns.part1 == 'seemingly full, complete sentence.' assert config.key == 'A seemingly full, complete sentence.'
def test_dir(): subject = Configuration({ 'key1': 'value', 'key2': 5, 'namespace.key3': False }) assert 'keys' in dir(subject) assert 'key1' in dir(subject) assert 'namespace' in dir(subject) assert 'key3' in dir(subject.namespace)
def test_not_configured(): subject = Configuration({'key': 'value'}) assert subject.key == 'value' assert subject.does_nope_exist is NotConfigured assert subject.does.nope.exist is NotConfigured assert subject.does_nope_exist is subject.does.nope.exist assert not NotConfigured assert bool(NotConfigured) is False assert (subject.does_not_exist or 'default') == 'default' assert 'not configured' in str(subject.does_nope.exist) assert str(subject.does_nope_exist) == repr(subject.does.nope.exist)
def test_multiple_overwrite(): subject = Configuration({'key1': 1, 'namespace.key1': 1, 'namespace.key2': 2, 'key2': 2}, {'key2': 4, 'key3': 3, 'namespace.key1': 1}, {'key3': 6, 'namespace.key3': 3}) assert len(subject) == 4 assert subject.key1 == 1 assert subject.key2 == 4 assert subject.key3 == 6 assert subject.namespace.key1 == 1 assert subject.namespace.key2 == 2 assert subject.namespace.key3 == 3
def test_value_types(): def run_test(subject, key, expected_type): assert isinstance(subject.get(key), expected_type), 'key {} not of type {}'.format(key, expected_type) run_test(Configuration({'just': 'string'}), 'just', str) run_test(Configuration({'a': 42}), 'a', int) run_test(Configuration({'simple': 3.14}), 'simple', float) run_test(Configuration({'silly': False}), 'silly', bool) run_test(Configuration({'test': [1, 2, 3]}), 'test', Sequence) run_test(Configuration({'case': {'surprise!': None}}), 'case', Mapping) run_test(Configuration({'we_must': {'go_deeper': True}}), 'we_must.go_deeper', bool)
def test_reference_ns(): config = Configuration({ 'key': '${ns}', 'ns.key': 'string', 'broken': 'no ${ns} inside', }) assert config.ns.key == 'string' assert isinstance(config.key, Configuration) assert config.key.key == 'string' with pytest.raises(ConfiguredReferenceError) as e: assert not config.broken assert 'cannot insert namespace' in str(e.value)
def test_as_type(): subject = Configuration({'as_int': 5, 'as_str': '5'}) assert subject.get('as_int') == 5 assert subject.get('as_str') == '5' assert subject.get('as_str', as_type=str) == '5' assert subject.get('as_str', as_type=int) == 5 assert subject.get('as_str', as_type=bool) is True assert subject.get('as_str', as_type=lambda value: int(value) - 2) == 3
def test_collisions(): with patch('confidence.warnings') as warnings: subject = Configuration({ 'key': 'value', 'keys': [1, 2], '_separator': '_' }) for collision in ('keys', '_separator'): warnings.warn.assert_any_call( 'key {key} collides with member of Configuration type, use get() method to ' 'retrieve the value for {key}'.format(key=collision), UserWarning) assert subject.key == 'value' assert callable(subject.keys) assert subject._separator == '.'
def test_value_types(): subject = Configuration({ 'a_string': 'just', 'an_int': 42, 'a_float': 3.14, 'a_boolean': False, 'a_list': [1, 2, 3], 'we_must': { 'go_deeper': True }, }) assert isinstance(subject.a_string, str) assert isinstance(subject.an_int, int) assert isinstance(subject.a_float, float) assert isinstance(subject.a_boolean, bool) assert isinstance(subject.a_list, list) assert isinstance(subject.we_must, Mapping)
def test_assignments(): subject = Configuration({ 'key1': 'value', 'key2': 5, 'namespace.key3': False }) subject._private = 42 subject.__very_private = 43 assert subject._private == 42 assert subject.__very_private == 43 with pytest.raises(AttributeError) as e: subject.non_existent = True assert 'assignment not supported' in str( e.value) and 'non_existent' in str(e.value) with pytest.raises(AttributeError) as e: subject.key1 = True assert 'assignment not supported' in str(e.value) and 'key1' in str( e.value) with pytest.raises(AttributeError) as e: subject.namespace.key3 = True assert 'assignment not supported' in str(e.value) and 'key3' in str( e.value) with pytest.raises(AttributeError) as e: subject.namespace.key4 = True assert 'assignment not supported' in str(e.value) and 'key4' in str( e.value) with pytest.raises(AttributeError) as e: subject.non_existent.key6 = True assert 'assignment not supported' in str(e.value) and 'key6' in str( e.value) with pytest.raises(AttributeError) as e: subject.we.must.go.deeper = True assert 'assignment not supported' in str(e.value) and 'deeper' in str( e.value)
import os from confidence import Configuration from confidence.presets import ProjectPreset, OptionsPreset BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) PROJECT_ROOT = os.path.dirname(os.path.abspath(__file__)) PROJECT_CONF = Configuration.compile_from_presets( os.path.join(PROJECT_ROOT, 'conf/project.conf'), [ ProjectPreset(name='CompanyTracker', version='0.0.1', site_url='http://localhost:8000'), OptionsPreset(secret_key=None, debug=False, allowed_hosts=['127.0.0.1'], database='posrgresql', cache='redis'), ]) SECRET_KEY = PROJECT_CONF.get('options', 'secret_key') DEBUG = PROJECT_CONF.get_bool('options', 'debug') ALLOWED_HOSTS = PROJECT_CONF.get_csv('options', 'allowed_hosts') PROJECT_APPS = [ 'core', ]
def handle(self, *args, **options): option_apply = options.get('apply') option_blank = options.get('blank') config = Configuration(settings.BASE_DIR) if not config.settings or option_blank: settings_dct = dict() filename = input_formatted( 'Enter configuration file name (leave it blank for `config.json`): ' ) or 'config.json' if not filename.endswith('.json'): filename += '.json' settings_dct['filename'] = filename environments = input_formatted( 'Enter your root environment layouts separated by spaces' ' (leave it blank for `development production`): ').split( ) or ['development', 'production'] settings_dct['environments'] = environments config.setup(settings_dct) config.set_filename(filename) else: print_formatted( f'Found already set configuration file name: `{config.settings["filename"]}`.' ) if config.blueprint_exists() and not option_blank: response = input_formatted( f'Found blueprint at {config.blueprint_filepath}. Rewrite? Y/n ' ) if response.lower() not in ['y', 'yes']: print_formatted('Aborting operation.') return # Preset selection / Start print_formatted( 'Choose presets that you want to use in your configuration:') presets = [] idx = 0 for group in config.presets.values(): print_formatted(f'- - - [{group["verbose_name"]}] - - -') for preset in group['items']: presets.append(preset) preset_name = preset.get_full_verbose_name() print_formatted(f'{idx + 1} : {preset_name}', level=1) idx += 1 preset_idxs_spl = input_formatted( 'Enter indices of presets you\'ve chosen separated by spaces: ' ).split() selected_presets = [] for preset_idx in preset_idxs_spl: try: idx = int(preset_idx) - 1 selected_presets.append(presets[idx]) except (IndexError, ValueError) as e: pass # Presets selection / End try: extra_layout = settings.CONFIDENCE_EXTRA_LAYOUT print_formatted( f'Extra layout from CONFIDENCE_EXTRA_LAYOUT setting will be added to blueprint.' ) except AttributeError: extra_layout = None config.initialize(selected_presets, extra_layout=extra_layout) print_formatted( f'Created configuration blueprint at {config.blueprint_filepath}.') if option_apply: config.replicate() print_formatted( f'Created configuration file at {config.filepath}.')
import os from confidence import Configuration BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) PROJECT_ROOT = os.path.dirname(os.path.abspath(__file__)) config = Configuration(BASE_DIR) SECRET_KEY = config.get('environment.secret_key', 'verysecretkey') DEBUG = config.get('environment.debug', True) ALLOWED_HOSTS = config.get('environment.allowed_hosts', []) INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'confidence', ] MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware',