Skip to content

cli_tools

PROCESS I/O CLI

help_opt = click.help_option('-h', '--help') module-attribute

scan_opt = click.option('--scan', type=int, help='Scan to select') module-attribute

mfile_arg = click.argument('mfiles', nargs=(-1), type=(click.Path(exists=True, path_type=Path))) module-attribute

LazyGroup

Bases: Group

Lazily load click command groups to reduce cli load times

We dont import all things unless required

Source code in process/core/io/cli_tools.py
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
class LazyGroup(click.Group):
    """Lazily load click command groups to reduce cli load times


    We dont import all things unless required
    """

    def __init__(self, *args, lazy_subcommands=None, **kwargs):
        super().__init__(*args, **kwargs)
        # lazy_subcommands is a map of the form:
        #
        #   {command-name} -> {module-name}.{command-object-name}
        #
        self.lazy_subcommands = lazy_subcommands or {}

    def list_commands(self, ctx):
        """List available commands"""
        base = super().list_commands(ctx)
        lazy = sorted(self.lazy_subcommands.keys())
        return sorted(base + lazy)

    def get_command(self, ctx, cmd_name):
        """Get available commands"""
        if cmd_name in self.lazy_subcommands:
            return self._lazy_load(cmd_name)
        return super().get_command(ctx, cmd_name)

    def _lazy_load(self, cmd_name):
        # lazily loading a command, first get the module name and attribute name
        import_path = self.lazy_subcommands[cmd_name]
        modname, cmd_object_name = import_path.rsplit(".", 1)
        # do the import
        mod = importlib.import_module(modname)
        # get the Command object from that module
        cmd_object = getattr(mod, cmd_object_name)
        # check the result to make debugging easier
        if not isinstance(cmd_object, click.Command):
            raise ValueError(  # noqa: TRY004
                f"Lazy loading of {import_path} failed by returning a non-command object"
            )
        return cmd_object

lazy_subcommands = lazy_subcommands or {} instance-attribute

list_commands(ctx)

List available commands

Source code in process/core/io/cli_tools.py
65
66
67
68
69
def list_commands(self, ctx):
    """List available commands"""
    base = super().list_commands(ctx)
    lazy = sorted(self.lazy_subcommands.keys())
    return sorted(base + lazy)

get_command(ctx, cmd_name)

Get available commands

Source code in process/core/io/cli_tools.py
71
72
73
74
75
def get_command(self, ctx, cmd_name):
    """Get available commands"""
    if cmd_name in self.lazy_subcommands:
        return self._lazy_load(cmd_name)
    return super().get_command(ctx, cmd_name)

mfile_opt(exists=False)

Click option for an mfile filepath

Source code in process/core/io/cli_tools.py
15
16
17
18
19
20
21
22
23
24
def mfile_opt(exists: bool = False):
    """Click option for an mfile filepath"""
    return click.option(
        "-f",
        "--mfile",
        "mfile",
        default="MFILE.DAT",
        type=click.Path(exists=exists, path_type=Path),
        help="The mfile to read",
    )

indat_opt(default='IN.DAT', exists=True)

Click option for an indat filepath

Source code in process/core/io/cli_tools.py
27
28
29
30
31
32
33
34
35
36
def indat_opt(default="IN.DAT", exists=True):
    """Click option for an indat filepath"""
    return click.option(
        "-i",
        "--input",
        "indat",
        type=click.Path(exists, path_type=Path),
        help="The path to the input file",
        default=default,
    )

save(help_)

Click save option

Source code in process/core/io/cli_tools.py
39
40
41
def save(help_):
    """Click save option"""
    return click.option("-s", "--save", "save", default=False, is_flag=True, help=help_)

split_callback(ctx, param, value)

Callback to split a string on spaces and colons

Source code in process/core/io/cli_tools.py
44
45
46
def split_callback(ctx: click.Context, param, value: str | None) -> list[str] | None:  # noqa: ARG001
    """Callback to split a string on spaces and colons"""
    return value.replace(" ", ":").split(":") if isinstance(value, str) else value