Exemple #1
0
 def test_returns_unmodified_if_no_variable_references(self):
     config = {
         collections.CompoundKey(["a", "b"]): "foo",
         collections.CompoundKey(["a"]): "bar",
     }
     replaced = replace_variable_references(config)
     assert config == replaced
Exemple #2
0
    def test_replaces_root_variable(self):
        config = {
            collections.CompoundKey(["a"]): "${b}",
            collections.CompoundKey(["b"]): "foo",
        }
        replaced = replace_variable_references(config)

        assert (replaced[collections.CompoundKey(
            ["a"])] == replaced[collections.CompoundKey(["b"])])
Exemple #3
0
 def test_chained_variables(self):
     config = {
         collections.CompoundKey(["a"]): "${b}",
         collections.CompoundKey(["b"]): "${c}",
         collections.CompoundKey(["c"]): "bar",
     }
     replaced = replace_variable_references(config)
     for value in replaced.values():
         assert value == "bar"
Exemple #4
0
    def test_replaces_from_root_to_nested_keys(self):
        config = {
            collections.CompoundKey(["a"]): "${a.b}",
            collections.CompoundKey(["a", "b"]): "foo",
        }
        replaced = replace_variable_references(config)

        assert (replaced[collections.CompoundKey(
            ["a"])] == replaced[collections.CompoundKey(["a", "b"])])
Exemple #5
0
    def test_doesnt_modify_input(self):
        config = {
            collections.CompoundKey(["a", "b"]): "foo",
            collections.CompoundKey(["a"]): "${a.b}",
        }
        before_config = {
            collections.CompoundKey(["a", "b"]): "foo",
            collections.CompoundKey(["a"]): "${a.b}",
        }
        replaced = replace_variable_references(config)

        assert config == before_config
        assert config != replaced
Exemple #6
0
    def test_array_replacement_missing_variable(self):
        config = {
            collections.CompoundKey(["a"]): "foo",
            collections.CompoundKey(["b"]): ["${a}", "${a}", "${c}"],
        }

        replaced = replace_variable_references(config)

        assert replaced[collections.CompoundKey(["b"])] == [
            replaced[collections.CompoundKey(["a"])],
            replaced[collections.CompoundKey(["a"])],
            "",
        ]
Exemple #7
0
    def check_and_replace(flat_config: dict, value: str) -> Optional[str]:
        match = INTERPOLATION_REGEX.search(value)
        if not match:
            return None

        # the matched_string includes "${}"; the matched_key is just the inner value
        matched_string = match.group(0)
        matched_key = match.group(1)

        # get the referenced key from the config value
        ref_key = collections.CompoundKey(matched_key.split("."))
        # get the value corresponding to the referenced key
        ref_value = flat_config.get(ref_key, "")

        # The configuration's value was just a reference and nothing else
        if value == matched_string:
            return ref_value

        # The reference wasn't a valid reference, so to maintain consistency
        # with the rest of the config API, a missing reference returns an
        # empty string

        # The value could either have multiple references, or
        # be used to interpolate a larger string, such
        # as a database URI or API request header
        # Ex1) "postgresql+psycopg2://${username}:${password}@{host}:${port}/${dbname}"
        # Ex2) "Bearer ${api_token}"
        return value.replace(matched_string, str(ref_value), 1)
Exemple #8
0
def load_environment_variables(
    env_var_prefix: str,
) -> Dict[collections.CompoundKey, Any]:

    flat_config = {}

    for env_var, env_var_value in os.environ.items():
        if not env_var.startswith(env_var_prefix + "__"):
            continue

        # Strips the prefix off the environment variable
        env_var_option = env_var[len(env_var_prefix + "__") :]

        # Make sure the result has at least one delimited section
        # with a key
        if "__" not in env_var:
            continue

        # Env vars with escaped characters are interpreted as a
        # literal "\", which Python helpfuly escaped with a second "\".
        # This step makes sure that the escaped characters are properly
        # interpreted.
        value = cast(str, env_var_value.encode().decode("unicode_escape"))

        # Place the environment variable into the flat config
        # as the compound key
        config_option = collections.CompoundKey(env_var_option.lower().split("__"))
        flat_config[config_option] = string_to_type(
            cast(str, interpolate_env_vars(value))
        )

    return flat_config
Exemple #9
0
 def test_replaces_multiple_existing_variables(self):
     config = {
         collections.CompoundKey(["a"]): "${b}",
         collections.CompoundKey(["b"]): "foo",
         collections.CompoundKey(["c"]): "bar",
         collections.CompoundKey(["d"]): "${c}",
     }
     replaced = replace_variable_references(config)
     assert (replaced[collections.CompoundKey(
         ["a"])] == replaced[collections.CompoundKey(["b"])])
     assert (replaced[collections.CompoundKey(
         ["c"])] == replaced[collections.CompoundKey(["d"])])
Exemple #10
0
 def test_single_key_multiple_variables(self):
     same_values = "${b}-${b}"
     different_values = "${b}-${c}"
     config = {
         collections.CompoundKey(["a"]): same_values,
         collections.CompoundKey(["d"]): different_values,
         collections.CompoundKey(["b"]): "foo",
         collections.CompoundKey(["c"]): "bar",
     }
     replaced = replace_variable_references(config)
     assert replaced[collections.CompoundKey(
         ["a"])] == "{val}-{val}".format(
             val=replaced[collections.CompoundKey(["b"])])
     assert replaced[collections.CompoundKey(["d"])] == "{b}-{c}".format(
         b=replaced[collections.CompoundKey(["b"])],
         c=replaced[collections.CompoundKey(["c"])],
     )
Exemple #11
0
 def test_bad_reference_returns_empty_string(self):
     config = {
         collections.CompoundKey(["a"]): "${b}",
         collections.CompoundKey(["c"]): "bar",
         collections.CompoundKey(["d"]): "${c}",
     }
     replaced = replace_variable_references(config)
     assert replaced[collections.CompoundKey(["a"])] == ""
     # not modifying the other, valid entries
     assert replaced[collections.CompoundKey(["c"])] == "bar"
     assert (replaced[collections.CompoundKey(
         ["d"])] == replaced[collections.CompoundKey(["c"])])
def test_flatten_dict(nested_dict):
    flat = collections.dict_to_flatdict(nested_dict)
    assert flat == {
        collections.CompoundKey([1]): 2,
        collections.CompoundKey([2, 1]): 2,
        collections.CompoundKey([2, 3]): 4,
        collections.CompoundKey([3, 1]): 2,
        collections.CompoundKey([3, 3, 4]): 5,
        collections.CompoundKey([3, 3, 6, 7]): 8,
    }
Exemple #13
0
    def test_variable_reference_from_array(self):
        config = {
            collections.CompoundKey(["a"]): "foo",
            collections.CompoundKey(["b"]): ["${a}", "${a}", "${a}"],
        }

        replaced = replace_variable_references(config)
        assert replaced[collections.CompoundKey(["b"])] == [
            replaced[collections.CompoundKey(["a"])],
            replaced[collections.CompoundKey(["a"])],
            replaced[collections.CompoundKey(["a"])],
        ]
Exemple #14
0
 def test_self_reference_doesnt_cause_recursion_error(self):
     config = {
         collections.CompoundKey(["a"]): "${a}",
     }
     replaced = replace_variable_references(config)
     assert config == replaced