Skip to content

decorator

Module that contains the main decorator, @threshold.

Usage
# main.py
from argmerge import threshold

@threshold
def main(first: int, second: str, third: float = 3.0):
    ...

if __name__ == '__main__':
    main()

Many more examples of how to use this can be found in the Examples section

threshold

threshold(*args, fpath_json='', fpath_yaml='', env_prefix=ENV_PREFIX, cli_pattern=CLI_PATTERN, trace_level='', debug=False, **kwargs)

Merge arguments from external environment sources into the program.

We allow syntax of both @threshold and @threshold(), depending whether you want to allow for defaults or override them.

Parameters:

  • fpath_json (str | Path, default: '' ) –

    The path to find a JSON configuration file. Defaults to "".

  • fpath_yaml (str | Path, default: '' ) –

    The path to find a YAML configuration file. Defaults to "".

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

    The string or Regex to match environment variables against. Defaults to ENV_PREFIX, which is 'THRESH'.

  • cli_pattern (str | Pattern[str], default: CLI_PATTERN ) –

    The string or Regex to match CLI arguments against. Defaults to CLI_PATTERN.

  • trace_level (str, default: '' ) –

    Trace the source of each kwarg and display at the specified trace log level. Defaults to "", which skips the trace entirely.

  • debug (bool, default: False ) –

    Turns on debugging for all the parsers. Defaults to False.

Raises:

  • ValueError

    level must be in one of the default loguru logger levels: ("critical", "warning", "success", "info", "debug")

Returns:

  • callable

    A wrapped, yet-to-be-called function with resolved arguments.

Source code in src/argmerge/decorator.py
 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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
def threshold(
    *args,
    fpath_json: str | Path = "",
    fpath_yaml: str | Path = "",
    env_prefix: str | re.Pattern[str] = ENV_PREFIX,  # 'THRESH', also set at PYTHRESH
    cli_pattern: str | re.Pattern[str] = CLI_PATTERN,
    trace_level: str = "",
    debug: bool = False,
    **kwargs,
):
    """Merge arguments from external environment sources into the program.

    We allow syntax of both @threshold and @threshold(), depending whether you want to
    allow for defaults or override them.

    Args:
        fpath_json (str | Path, optional): The path to find a JSON configuration file.
            Defaults to "".
        fpath_yaml (str | Path, optional): The path to find a YAML configuration file.
            Defaults to "".
        env_prefix (str | re.Pattern[str], optional): The string or Regex to match
            environment variables against. Defaults to ENV_PREFIX, which is 'THRESH'.
        cli_pattern (str | re.Pattern[str], optional): The string or Regex to match
            CLI arguments against. Defaults to CLI_PATTERN.
        trace_level (str, optional): Trace the source of each kwarg and display at the
            specified trace log level. Defaults to "", which skips the trace entirely.
        debug (bool, optional): Turns on debugging for all the parsers.
            Defaults to False.

    Raises:
        ValueError: `level` must be in one of the default loguru logger levels:
            `("critical", "warning", "success", "info", "debug")`

    Returns:
        callable: A wrapped, yet-to-be-called function with resolved arguments.
    """
    if len(args) == 1:
        # allow syntax of @threshold and @threshold()
        return threshold()(args[0])

    else:

        def wrapped(f):
            @functools.wraps(f)
            def wrapped_f(*_args, **_kwargs):
                _threshold_kwargs, _change_ledger = dict(), dict()
                _threshold_kwargs, _change_ledger = parse_func(
                    _threshold_kwargs, _change_ledger, f, debug=debug
                )

                _threshold_kwargs, _change_ledger = parse_json(
                    _threshold_kwargs,
                    _change_ledger,
                    fpath_json=fpath_json,
                    debug=debug,
                )

                _threshold_kwargs, _change_ledger = parse_yaml(
                    _threshold_kwargs,
                    _change_ledger,
                    fpath_yaml=fpath_yaml,
                    debug=debug,
                )

                _threshold_kwargs, _change_ledger = parse_env(
                    _threshold_kwargs,
                    _change_ledger,
                    env_prefix=env_prefix,
                    debug=debug,
                )

                _threshold_kwargs, _change_ledger = parse_cli(
                    _threshold_kwargs,
                    _change_ledger,
                    cli_pattern=cli_pattern,
                    debug=debug,
                )

                _threshold_kwargs, _change_ledger = parse_func_runtime(
                    _threshold_kwargs, _change_ledger, func_kwargs=_kwargs, debug=debug
                )

                if trace_level.lower() in LOG_LEVELS:
                    trace_arg_lineage(
                        f,
                        _change_ledger,
                        level=trace_level,
                    )

                elif trace_level == "":
                    # default behavior
                    pass

                else:
                    raise ValueError(
                        f"'trace_level' has been set to '{trace_level}', which is not "
                        "supported. Please set 'trace_level' to an empty string or one"
                        f" of: {LOG_LEVELS}."
                    )

                return f(*_args, **_threshold_kwargs)

            return wrapped_f

        return wrapped