def test_from_env_one_dash_separator(): os.environ["AWS_DEFAULT_REGION"] = "us-east-1" config = from_env(separator="_") with pytest.raises(AssertionError): assert config.aws.default.region == "us-east-1" assert config.AWS.DEFAULT.REGION == "us-east-1" config = from_env(separator="_").lower(True) with pytest.raises(AssertionError): assert config.AWS.DEFAULT.REGION == "us-east-1" assert config.aws.default.region == "us-east-1"
def __init__(self): super().__init__( self.defaults, ilexconf.from_json(Config.defaults.config, ignore_errors=True), ilexconf.from_env(prefix="WUTCH_"), ilexconf.from_argparse(self._parse_arguments()), )
def test_from_env_basic(): os.environ["AWS_DEFAULT_REGION"] = "us-east-1" # from ilexconf.tests.debug import debug # debug() # Prefix = AWS_ # Separator = __ # Lowercase = True config = from_env(prefix="AWS_", separator="__").lower(inplace=True) assert dict(config) == {"default_region": "us-east-1"} # Prefix = "" (empty) # Separator = "" # Lowercasee = False (default) # TODO: Tell about environment variables dashes converted to underscores in docs config = from_env() assert config.AWS_DEFAULT_REGION == "us-east-1"
def test_from_env_no_prefix(): os.environ["AWS_DEFAULT_REGION"] = "us-east-1" # debug() config = from_env(separator="_").lower(True) with pytest.raises(AssertionError): # Should raise error, because correct key is config.aws.deault.region assert config.default.region == "us-east-1" assert config.aws.default.region == "us-east-1" config = from_env().lower(True) assert config.aws_default_region == "us-east-1" config = from_env(prefix=None).lower(True) assert config.aws_default_region == "us-east-1" config = from_env() with pytest.raises(AssertionError): # Should raise error, because correct key is uppercase assert config.aws_default_region == "us-east-1" assert config.AWS_DEFAULT_REGION == "us-east-1"
def test_from_env_no_separator(): os.environ["AWS_DEFAULT_REGION"] = "us-east-1" config = from_env(prefix="_").lower(True) with pytest.raises(AssertionError): assert config.aws_default_region == "whatever" assert config.aws_default_region == Config() config = from_env(separator="").lower(True) with pytest.raises(AssertionError): assert config.AWS_DEFAULT_REGION == "us-east-1" assert config.aws_default_region == "us-east-1" config = from_env(separator=None) with pytest.raises(AssertionError): assert config.aws_default_region == "us-east-1" assert config.AWS_DEFAULT_REGION == "us-east-1" config = from_env() with pytest.raises(AssertionError): assert config.aws_default_region == "us-east-1" assert config.AWS_DEFAULT_REGION == "us-east-1"
def test_to_env_current_context(): os.environ["AWS_DEFAULT_REGION"] = "us-east-1" config = from_env().lower(True) config.aws_default_region = "us-east-2" to_env(config.upper(), prefix="") assert os.environ["AWS_DEFAULT_REGION"] == "us-east-2" to_env(config.lower(), prefix="MY") assert os.environ["MYaws_default_region"] == "us-east-2" to_env(config, prefix="mY_") assert os.environ["mY_aws_default_region"] == "us-east-2" to_env(config.upper(), prefix="MY_") with pytest.raises(KeyError): # Should not exist because MY_ is prefix assert os.environ["MY__AWS_DEFAULT_REGION"] == "us-east-2" assert os.environ["MY_AWS_DEFAULT_REGION"] == "us-east-2"
def test_quick_start( settings_json_dict, settings_json_file_path, resulting_dict, tmp_path ): # os.putenv("AWS_DEFAULT_REGION", "us-east-1") os.environ["AWS_DEFAULT_REGION"] = "us-east-1" # [create] from ilexconf import Config, from_json, from_env, to_json # Empty config config = Config() assert dict(config) == {} # Create config from json and merge it into our initial config # Let settings_json_file_path = "settings.json" where inside the file we have # { "database": { "connection": { "host": "localhost", "port": 5432 } } } config.merge(from_json(settings_json_file_path)) assert dict(config) == { "database": {"connection": {"host": "localhost", "port": 5432}} } # Merge dict into config config.merge({"database": {"connection": {"host": "test.local"}}}) assert dict(config) == { "database": {"connection": {"host": "test.local", "port": 5432}} } # Merge environment variables into config config.merge(from_env(prefix="AWS_", separator="__").lower(inplace=True)) assert dict(config) == { "database": {"connection": {"host": "test.local", "port": 5432}}, "default_region": "us-east-1", } # Merge keyword arguments config.set("my__keyword__argument", True, key_sep="__") assert dict(config) == { "database": {"connection": {"host": "test.local", "port": 5432}}, "default_region": "us-east-1", "my": {"keyword": {"argument": True}}, } # Clear values, just like with dict config.clear() assert dict(config) == {} # Or, better yet, do this all in one step, since Config() constructor # accepts any number of mapping objects and keyword arguments as # initialization parameters. However, order of parameters matters. # Last mappings are merged on top of others. And keywords override even that. config = Config( from_json(settings_json_file_path), {"database": {"connection": {"host": "test.local"}}}, database__connection__port=4000, ) assert dict(config) == { "database": {"connection": {"host": "test.local", "port": 4000}} } # [create] # from ilexconf import ( # from_json, # # from_yaml, # # from_toml, # from_ini, # # from_python, # # from_dotenv, # from_env, # ) # [read] cfg1 = from_json(settings_json_file_path) assert dict(cfg1) == { "database": {"connection": {"host": "localhost", "port": 5432}} } # [read] # cfg2 = Config( # from_yaml("settings.yaml"), # from_toml("settings.toml") # ) # cfg3 = Config( # from_ini("settings.ini"), # from_python("settings.py"), # from_dotenv(".env"), # from_env() # ) # [access] # Classic way assert config["database"]["connection"]["host"] == "test.local" # Dotted key notation assert config["database.connection.host"] == "test.local" # Via attributes assert config.database.connection.host == "test.local" # Any combination of the above assert config["database"].connection.host == "test.local" assert config.database["connection.host"] == "test.local" assert config.database["connection"].host == "test.local" assert config.database.connection["host"] == "test.local" # [access] # [upsert] # Change value that already exists in the dictionary # just like you would do with simple dict config["database"]["connection"]["port"] = 8080 assert config["database"]["connection"]["port"] == 8080 # Create new value using 'dotted notation'. Notice that # 'user' field did not exist before. config["database.connection.user"] = "******" assert config["database.connection.user"] == "root" # Create new value using. 'password' field did not exist # before we assigned a value to it and was created automatically. config.database.connection.password = "******" assert config.database.connection.password == "secret stuff" # [upsert] # [merge] # Config correctly merges nested values. Notice how it overrides # the value of the 'password' key in the nested 'connection' config # from 'secret stuff' to 'different secret' config.database.connection.merge({"password": "******"}) assert config.database.connection.password == "different secret" # [merge] # [smart-merge] merged = Config( {"a1": {"c1": 1, "c2": 2, "c3": 3}}, {"a1": {"c3": "other"}} ) # Instead of overriding the value of the "a1" key completely, `merge` method # will recursively look inside and merge nested values. assert dict(merged) == {"a1": {"c1": 1, "c2": 2, "c3": "other"}} # [smart-merge] # [as-dict] assert dict(config) == { "database": { "connection": { "host": "test.local", "port": 8080, "user": "******", "password": "******", } } } # [as-dict] # [write] # Temporary path p = tmp_path / "settings.json" # Save config to_json(config, p) # Verify written file is correct assert dict(from_json(p)) == { "database": { "connection": { "host": "test.local", "port": 8080, "user": "******", "password": "******", } } } # [write] # [subclass] class MyConfig(Config): def __init__(self, do_stuff=False): # Initialize your custom config using json settings file super().__init__(from_json(settings_json_file_path)) # Add some custom value depending on some logic if do_stuff: # Here, we create new nested key that did not exist # before and assign a value to it. self.my.custom.key = "Yes, do stuff" # Merge one more mapping on top self.merge({"Horizon": "Up"}) # [subclass] # [test-subclass] # Now you can use your custom defined Config. Given the `setting.json` file that # contains { "database": { "connection": { "host": "localhost", "port": 5432 } } } # MyConfig will have the following values: config = MyConfig(do_stuff=True) assert dict(config) == { "database": { "connection": { "host": "localhost", "port": 5432, }, }, "Horizon": "Up", "my": {"custom": {"key": "Yes, do stuff"}}, }