Skip to content

argparse-tui

Classes

TuiAction

TuiAction(
    option_strings: list[str],
    dest: str = argparse.SUPPRESS,
    default: Any = argparse.SUPPRESS,
    help: str | None = "Open Textual UI.",
    const: str | None = None,
    metavar: str | None = None,
    parent_parser: argparse.ArgumentParser | None = None,
    **_kwargs: Any
)

argparse Action that will analyze the parser and display a TUI.

PARAMETER DESCRIPTION
option_strings

...

TYPE: list[str]

dest

...

TYPE: str DEFAULT: SUPPRESS

default

...

TYPE: Any DEFAULT: SUPPRESS

help

...

TYPE: str | None DEFAULT: 'Open Textual UI.'

const

...

TYPE: str | None DEFAULT: None

metavar

...

TYPE: str | None DEFAULT: None

parent_parser

...

TYPE: ArgumentParser | None DEFAULT: None

Examples:

import argparse
from argparse_tui import TuiAction

parser = argparse.ArgumentParser()
parser.add_argument("--tui", action=TuiAction)
parser.print_usage()

Source code in src/argparse_tui/argparse.py
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
def __init__(
    self,
    option_strings: list[str],
    dest: str = argparse.SUPPRESS,
    default: Any = argparse.SUPPRESS,
    help: str | None = "Open Textual UI.",  # pylint: disable=redefined-builtin # noqa: A002
    const: str | None = None,
    metavar: str | None = None,
    parent_parser: argparse.ArgumentParser | None = None,
    **_kwargs: Any,
):
    super().__init__(
        option_strings=option_strings,
        dest=dest,
        default=default,
        nargs=0,
        help=help,
        const=const,
        metavar=metavar,
    )
    self._parent_parser = parent_parser

Functions

add_tui_argument

add_tui_argument(
    parser: argparse.ArgumentParser,
    parent_parser: argparse.ArgumentParser | None = None,
    option_strings: str | list[str] | None = None,
    help: str = "Open Textual UI.",
    default=argparse.SUPPRESS,
    **kwargs
) -> None
PARAMETER DESCRIPTION
parser

the argparse parser to add the argument to.

TYPE: ArgumentParser

parent_parser

the parent of the given parser.

TYPE: ArgumentParser | None DEFAULT: None

option_strings

list of CLI flags that will invoke the TUI

TYPE: str | list[str] | None DEFAULT: None

help

...

TYPE: str DEFAULT: 'Open Textual UI.'

default

...

DEFAULT: SUPPRESS

**kwargs

passed to parser.add_argument(...)

DEFAULT: {}

Examples:

import argparse
from argparse_tui import add_tui_argument

parser = argparse.ArgumentParser()
add_tui_argument(parser)
parser.print_usage()

Source code in src/argparse_tui/argparse.py
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
def add_tui_argument(
    parser: argparse.ArgumentParser,
    parent_parser: argparse.ArgumentParser | None = None,
    option_strings: str | list[str] | None = None,
    help: str = "Open Textual UI.",  # pylint: disable=redefined-builtin # noqa: A002
    default=argparse.SUPPRESS,
    **kwargs,
) -> None:
    """

    Args:
        parser: the argparse parser to add the argument to.
        parent_parser: the parent of the given parser.
        option_strings: list of CLI flags that will invoke the TUI
        help: ...
        default: ...
        **kwargs: passed to `parser.add_argument(...)`

    Examples:
    ```python
    import argparse
    from argparse_tui import add_tui_argument

    parser = argparse.ArgumentParser()
    add_tui_argument(parser)
    parser.print_usage()
    ```
    """
    if not option_strings:
        option_strings = [f"--{DEFAULT_COMMAND_NAME.replace('_', '-').lstrip('-')}"]
    elif isinstance(option_strings, str):
        option_strings = [option_strings]

    parser.add_argument(
        *option_strings,
        action=TuiAction,
        default=default,
        help=help,
        parent_parser=parent_parser,
        **kwargs,
    )

add_tui_command

add_tui_command(
    parser: argparse.ArgumentParser,
    command: str = DEFAULT_COMMAND_NAME,
    help: str = "Open Textual UI.",
    **kwargs: Any
) -> argparse._SubParsersAction
PARAMETER DESCRIPTION
parser

the argparse parser

TYPE: ArgumentParser

command

name of the CLI command that will invoke the TUI (default=tui)

TYPE: str DEFAULT: DEFAULT_COMMAND_NAME

help

help message for the argument

TYPE: str DEFAULT: 'Open Textual UI.'

**kwargs

if subparsers do not already exist, create with these kwargs.

TYPE: Any DEFAULT: {}

RETURNS DESCRIPTION
_SubParsersAction

The Argparse subparsers action that was discovered or created.

Examples:

import argparse
from argparse_tui import add_tui_command

parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers()
add_tui_command(parser)
parser.print_usage()

Source code in src/argparse_tui/argparse.py
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
def add_tui_command(
    parser: argparse.ArgumentParser,
    command: str = DEFAULT_COMMAND_NAME,
    help: str = "Open Textual UI.",  # pylint: disable=redefined-builtin # noqa: A002
    **kwargs: Any,
) -> argparse._SubParsersAction:
    """

    Args:
        parser: the argparse parser
        command: name of the CLI command that will invoke the TUI (default=`tui`)
        help: help message for the argument
        **kwargs: if subparsers do not already exist, create with these kwargs.

    Returns:
        The Argparse subparsers action that was discovered or created.

    Examples:
    ```python
    import argparse
    from argparse_tui import add_tui_command

    parser = argparse.ArgumentParser()
    subparsers = parser.add_subparsers()
    add_tui_command(parser)
    parser.print_usage()
    ```
    """

    subparsers: argparse._SubParsersAction
    if parser._subparsers is None:
        subparsers = parser.add_subparsers(**kwargs)
    else:
        for action in parser._actions:
            if isinstance(action, argparse._SubParsersAction):
                subparsers = action
                break

    tui_parser = subparsers.add_parser(
        command,
        description=argparse.SUPPRESS,
        help=help,
    )

    add_tui_argument(
        tui_parser,
        parent_parser=parser,
        option_strings=[command],
    )

    return subparsers

build_tui

build_tui(
    parser: argparse.ArgumentParser,
    cli_args: Sequence[str] | None = None,
    subparser_ignorelist: (
        list[argparse.ArgumentParser] | None
    ) = None,
) -> App

Build a Textual UI (TUI) given an argparse parser.

PARAMETER DESCRIPTION
parser

...

TYPE: ArgumentParser

cli_args

Arguments parsed for pre-populating the TUI form.

TYPE: Sequence[str] | None DEFAULT: None

subparser_ignorelist

...

TYPE: list[ArgumentParser] | None DEFAULT: None

RETURNS DESCRIPTION
App

a Textualize App

Examples:

from argparse_tui import build_tui

import argparse
import textual

parser = argparse.ArgumentParser(prog="awesome-app")

parser.add_argument("--value")

app = build_tui(parser)

assert isinstance(app, textual.app.App)

Source code in src/argparse_tui/argparse.py
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
def build_tui(
    parser: argparse.ArgumentParser,
    cli_args: Sequence[str] | None = None,
    subparser_ignorelist: list[argparse.ArgumentParser] | None = None,
) -> App:
    """Build a Textual UI (TUI) given an argparse parser.

    Args:
        parser: ...
        cli_args: Arguments parsed for pre-populating the TUI form.
        subparser_ignorelist: ...

    Returns:
        a Textualize App

    Examples:
    ```python
    from argparse_tui import build_tui

    import argparse
    import textual

    parser = argparse.ArgumentParser(prog="awesome-app")

    parser.add_argument("--value")

    app = build_tui(parser)

    assert isinstance(app, textual.app.App)
    ```
    """

    subcmd_args: list[str]
    parsed_args: dict[str, str]

    if cli_args:
        # Make all args optional
        def _set_actions_optional(
            parser,
            cli_args: list[str] | None = None,
            subcmd_args: list[str] | None = None,
        ) -> list[str]:
            # Update arguments
            for action in parser._actions:
                action.required = False

            # Update subparsers
            sp_actions = parser._subparsers._actions if parser._subparsers else []
            for sp_action in sp_actions:
                sp_action.required = False
                if isinstance(sp_action, argparse._SubParsersAction):
                    found_subcmd: bool = False
                    for subcmd, subparser in sp_action.choices.items():
                        if found_subcmd:
                            _set_actions_optional(subparser)
                            continue

                        try:
                            if not cli_args:
                                raise ValueError
                            subcmd_index: int = cli_args.index(subcmd)
                        except ValueError:
                            _set_actions_optional(subparser)
                        else:
                            found_subcmd = True
                            subcmd_args.append(subcmd)
                            _set_actions_optional(
                                subparser,
                                cli_args=cli_args[(subcmd_index + 1) :],
                                subcmd_args=subcmd_args,
                            )

            return subcmd_args

        parser_copy: argparse.ArgumentParser = deepcopy(parser)
        subcmd_args = _set_actions_optional(
            parser_copy,
            cli_args=cli_args,
            subcmd_args=[],
        )

        with suppress(SystemExit):
            namespace, _unknown_args = parser_copy.parse_known_args(cli_args)
            parsed_args = vars(namespace)
    else:
        subcmd_args = []
        parsed_args = {}

    schemas = introspect_argparse_parser(
        parser,
        subparser_ignorelist=subparser_ignorelist,
        value_overrides=parsed_args,
    )

    return Tui(schemas, app_name=parser.prog, subcommand_filter=subcmd_args)

invoke_tui

invoke_tui(
    parser: argparse.ArgumentParser,
    cli_args: Sequence[str] | None = None,
    subparser_ignorelist: (
        list[argparse.ArgumentParser] | None
    ) = None,
) -> None

Invoke a Textual UI (TUI) given an argparse parser.

PARAMETER DESCRIPTION
parser

...

TYPE: ArgumentParser

cli_args

Arguments parsed for pre-populating the TUI form.

TYPE: Sequence[str] | None DEFAULT: None

subparser_ignorelist

...

TYPE: list[ArgumentParser] | None DEFAULT: None

Examples:

import argparse
from argparse_tui import invoke_tui

parser = argparse.ArgumentParser(prog="awesome-app")

parser.add_argument("--value")

# invoke_tui(parser)

Source code in src/argparse_tui/argparse.py
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
def invoke_tui(
    parser: argparse.ArgumentParser,
    cli_args: Sequence[str] | None = None,
    subparser_ignorelist: list[argparse.ArgumentParser] | None = None,
) -> None:
    """Invoke a Textual UI (TUI) given an argparse parser.

    Args:
        parser: ...
        cli_args: Arguments parsed for pre-populating the TUI form.
        subparser_ignorelist: ...

    Examples:
    ```python
    import argparse
    from argparse_tui import invoke_tui

    parser = argparse.ArgumentParser(prog="awesome-app")

    parser.add_argument("--value")

    # invoke_tui(parser)
    ```
    """
    app: App = build_tui(
        parser=parser,
        cli_args=cli_args,
        subparser_ignorelist=subparser_ignorelist,
    )
    app.run()