Skip to content

env

EnvParser

Bases: SourceParser

The parser the extracts relevant environment variables.

Parameters:

  • label (str) –

    The debugging label to indicate an argument was set by environment variables.

  • rank (int) –

    The priority of the parser. Generally, we aim between [0,100] for human-readabilty.

Source code in src/argmerge/env.py
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
class EnvParser(SourceParser):
    """The parser the extracts relevant environment variables.

    Args:
        label (str): The debugging label to indicate an argument was set by environment
            variables.
        rank (int): The priority of the parser. Generally, we aim between [0,100] for
            human-readabilty.
    """

    rank: int = 30
    label: str = "Environment Variable"

    def __call__(
        cls,
        threshold_kwargs: dict[str, Any],
        change_ledger: dict[str, dict[str, str | int]],
        env_prefix: str | re.Pattern[str] = ENV_PREFIX,
        debug=False,
        **kwargs,
    ):
        """Parse the environment variables using the `env_prefix` and update inputs.

        Args:
            threshold_kwargs (dict[str, Any]): kwargs passed around the
                @threshold decorator.
            change_ledger (dict[str, dict[str, str  |  int]]): Tracks when kwargs are
                updated inside the @threshold decorator.
            env_prefix (str | re.Pattern[str], optional): The prefix used to search for
                set environment variables. Defaults to ENV_PREFIX, which is 'THRESH_'.
            debug (bool, optional): Flag to turn on more logging. Defaults to False.

        Raises:
            ValueError: `env_prefix` must either be a string or Regex string pattern.

        Returns:
            tuple[dict, dict]: an updated `threshold_kwargs` and `change_ledger`.
        """
        if debug:
            LOGGER.remove()
            LOGGER.add(sys.stderr, level="DEBUG")

        if isinstance(env_prefix, re.Pattern):
            pattern = env_prefix

        elif isinstance(env_prefix, str):
            pattern = re.compile(rf"(?:{env_prefix.upper()}.)([A-Za-z0\-\_]+)")

        else:
            raise ValueError(
                f"'env_prefix' must be either a string or Regex string pattern. Received: {env_prefix} ({type(env_prefix)})."
            )

        LOGGER.debug(f"{env_prefix=}")
        LOGGER.debug(f"{pattern=}")

        _env_kwargs = {}

        for k, v in os.environ.items():
            _search = pattern.search(k)

            if _search is not None:
                try:
                    key = _search.group(1).lower()
                    LOGGER.debug(f"{key=} {v=}")
                    _env_kwargs[key] = extract_literals(v)

                except IndexError:
                    LOGGER.debug(f"Regex search failed on environment variable {k}.")

            else:
                LOGGER.debug(f"Miss: {k=}")

        LOGGER.debug(f"{_env_kwargs=}")
        threshold_kwargs.update(_env_kwargs)

        LOGGER.debug(f"Updated {threshold_kwargs=}")

        for key in _env_kwargs:
            change_ledger[key] = {"label": cls.label, "rank": cls.rank}

        return threshold_kwargs, change_ledger

__call__

__call__(threshold_kwargs, change_ledger, env_prefix=ENV_PREFIX, debug=False, **kwargs)

Parse the environment variables using the env_prefix and update inputs.

Parameters:

  • threshold_kwargs (dict[str, Any]) –

    kwargs passed around the @threshold decorator.

  • change_ledger (dict[str, dict[str, str | int]]) –

    Tracks when kwargs are updated inside the @threshold decorator.

  • env_prefix (str | Pattern[str], default: ENV_PREFIX ) –

    The prefix used to search for set environment variables. Defaults to ENV_PREFIX, which is 'THRESH_'.

  • debug (bool, default: False ) –

    Flag to turn on more logging. Defaults to False.

Raises:

  • ValueError

    env_prefix must either be a string or Regex string pattern.

Returns:

  • tuple[dict, dict]: an updated threshold_kwargs and change_ledger.

Source code in src/argmerge/env.py
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
def __call__(
    cls,
    threshold_kwargs: dict[str, Any],
    change_ledger: dict[str, dict[str, str | int]],
    env_prefix: str | re.Pattern[str] = ENV_PREFIX,
    debug=False,
    **kwargs,
):
    """Parse the environment variables using the `env_prefix` and update inputs.

    Args:
        threshold_kwargs (dict[str, Any]): kwargs passed around the
            @threshold decorator.
        change_ledger (dict[str, dict[str, str  |  int]]): Tracks when kwargs are
            updated inside the @threshold decorator.
        env_prefix (str | re.Pattern[str], optional): The prefix used to search for
            set environment variables. Defaults to ENV_PREFIX, which is 'THRESH_'.
        debug (bool, optional): Flag to turn on more logging. Defaults to False.

    Raises:
        ValueError: `env_prefix` must either be a string or Regex string pattern.

    Returns:
        tuple[dict, dict]: an updated `threshold_kwargs` and `change_ledger`.
    """
    if debug:
        LOGGER.remove()
        LOGGER.add(sys.stderr, level="DEBUG")

    if isinstance(env_prefix, re.Pattern):
        pattern = env_prefix

    elif isinstance(env_prefix, str):
        pattern = re.compile(rf"(?:{env_prefix.upper()}.)([A-Za-z0\-\_]+)")

    else:
        raise ValueError(
            f"'env_prefix' must be either a string or Regex string pattern. Received: {env_prefix} ({type(env_prefix)})."
        )

    LOGGER.debug(f"{env_prefix=}")
    LOGGER.debug(f"{pattern=}")

    _env_kwargs = {}

    for k, v in os.environ.items():
        _search = pattern.search(k)

        if _search is not None:
            try:
                key = _search.group(1).lower()
                LOGGER.debug(f"{key=} {v=}")
                _env_kwargs[key] = extract_literals(v)

            except IndexError:
                LOGGER.debug(f"Regex search failed on environment variable {k}.")

        else:
            LOGGER.debug(f"Miss: {k=}")

    LOGGER.debug(f"{_env_kwargs=}")
    threshold_kwargs.update(_env_kwargs)

    LOGGER.debug(f"Updated {threshold_kwargs=}")

    for key in _env_kwargs:
        change_ledger[key] = {"label": cls.label, "rank": cls.rank}

    return threshold_kwargs, change_ledger