# API

class cyclopts.App(name: str | Iterable[str] | None = None, help: str | None = None, usage: str | None = None, *, alias: str | Iterable[str] | None = None, synonym: str | Iterable[str] | None = None, default_command: Callable[[...], Any] | None = None, default_parameter: Parameter | None = None, config: _ConfigCallable | Iterable[_ConfigCallable] | None = None, version: None | str | Callable[[...], str] | Callable[[...], Coroutine[Any, Any, str]] = None, version_flags: str | Iterable[str] | None = ['--version'], show: bool = True, console: Console | None = None, error_console: Console | None = None, help_flags: str | Iterable[str] | None = ['--help', '-h'], help_format: Literal['markdown', 'md', 'plaintext', 'restructuredtext', 'rst', 'rich'] | None = None, help_on_error: bool | None = None, help_prologue: str | None = None, help_epilogue: str | None = None, version_format: Literal['markdown', 'md', 'plaintext', 'restructuredtext', 'rst', 'rich'] | None = None, group: Group | str | Iterable[Group | str] | None = None, group_arguments: None | str | Group = None, group_parameters: None | str | Group = None, group_commands: None | str | Group = None, validator: Callable[[...], Any] | Iterable[Callable[[...], Any]] | None = None, name_transform: Callable[[str], str] | None = None, sort_key: Any = None, end_of_options_delimiter: str | None = None, print_error: bool | None = None, exit_on_error: bool | None = None, verbose: bool | None = None, suppress_keyboard_interrupt: bool = True, backend: Literal['asyncio', 'trio'] | None = None, help_formatter: None | Literal['default', 'plain'] | HelpFormatter = None, error_formatter: Callable[[CycloptsError], Any] | None = None, result_action: ResultAction | ResultActionSingle | None = None)

  Cyclopts Application.

  name: str | Iterable[str] | None = None

    Name of application, or subcommand if registering to another application. Name resolution order:

    1. User specified `name` parameter.

    2. If a `default` function has been registered, the name of that function.

    3. If the module name is `__main__.py`, the name of the encompassing package.

    4. The value of `sys.argv[0]`; i.e. the name of the python script.

    Multiple names can be provided in the case of a subcommand, but this is relatively unusual.

    Special value `"*"` can be used when registering sub-apps with `command()` to flatten all commands from the sub-app into the parent app. See Flattening SubCommands for details.

    Example:

        from cyclopts import App

        app = App()
        app.command(App(name="foo"))

        @app["foo"].command
        def bar():
            print("Running bar.")

        app()

        $ my-script foo bar
        Running bar.

  alias: str | Iterable[str] | None = None

    Extends `name` with additional names. Unlike `name`, this does not override Cyclopts-derived names.

        from cyclopts import App

        app = App()

        @app.command(alias="bar")
        def foo():
            print("Running foo.")

        app()

        $ my-script foo
        Running bar.

        $ my-script bar
        Running bar.

  synonym: str | Iterable[str] | None = None

    Alternate names that trigger a "Did you mean..." suggestion when typed, but do not register the command under those names.

    Unlike `alias`, synonyms are not runnable and are hidden from `--help`. They exist to guide users who type a semantically equivalent but orthographically dissimilar token that Cyclopts' fuzzy matcher would otherwise miss (e.g., `remove` when the command is `uninstall`).

        from cyclopts import App

        app = App()

        @app.command(synonym=["remove", "rm"])
        def uninstall(name: str):
            print(f"uninstalling {name}")

        app()

        $ my-script uninstall mypackage
        uninstalling mypackage

        $ my-script remove mypackage
        Unknown command "remove". Did you mean "uninstall"? Available commands: uninstall.

    See Synonyms for details.

  help: str | None = None

    Text to display on help screen. If not supplied, fallbacks to parsing the docstring of function registered with `App.default()`.

        from cyclopts import App

        app = App(help="This is my help string.")
        app()

        $ my-script --help
        Usage: scratch.py COMMAND

        This is my help string.

        ╭─ Commands ────────────────────────────────────────────────────────────╮
        │ --help -h  Display this message and exit.                             │
        │ --version  Display application version.                               │
        ╰───────────────────────────────────────────────────────────────────────╯

  help_flags: str | Iterable[str] = ("--help", "-h")

    CLI flags that trigger `help_print()`. Set to an empty list to disable this feature. Defaults to `["--help", "-h"]`.

  help_format: Literal['plaintext', 'markdown', 'md', 'restructuredtext', 'rst'] | None = None

    The markup language used in function docstring. If `None`, fallback to parenting `help_format`. If no `help_format` is defined, falls back to `"markdown"`.

  help_formatter: None | Literal['default', 'plain'] | HelpFormatter = None

    Help formatter to use for rendering help panels.

    - If `None` (default), inherits from parent `App`, eventually defaulting to `DefaultFormatter`.

    - If `"default"`, uses `DefaultFormatter`.

    - If `"plain"`, uses `PlainFormatter` for no-frills plain text output.

    - If a callable (see `HelpFormatter` protocol), uses the provided formatter.

    Example:

        from cyclopts import App
        from cyclopts.help import DefaultFormatter, PlainFormatter, PanelSpec

        # Use plain text formatter
        app = App(help_formatter="plain")

        # Use default formatter with customization
        app = App(help_formatter=DefaultFormatter(
            panel_spec=PanelSpec(border_style="blue")
        ))

    See Help Customization for detailed examples and advanced usage.

  help_prologue: str | None = None

    Text to display at the beginning of the help screen, before the usage section. If `None`, no prologue is displayed. If not set, attempts to inherit from parenting `App`.

    The prologue supports the same formatting as `help` based on `help_format` (markdown, plaintext, restructuredtext, or rich).

    Example:

        from cyclopts import App

        app = App(
            name="myapp",
            help="My application help.",
            help_prologue=f"myapp, v1.0.0 (http://example.myapp.com)"
        )
        app()

        $ my-script --help
        myapp, v1.0.0 (http://example.myapp.com)

        Usage: myapp COMMAND

        My application help.

        ╭─ Commands ────────────────────────────────────────────────────────────╮
        │ --help -h  Display this message and exit.                             │
        │ --version  Display application version.                               │
        ╰───────────────────────────────────────────────────────────────────────╯

  help_epilogue: str | None = None

    Text to display at the end of the help screen, after all help panels. Commonly used for version information, contact details, or additional notes. If `None`, no epilogue is displayed. If not set, attempts to inherit from parenting `App`.

    The epilogue supports the same formatting as `help` based on `help_format` (markdown, plaintext, restructuredtext, or rich).

    Example:

        from cyclopts import App

        app = App(
            name="myapp",
            help="My application help.",
            help_epilogue="Support: support@example.com"
        )
        app()

        $ my-script --help
        Usage: myapp COMMAND

        My application help.

        ╭─ Commands ────────────────────────────────────────────────────────────╮
        │ --help -h  Display this message and exit.                             │
        │ --version  Display application version.                               │
        ╰───────────────────────────────────────────────────────────────────────╯

        Support: support@example.com

  help_on_error: bool | None = None

    Prints the help-page before printing an error. If not set, attempts to inherit from parenting `App`, eventually defaulting to `False`.

  print_error: bool | None = None

    Print a rich-formatted error on error. If not set, attempts to inherit from parenting `App`, eventually defaulting to `True`.

  exit_on_error: bool | None = None

    If there is an error parsing the CLI tokens, invoke `sys.exit(1)`. Otherwise, continue to raise the exception. If not set, attempts to inherit from parenting `App`, eventually defaulting to `True`.

  verbose: bool | None = None

    Populate exception strings with more information intended for developers. If not set, attempts to inherit from parenting `App`, eventually defaulting to `False`.

  error_formatter: Callable[[CycloptsError], Any] | None = None

    A callable that formats `CycloptsError` exceptions for display. The callable receives the exception and should return any Rich-printable object (string, `Text`, `Panel`, etc.). If not set, attempts to inherit from parenting `App`, eventually defaulting to `CycloptsPanel()`.

    See Custom Error Formatting for examples.

  version_format: Literal['plaintext', 'markdown', 'md', 'restructuredtext', 'rst'] | None = None

    The markup language used in the version string. If `None`, fallback to parenting `version_format`. If no `version_format` is defined, falls back to resolved `help_format`.

  usage: str | None = None

    Text to be displayed in lieue of the default `Usage: app COMMAND ...` at the beginning of the help-page. Set to an empty-string `""` to disable showing the default usage.

  show: bool = True

    Show this command on the help screen. Hidden commands (`show=False`) are still executable.

        from cyclopts import App
        app = App()

        @app.command
        def foo():
           print("Running foo.")

        @app.command(show=False)
        def bar():
           print("Running bar.")

        app()

        $ my-script foo
        Running foo.

        $ my-script bar
        Running bar.

        $ my-script --help
        Usage: scratch.py COMMAND

        ╭─ Commands ─────────────────────────────────────────────────╮
        │ foo                                                        │
        │ --help -h  Display this message and exit.                  │
        │ --version  Display application version.                    │
        ╰────────────────────────────────────────────────────────────╯

  sort_key: Any = None

    Modifies command display order on the help-page.

    1. If `sort_key` is a generator, it will be consumed immediately with `next()` to get the actual value.

    2. If `sort_key`, or any of it's contents, are `Callable`, then invoke it `sort_key(app)` and apply the returned value to (3) if `None`, (4) otherwise.

    3. For all commands with `sort_key==None` (default value), sort them alphabetically. These sorted commands will be displayed after `sort_key != None` list (see 4).

    4. For all commands with `sort_key!=None`, sort them by `(sort_key, app.name)`. It is the user's responsibility that `sort_key` s are comparable.

    Example usage:

        from cyclopts import App

        app = App()

        @app.command  # sort_key not specified; will be sorted AFTER bob/charlie.
        def alice():
            """Alice help description."""

        @app.command(sort_key=2)
        def bob():
            """Bob help description."""

        @app.command(sort_key=1)
        def charlie():
            """Charlie help description."""

        app()

    Resulting help-page:

        Usage: demo.py COMMAND

        ╭─ Commands ──────────────────────────────────────────────────╮
        │ charlie    Charlie help description.                        │
        │ bob        Bob help description.                            │
        │ alice      Alice help description.                          │
        │ --help -h  Display this message and exit.                   │
        │ --version  Display application version.                     │
        ╰─────────────────────────────────────────────────────────────╯

    Using generators (e.g., `itertools.count()`):

        import itertools
        from cyclopts import App

        app = App()
        counter = itertools.count()

        @app.command(sort_key=counter)
        def beta():
            """Beta help description."""

        @app.command(sort_key=counter)
        def alpha():
            """Alpha help description."""

        app()

        Usage: demo.py COMMAND

        ╭─ Commands ──────────────────────────────────────────────────╮
        │ beta       Beta help description.                           │
        │ alpha      Alpha help description.                          │
        │ --help -h  Display this message and exit.                   │
        │ --version  Display application version.                     │
        ╰─────────────────────────────────────────────────────────────╯

  version: None | str | Callable = None

    Version to be displayed when a `version_flags` is parsed. Defaults to the version of the package instantiating `App`. If a `Callable`, it will be invoked with no arguments when version is queried.

  version_flags: str | Iterable[str] = ("--version",)

    Token(s) that trigger `version_print()`. Set to an empty list to disable version feature. Defaults to `["--version"]`.

  console: Console = None

    Default `Console` to use when displaying runtime messages. Cyclopts console resolution is as follows:

    1. Any explicitly passed in console to methods like `App.__call__()`, `App.parse_args()`, etc.

    2. The relevant subcommand's `App.console` attribute, if not `None`.

    3. The parenting `App.console` (and so on), if not `None`.

    4. If all values are `None`, then the default `Console` is used.

  error_console: Console = None

    Default `Console` to use when displaying error messages. Cyclopts error_console resolution is as follows:

    1. Any explicitly passed in error_console to methods like `App.__call__()`, `App.parse_args()`, etc.

    2. The relevant subcommand's `App.error_console` attribute, if not `None`.

    3. The parenting `App.error_console` (and so on), if not `None`.

    4. If all values are `None`, then a default `Console` with `stderr=True` is used.

    This separation of error output from normal output follows Unix conventions, allowing users to redirect error messages independently from normal output (e.g., `program > output.txt 2> errors.txt`).

  default_parameter: Parameter = None

    Default `Parameter` configuration. Unspecified values of command-annotated `Parameter` will inherit these values. See Default Parameter for more details.

  group: None | str | Group | Iterable[str | Group] = None

    The group(s) that `default_command` belongs to.

    - If `None`, defaults to the `"Commands"` group.

    - If `str`, use an existing `Group` (from neighboring sub-commands) with name, or create a `Group` with provided name if it does not exist.

    - If `Group`, directly use it.

  group_commands: Group = Group("Commands")

    The default `Group` that sub-commands are assigned to.

  group_arguments: Group = Group("Arguments")

    The default `Group` that positional-only parameters are assigned to.

  group_parameters: Group = Group("Parameters")

    The default `Group` that non-positional-only parameters are assigned to.

  validator: None | Callable | list[Callable] = []

    A function (or list of functions) where all the converted CLI-provided variables will be keyword-unpacked, regardless of their positional/keyword-type in the command function signature. The python variable names will be used, which may differ from their CLI names.

    Example usage:

        def validator(**kwargs):
            "Raise an exception if something is invalid."

    This validator runs after `Parameter` and `Group` validators.

  name_transform: Callable[[str], str] | None = None

    A function that converts function names to their CLI command counterparts.

    The function must have signature:

        def name_transform(s: str) -> str:
            ...

    The returned string should be without a leading `--`. If `None` (default value), uses `default_name_transform()`. Subapps inherit from the first non-`None` parent `name_transform`.

  config: None | Callable | Iterable[Callable] = None

    A function or list of functions that are consecutively executed after parsing CLI tokens and environment variables. These function(s) are called before any conversion and validation. Each config function must have signature:

        def config(app: "App", commands: Tuple[str, ...], arguments: ArgumentCollection):
            """Modifies given mapping inplace with some injected values.

            Parameters
            ----------
            app: App
               The current command app being executed.
            commands: Tuple[str, ...]
               The CLI strings that led to the current command function.
            arguments: ArgumentCollection
               Complete ArgumentCollection for the app.
               Modify this collection inplace to influence values provided to the function.
            """

    The intended use-case of this feature is to allow users to specify functions that can load defaults from some external configuration. See cyclopts.config for useful builtins and Config Files for examples.

  end_of_options_delimiter: str | None = None

    All tokens after this delimiter will be force-interpreted as positional arguments. If not set, attempts to inherit from parenting `App`, eventually defaulting to POSIX-standard `"--"`. Set to an empty string to disable.

  suppress_keyboard_interrupt: bool = True

    If the application receives a keyboard interrupt (Ctrl-C), suppress the error message and exit gracefully. Set to `False` to let `KeyboardInterrupt` propagate normally.

  backend: Literal['asyncio', 'trio'] | None = None

    The async backend to use when executing async commands. If not set, attempts to inherit from parenting `App`, eventually defaulting to `"asyncio"`.

    Example:

        from cyclopts import App

        app = App(backend="asyncio")

        @app.default
        async def main():
            await some_async_operation()

        app()

    The backend can also be overridden on a per-call basis:

        app(backend="trio")  # Override the app's backend for this call

  result_action: Literal['return_value', 'call_if_callable', 'print_non_int_return_int_as_exit_code', 'print_str_return_int_as_exit_code', 'print_str_return_zero', 'print_non_none_return_int_as_exit_code', 'print_non_none_return_zero', 'return_int_as_exit_code_else_zero', 'print_non_int_sys_exit', 'sys_exit', 'return_none', 'return_zero', 'print_return_zero', 'sys_exit_zero', 'print_sys_exit_zero'] | Callable[[Any], Any] | Iterable[Literal[...] | Callable[[Any], Any]] | None = None

    Controls how `App.__call__()` and `App.run_async()` handle command return values. By default (`"print_non_int_sys_exit"`), the app will call `sys.exit()` with an appropriate exit code. This default was chosen for consistent functionality between standalone scripts, and console entrypoints.

    Can be a predefined literal string, a custom callable that takes the result and returns a processed value, or a sequence of actions to be applied left-to-right in a pipeline.

    Each predefined mode's exact behavior is shown below:

    "print_non_int_sys_exit" (default)

    > The default CLI mode. Prints non-int values to stdout, then calls `sys.exit()` with the appropriate exit code.

    >     if isinstance(result, bool):
    >         sys.exit(0 if result else 1)  # i.e. True is success
    >     elif isinstance(result, int):
    >         sys.exit(result)
    >     elif result is not None:
    >         print(result)
    >         sys.exit(resolve_returncode(result))
    >     else:
    >         sys.exit(resolve_returncode(result))

    > See Custom Return Code Protocol for `resolve_returncode()`.

    "return_value"

    > Returns the command's value unchanged. Use for embedding Cyclopts in other Python code or testing.

    >     return result

    "call_if_callable"

    > Calls the result if it's callable (with no arguments), otherwise returns it unchanged. Useful for the dataclass command pattern where commands return class instances with `__call__` methods. Intended to be used in composition with other result actions (e.g., `["call_if_callable", "print_non_int_sys_exit"]`).

    >     return result() if callable(result) else result

    > See Dataclass Commands for usage examples.

    "sys_exit"

    > Never prints output. Calls `sys.exit()` with the appropriate exit code. Useful for CLI apps that handle their own output and just need exit code handling.

    >     if isinstance(result, bool):
    >         sys.exit(0 if result else 1)  # i.e. True is success
    >     elif isinstance(result, int):
    >         sys.exit(result)
    >     else:
    >         sys.exit(resolve_returncode(result))

    "print_non_int_return_int_as_exit_code"

    > Prints non-int values, returns int/bool as exit codes. Useful for testing and embedding.

    >     if isinstance(result, bool):
    >         return 0 if result else 1  # i.e. True is success
    >     elif isinstance(result, int):
    >         return result
    >     elif result is not None:
    >         print(result)
    >         return resolve_returncode(result)
    >     else:
    >         return resolve_returncode(result)

    "print_str_return_int_as_exit_code"

    > Only prints string return values. Returns int/bool as exit codes, silently returns 0 for other types.

    >     if isinstance(result, str):
    >         print(result)
    >         return resolve_returncode(result)
    >     elif isinstance(result, bool):
    >         return 0 if result else 1  # i.e. True is success
    >     elif isinstance(result, int):
    >         return result
    >     else:
    >         return resolve_returncode(result)

    "print_str_return_zero"

    > Only prints string return values, always returns 0. Useful for simple output-only CLIs.

    >     if isinstance(result, str):
    >         print(result)
    >     return resolve_returncode(result)

    "print_non_none_return_int_as_exit_code"

    > Prints all non-None values (including ints), returns int/bool as exit codes.

    >     if result is not None:
    >         print(result)
    >     if isinstance(result, bool):
    >         return 0 if result else 1  # i.e. True is success
    >     elif isinstance(result, int):
    >         return result
    >     return resolve_returncode(result)

    "print_non_none_return_zero"

    > Prints all non-None values (including ints), always returns 0.

    >     if result is not None:
    >         print(result)
    >     return resolve_returncode(result)

    "return_int_as_exit_code_else_zero"

    > Never prints output. Returns int/bool as exit codes, 0 for all other types. Useful for silent CLIs.

    >     if isinstance(result, bool):
    >         return 0 if result else 1  # i.e. True is success
    >     elif isinstance(result, int):
    >         return result
    >     else:
    >         return resolve_returncode(result)

    "return_none"

    > Always returns None, regardless of the command's return value.

    >     return None

    "return_zero"

    > Always returns 0, regardless of the command's return value.

    >     return resolve_returncode(result)

    "print_return_zero"

    > Always prints the result (even None), then always returns 0.

    >     print(result)
    >     return resolve_returncode(result)

    "sys_exit_zero"

    > Always calls `sys.exit(0)`, regardless of the command's return value.

    >     sys.exit(resolve_returncode(result))

    "print_sys_exit_zero"

    > Always prints the result (even None), then calls `sys.exit(0)`.

    >     print(result)
    >     sys.exit(resolve_returncode(result))

    Custom Callable

    > Provide a function for fully custom result handling. Receives the command's return value and returns a processed value.

    >     def custom_handler(result):
    >         if result is None:
    >             return 0
    >         elif isinstance(result, str):
    >             print(f"[OUTPUT] {result}")
    >             return 0
    >         return result

    >     app = App(result_action=custom_handler)

    Sequence of Actions

    > Provide a sequence (list or tuple) of actions to create a result-processing pipeline. Actions are applied left-to-right, with each action receiving the result of the previous action.

    >     def uppercase(result):
    >         return result.upper() if isinstance(result, str) else result

    >     def add_prefix(result):
    >         return f"[OUTPUT] {result}" if isinstance(result, str) else result

    >     # Pipeline: result → uppercase → add_prefix → return
    >     app = App(result_action=[uppercase, add_prefix, "return_value"])

    >     @app.command
    >     def greet(name: str) -> str:
    >         return f"hello {name}"

    >     result = app(["greet", "world"])
    >     # result == "[OUTPUT] HELLO WORLD"

    > Actions in a sequence can be any combination of predefined literal strings and custom callables. Empty sequences raise a `ValueError` at app initialization.

    Example:

        from cyclopts import App

        # For CLI applications with console_scripts entry points
        app = App(result_action="print_non_int_return_int_as_exit_code")

        @app.command
        def greet(name: str) -> str:
            return f"Hello {name}!"

        app()

    See Result Action for detailed examples and usage patterns.

  version_print(console: Annotated[Console | None, Parameter(parse=False)] = None) → None

    Print the application version.

    Parameters:

      console (Console) -- Console to print version string to. If not provided, follows the resolution order defined in `App.console`.

  __getitem__(key: str) → App

    Get the subapp from a command string.

    All commands get registered to Cyclopts as subapps. The actual function handler is at `app[key].default_command`.

    If the command was registered via lazy loading (import path string), it will be imported and resolved on first access.

    Example usage:

        from cyclopts import App

        app = App()
        app.command(App(name="foo"))

        @app["foo"].command
        def bar():
            print("Running bar.")

        app()

  __iter__() → Iterator[str]

    Iterate over command & meta command names.

    Example usage:

        from cyclopts import App

        app = App()

        @app.command
        def foo():
            pass

        @app.command
        def bar():
            pass

        # help and version flags are treated as commands.
        assert list(app) == ["--help", "-h", "--version", "foo", "bar"]

  parse_commands(tokens: None | str | Iterable[str] = None, *, include_parent_meta=True) → tuple[tuple[str, ...], tuple[App, ...], list[str]]

    Extract out the command tokens from a command.

    You are probably actually looking for `parse_args()`.

    Parameters:

      - tokens (None | str | Iterable[str]) -- Either a string, or a list of strings to launch a command. Defaults to `sys.argv[1:]`

      - include_parent_meta (bool) --

        Controls whether parent meta apps are included in the execution path.

        When True (default): - Parent meta apps (i.e. the "normal" app ) are added to the apps list. - Meta app options are consumed while parsing commands. - Used for getting the inheritance hierarchy.

        When False: - Meta app options are treated as regular arguments. - Used for getting the execution hierarchy.

        This parameter is primarily for internal use.

    Returns:

      - tuple[str, ...] -- Strings that are interpreted as a valid command chain.

      - tuple[App, ...] -- The execution path - apps that will be invoked in order.

      - list[str] -- The remaining non-command tokens.

  command(obj: T, name: None | str | Iterable[str] = None, *, alias: None | str | Iterable[str] = None, **kwargs: object) → T
  command(obj: None = None, name: None | str | Iterable[str] = None, *, alias: None | str | Iterable[str] = None, **kwargs: object) → Callable[[T], T]
  command(obj: str, name: None | str | Iterable[str] = None, *, alias: None | str | Iterable[str] = None, **kwargs: object) → None

    Decorator to register a function as a CLI command.

    Example usage:

        from cyclopts import App

        app = App()

        @app.command
        def foo():
            print("foo!")

        @app.command(name="buzz")
        def bar():
            print("bar!")

        # Lazy loading via import path
        app.command("myapp.commands:create_user", name="create")

        app()

        $ my-script foo
        foo!

        $ my-script buzz
        bar!

        $ my-script create
        # Imports and runs myapp.commands:create_user

    Parameters:

      - obj (Callable | App | str | None) -- Function, `App`, or import path string to be registered as a command. For lazy loading, provide a string in format "module.path:function_or_app_name".

      - name (None | str | Iterable[str]) --

        Name(s) to register the command to. If not provided, defaults to:

        - If registering an `App`, then the app's name.

        - If registering a function, then the function's name after applying `name_transform`.

        - If registering via import path, then the attribute name after applying `name_transform`.

        Special value `"*"` flattens all sub-App commands into this app (App instances only). See Flattening SubCommands for details.

      - **kwargs -- Any argument that `App` can take.

  default(obj: T, *, validator: Callable[[...], Any] | None = None) → T
  default(obj: None = None, *, validator: Callable[[...], Any] | None = None) → Callable[[T], T]

    Decorator to register a function as the default action handler.

    Example usage:

        from cyclopts import App

        app = App()

        @app.default
        def main():
            print("Hello world!")

        app()

        $ my-script
        Hello world!

  assemble_argument_collection(*, default_parameter: Parameter | None = None, parse_docstring: bool = False) → ArgumentCollection

    Assemble the argument collection for this app.

    Parameters:

      - default_parameter (Parameter | None) -- Default parameter with highest priority.

      - parse_docstring (bool) -- Parse the docstring of `default_command`. Set to `True` if we need help strings, otherwise set to `False` for performance reasons.

    Returns:

      All arguments for this app.

    Return type:

      ArgumentCollection

  parse_known_args(tokens: None | str | Iterable[str] = None, *, console: Console | None = None, error_console: Console | None = None, end_of_options_delimiter: str | None = None) → tuple[Callable[[...], Any], BoundArguments, list[str], dict[str, Any]]

    Interpret arguments into a registered function, `BoundArguments`, and any remaining unknown tokens.

    Parameters:

      - tokens (None | str | Iterable[str]) -- Either a string, or a list of strings to launch a command. Defaults to `sys.argv[1:]`

      - console (Console) -- Console to print help and runtime Cyclopts errors. If not provided, follows the resolution order defined in `App.console`.

      - error_console (Console) -- Console to print error messages. If not provided, follows the resolution order defined in `App.error_console`.

      - end_of_options_delimiter (str | None) -- All tokens after this delimiter will be force-interpreted as positional arguments. If None, inherits from `App.end_of_options_delimiter`, eventually defaulting to POSIX-standard `"--"`. Set to an empty string to disable.

    Returns:

      - command (Callable) -- Bare function to execute.

      - bound (inspect.BoundArguments) -- Bound arguments for `command`.

      - unused_tokens (list[str]) -- Any remaining CLI tokens that didn't get parsed for `command`.

      - ignored (dict[str, Any]) -- A mapping of python-variable-name to annotated type of any parameter with annotation `parse=False`. `Annotated` will be resolved. Intended to simplify meta apps.

  parse_args(tokens: None | str | Iterable[str] = None, *, console: Console | None = None, error_console: Console | None = None, print_error: bool | None = None, exit_on_error: bool | None = None, help_on_error: bool | None = None, verbose: bool | None = None, end_of_options_delimiter: str | None = None, error_formatter: Callable[[CycloptsError], Any] | None = None) → tuple[Callable[[...], Any], BoundArguments, dict[str, Any]]

    Interpret arguments into a function and `BoundArguments`.

    Raises:

      UnusedCliTokensError -- If any tokens remain after parsing.

    Parameters:

      - tokens (None | str | Iterable[str]) -- Either a string, or a list of strings to launch a command. Defaults to `sys.argv[1:]`.

      - console (Console) -- Console to print help and runtime Cyclopts errors. If not provided, follows the resolution order defined in `App.console`.

      - error_console (Console) -- Console to print error messages. If not provided, follows the resolution order defined in `App.error_console`.

      - print_error (bool | None) -- Print a rich-formatted error on error. If `None`, inherits from `App.print_error`, eventually defaulting to `True`.

      - exit_on_error (bool | None) -- If there is an error parsing the CLI tokens invoke `sys.exit(1)`. Otherwise, continue to raise the exception. If `None`, inherits from `App.exit_on_error`, eventually defaulting to `True`.

      - help_on_error (bool | None) -- Prints the help-page before printing an error. If `None`, inherits from `App.help_on_error`, eventually defaulting to `False`.

      - verbose (bool | None) -- Populate exception strings with more information intended for developers. If `None`, inherits from `App.verbose`, eventually defaulting to `False`.

      - end_of_options_delimiter (str | None) -- All tokens after this delimiter will be force-interpreted as positional arguments. If `None`, inherits from `App.end_of_options_delimiter`, eventually defaulting to POSIX-standard `"--"`. Set to an empty string to disable.

    Returns:

      - command (Callable) -- Function associated with command action.

      - bound (inspect.BoundArguments) -- Parsed and converted `args` and `kwargs` to be used when calling `command`.

      - ignored (dict[str, Any]) -- A mapping of python-variable-name to type-hint of any parameter with annotation `parse=False`. `Annotated` will be resolved. Intended to simplify meta apps.

  __call__(tokens: None | str | Iterable[str] = None, *, console: Console | None = None, error_console: Console | None = None, print_error: bool | None = None, exit_on_error: bool | None = None, help_on_error: bool | None = None, verbose: bool | None = None, end_of_options_delimiter: str | None = None, backend: Literal['asyncio', 'trio'] | None = None, result_action: Literal['return_value', 'call_if_callable', 'print_non_int_return_int_as_exit_code', 'print_str_return_int_as_exit_code', 'print_str_return_zero', 'print_non_none_return_int_as_exit_code', 'print_non_none_return_zero', 'return_int_as_exit_code_else_zero', 'print_non_int_sys_exit', 'sys_exit', 'return_none', 'return_zero', 'print_return_zero', 'sys_exit_zero', 'print_sys_exit_zero'] | Callable[[Any], Any] | Iterable[Literal['return_value', 'call_if_callable', 'print_non_int_return_int_as_exit_code', 'print_str_return_int_as_exit_code', 'print_str_return_zero', 'print_non_none_return_int_as_exit_code', 'print_non_none_return_zero', 'return_int_as_exit_code_else_zero', 'print_non_int_sys_exit', 'sys_exit', 'return_none', 'return_zero', 'print_return_zero', 'sys_exit_zero', 'print_sys_exit_zero'] | Callable[[Any], Any]] | None = None, error_formatter: Callable[[CycloptsError], Any] | None = None) → Any

    Interprets and executes a command.

    Parameters:

      - tokens (None | str | Iterable[str]) -- Either a string, or a list of strings to launch a command. Defaults to `sys.argv[1:]`.

      - console (Console) -- Console to print help and runtime Cyclopts errors. If not provided, follows the resolution order defined in `App.console`.

      - error_console (Console) -- Console to print error messages. If not provided, follows the resolution order defined in `App.error_console`.

      - print_error (bool | None) -- Print a rich-formatted error on error. If `None`, inherits from `App.print_error`, eventually defaulting to `True`.

      - exit_on_error (bool | None) -- If there is an error parsing the CLI tokens invoke `sys.exit(1)`. Otherwise, continue to raise the exception. If `None`, inherits from `App.exit_on_error`, eventually defaulting to `True`.

      - help_on_error (bool | None) -- Prints the help-page before printing an error. If `None`, inherits from `App.help_on_error`, eventually defaulting to `False`.

      - verbose (bool | None) -- Populate exception strings with more information intended for developers. If `None`, inherits from `App.verbose`, eventually defaulting to `False`.

      - end_of_options_delimiter (str | None) -- All tokens after this delimiter will be force-interpreted as positional arguments. If `None`, inherits from `App.end_of_options_delimiter`, eventually defaulting to POSIX-standard `"--"`. Set to an empty string to disable.

      - backend (Literal["asyncio", "trio"] | None) -- Override the async backend to use (if an async command is invoked). If `None`, inherits from `App.backend`, eventually defaulting to "asyncio". If passing backend="trio", ensure trio is installed via the extra: cyclopts[trio].

      - result_action (ResultAction | None) -- Controls how command return values are handled. Can be a predefined literal string or a custom callable that takes the result and returns a processed value. If `None`, inherits from `App.result_action`, eventually defaulting to "print_non_int_return_int_as_exit_code". See `App.result_action` for available modes.

    Returns:

      return_value -- The value the command function returns.

    Return type:

      Any

  async run_async(tokens: None | str | Iterable[str] = None, *, console: Console | None = None, error_console: Console | None = None, print_error: bool | None = None, exit_on_error: bool | None = None, help_on_error: bool | None = None, verbose: bool | None = None, end_of_options_delimiter: str | None = None, backend: Literal['asyncio', 'trio'] | None = None, result_action: Literal['return_value', 'call_if_callable', 'print_non_int_return_int_as_exit_code', 'print_str_return_int_as_exit_code', 'print_str_return_zero', 'print_non_none_return_int_as_exit_code', 'print_non_none_return_zero', 'return_int_as_exit_code_else_zero', 'print_non_int_sys_exit', 'sys_exit', 'return_none', 'return_zero', 'print_return_zero', 'sys_exit_zero', 'print_sys_exit_zero'] | Callable[[Any], Any] | Iterable[Literal['return_value', 'call_if_callable', 'print_non_int_return_int_as_exit_code', 'print_str_return_int_as_exit_code', 'print_str_return_zero', 'print_non_none_return_int_as_exit_code', 'print_non_none_return_zero', 'return_int_as_exit_code_else_zero', 'print_non_int_sys_exit', 'sys_exit', 'return_none', 'return_zero', 'print_return_zero', 'sys_exit_zero', 'print_sys_exit_zero'] | Callable[[Any], Any]] | None = None, error_formatter: Callable[[CycloptsError], Any] | None = None) → Any

    Async equivalent of `__call__()` for use within existing event loops.

    This method should be used when you're already in an async context (e.g., Jupyter notebooks, existing async applications) and need to execute a Cyclopts command without creating a new event loop.

    Parameters:

      - tokens (None | str | Iterable[str]) -- Either a string, or a list of strings to launch a command. Defaults to `sys.argv[1:]`.

      - console (Console) -- Console to print help and runtime Cyclopts errors. If not provided, follows the resolution order defined in `App.console`.

      - error_console (Console) -- Console to print error messages. If not provided, follows the resolution order defined in `App.error_console`.

      - print_error (bool | None) -- Print a rich-formatted error on error. If `None`, inherits from `App.print_error`, eventually defaulting to `True`.

      - exit_on_error (bool | None) -- If there is an error parsing the CLI tokens invoke `sys.exit(1)`. Otherwise, continue to raise the exception. If `None`, inherits from `App.exit_on_error`, eventually defaulting to `True`.

      - help_on_error (bool | None) -- Prints the help-page before printing an error. If `None`, inherits from `App.help_on_error`, eventually defaulting to `False`.

      - verbose (bool | None) -- Populate exception strings with more information intended for developers. If `None`, inherits from `App.verbose`, eventually defaulting to `False`.

      - end_of_options_delimiter (str | None) -- All tokens after this delimiter will be force-interpreted as positional arguments. If `None`, inherits from `App.end_of_options_delimiter`, eventually defaulting to POSIX-standard `"--"`. Set to an empty string to disable.

      - backend (Literal["asyncio", "trio"] | None) -- Override the async backend to use (if an async command is invoked). If `None`, inherits from `App.backend`, eventually defaulting to "asyncio". If passing backend="trio", ensure trio is installed via the extra: cyclopts[trio].

      - result_action (ResultAction | None) -- Controls how command return values are handled. Can be a predefined literal string or a custom callable that takes the result and returns a processed value. If `None`, inherits from `App.result_action`, eventually defaulting to "print_non_int_return_int_as_exit_code". See `App.result_action` for available modes.

    Returns:

      return_value -- The value the command function returns.

    Return type:

      Any

    Examples

        import asyncio
        from cyclopts import App

        app = App()

        @app.command
        async def my_async_command():
            await asyncio.sleep(1)
            return "Done!"

        # In an async context (e.g., Jupyter notebook or existing async app):
        async def main():
            result = await app.run_async(["my-async-command"])
            print(result)  # Prints: Done!

        asyncio.run(main())

  help_print(tokens: Annotated[None | str | Iterable[str], Parameter(show=False)] = None, *, console: Annotated[Console | None, Parameter(parse=False)] = None) → None

    Print the help page.

    Parameters:

      - tokens (None | str | Iterable[str]) -- Tokens to interpret for traversing the application command structure. If not provided, defaults to `sys.argv`.

      - console (Console) -- Console to print help and runtime Cyclopts errors. If not provided, follows the resolution order defined in `App.console`.

  generate_docs(output_format: DocFormat = 'markdown', recursive: bool = True, include_hidden: bool = False, heading_level: int = 1, max_heading_level: int = 6, flatten_commands: bool = False, usage_name: str | None = None) → str

    Generate documentation for this CLI application.

    Parameters:

      - output_format (DocFormat) -- Output format for the documentation. Accepts "markdown"/"md", "html"/"htm", or "rst"/"rest"/"restructuredtext". Default is "markdown".

      - recursive (bool) -- If True, generate documentation for all subcommands recursively. Default is True.

      - include_hidden (bool) -- If True, include hidden commands/parameters in documentation. Default is False.

      - heading_level (int) -- Starting heading level for the main application title. Default is 1 (single # for markdown, = for RST).

      - max_heading_level (int) -- Maximum heading level to use. Headings deeper than this will be capped at this level. Standard Markdown and HTML support levels 1-6. Default is 6.

      - flatten_commands (bool) -- If True, generate all commands at the same heading level instead of nested. Default is False.

      - usage_name (str | None) -- Optional replacement for the root app name shown in `Usage:` lines of the generated documentation. Useful when the runtime invocation differs from the app's configured name — for example, an app named `"cli"` that is typically invoked as `uv run cli`. Only the `Usage:` lines change; document titles, section headings, and table-of-contents anchors continue to use `app.name[0]`. Default is None (use `app.name[0]`).

    Returns:

      The generated documentation.

    Return type:

      str

    Raises:

      ValueError -- If an unsupported output format is specified.

    Examples

        >>> app = App(name="myapp", help="My CLI Application")
        >>> docs = app.generate_docs()  # Generate markdown as string
        >>> html_docs = app.generate_docs(output_format="html")  # Generate HTML
        >>> rst_docs = app.generate_docs(output_format="rst")  # Generate RST
        >>> # To write to file, caller can do:
        >>> # Path("docs/cli.md").write_text(docs)
        >>> # Override the invocation shown in Usage: lines (e.g., uv run cli)
        >>> docs = app.generate_docs(usage_name="uv run cli")

  generate_completion(*, prog_name: str | None = None, shell: Literal['zsh', 'bash', 'fish'] | None = None) → str

    Generate shell completion script for this application.

    Parameters:

      - prog_name (str | None) -- Program name for completion. If None, uses first name from app.name.

      - shell (Literal["zsh", "bash", "fish"] | None) -- Shell type. If None, automatically detects current shell. Supported shells: "zsh", "bash", "fish".

    Returns:

      Complete shell completion script.

    Return type:

      str

    Examples

    Auto-detect shell and generate completion:

        >>> app = App(name="myapp")
        >>> script = app.generate_completion()
        >>> Path("_myapp").write_text(script)

    Explicitly specify shell type:

        >>> script = app.generate_completion(shell="zsh")

    Raises:

      - ValueError -- If app has no name or shell type is unsupported.

      - ShellDetectionError -- If shell is None and auto-detection fails.

  install_completion(*, shell: Literal['zsh', 'bash', 'fish'] | None = None, output: Path | None = None, add_to_startup: bool = True) → Path

    Install shell completion script to appropriate location.

    Generates and writes the completion script to a shell-specific location.

    Parameters:

      - shell (Literal["zsh", "bash", "fish"] | None) -- Shell type for completion. If not specified, attempts to auto-detect current shell.

      - output (Path | None) -- Output path for the completion script. If not specified, uses shell-specific default: - zsh: ~/.zsh/completions/_cyclopts_<prog_name> (or $ZSH_CUSTOM/completions/_cyclopts_<prog_name> with oh-my-zsh) - bash: ~/.local/share/bash-completion/completions/<prog_name> - fish: ~/.config/fish/completions/<prog_name>.fish

      - add_to_startup (bool) -- If True (default), adds source line to shell RC file to ensure completion is loaded. Set to False if completions are already configured to auto-load.

    Returns:

      Path where the completion script was installed.

    Return type:

      Path

    Examples

    Auto-detect shell and install:

        >>> app = App(name="myapp")
        >>> path = app.install_completion()

    Install for specific shell:

        >>> path = app.install_completion(shell="zsh")

    Install to custom path:

        >>> path = app.install_completion(output=Path("/custom/path"))

    Install without modifying RC files:

        >>> path = app.install_completion(shell="bash", add_to_startup=False)

    Raises:

      - ShellDetectionError -- If shell is None and auto-detection fails.

      - ValueError -- If shell type is unsupported.

  register_install_completion_command(name: str | Iterable[str] = '--install-completion', add_to_startup: bool = True, **kwargs) → None

    Register a command for installing shell completion.

    This is a convenience method that creates a command which calls `install_completion()`. For more control over the command implementation, users can manually define their own command.

    Parameters:

      - name (str | Iterable[str]) -- Command name(s) for the install completion command. Defaults to "--install-completion".

      - add_to_startup (bool) -- If True (default), adds source line to shell RC file to ensure completion is loaded. Set to False if completions are already configured to auto-load.

      - **kwargs -- Additional keyword arguments to pass to `command()`. Can be used to customize the command registration (e.g., help, group, help_flags, version_flags).

    Examples

    Register install-completion command:

        >>> app = App(name="myapp")
        >>> app.register_install_completion_command()
        >>> app()  # Now responds to: myapp --install-completion

    Use a custom command name:

        >>> app.register_install_completion_command(name="--setup-completion")

    Customize help text:

        >>> app.register_install_completion_command(help="Install shell completion for myapp.")

    Customize command registration:

        >>> app.register_install_completion_command(group="Setup", help_flags=[])

    Install without modifying RC files:

        >>> app.register_install_completion_command(add_to_startup=False)

    See also

    `install_completion`

      The underlying method that performs the installation.

  interactive_shell(prompt: str = '$ ', quit: None | str | Iterable[str] = None, dispatcher: Dispatcher | None = None, console: Console | None = None, exit_on_error: bool = False, result_action: Literal['return_value', 'call_if_callable', 'print_non_int_return_int_as_exit_code', 'print_str_return_int_as_exit_code', 'print_str_return_zero', 'print_non_none_return_int_as_exit_code', 'print_non_none_return_zero', 'return_int_as_exit_code_else_zero', 'print_non_int_sys_exit', 'sys_exit', 'return_none', 'return_zero', 'print_return_zero', 'sys_exit_zero', 'print_sys_exit_zero'] | Callable[[Any], Any] | Iterable[Literal['return_value', 'call_if_callable', 'print_non_int_return_int_as_exit_code', 'print_str_return_int_as_exit_code', 'print_str_return_zero', 'print_non_none_return_int_as_exit_code', 'print_non_none_return_zero', 'return_int_as_exit_code_else_zero', 'print_non_int_sys_exit', 'sys_exit', 'return_none', 'return_zero', 'print_return_zero', 'sys_exit_zero', 'print_sys_exit_zero'] | Callable[[Any], Any]] | None = None, **kwargs) → None

    Create a blocking, interactive shell.

    All registered commands can be executed in the shell.

    Parameters:

      - prompt (str) -- Shell prompt. Defaults to `"$ "`.

      - quit (str | Iterable[str]) -- String or list of strings that will cause the shell to exit and this method to return. Defaults to `["q", "quit"]`.

      - dispatcher (Dispatcher | None) --

        Optional function that subsequently invokes the command. The `dispatcher` function must have signature:

            def dispatcher(command: Callable, bound: inspect.BoundArguments, ignored: dict[str, Any]) -> Any:
                return command(*bound.args, **bound.kwargs)

        The default dispatcher additionally runs `async` commands using the resolved `App.backend` (defaulting to `"asyncio"`), mirroring `App.__call__()`. A custom `dispatcher` is responsible for handling async commands itself (e.g. via `asyncio.run()`).

      - console (Console | None) -- Rich Console to use for output. If `None`, uses `App.console`.

      - exit_on_error (bool) -- Whether to call `sys.exit` on parsing errors. Defaults to `False`.

      - result_action (ResultAction | None) -- How to handle command return values in the interactive shell. Defaults to `"print_non_int_return_int_as_exit_code"` which prints non-int results and returns int/bool as exit codes without calling sys.exit. If `None`, inherits from `App.result_action`.

      - **kwargs -- Get passed along to `parse_args()`.

  update(app: App)

    Copy over all commands from another `App`.

    Commands from the meta app will not be copied over.

    Parameters:

      app (cyclopts.App) -- All commands from this application will be copied over.

class cyclopts.Parameter(name: str | ~collections.abc.Iterable[str] | None = None, *, converter: ~collections.abc.Callable[[...], ~typing.Any] | str | None = None, validator: ~collections.abc.Callable[[...], ~typing.Any] | str | ~collections.abc.Iterable[~collections.abc.Callable[[...], ~typing.Any] | str] | None = (), alias: str | ~collections.abc.Iterable[str] | None = None, negative: bool | str | ~collections.abc.Iterable[str] | None = None, group: None | Group | str | Iterable[Group | str] = None, parse: bool | ~re.Pattern[str] | str | None = None, show: bool | None = None, show_default: None | bool | str | ~collections.abc.Callable[[~typing.Any], ~typing.Any] = None, show_choices: bool | None = None, help: str | None = None, show_env_var: bool | None = None, env_var: str | ~collections.abc.Iterable[str] | None = None, env_var_split: ~collections.abc.Callable[[...], ~typing.Any] = <function env_var_split>, negative_bool: str | ~collections.abc.Iterable[str] | None = None, negative_iterable: str | ~collections.abc.Iterable[str] | None = None, negative_none: str | ~collections.abc.Iterable[str] | None = None, required: bool | None = None, allow_leading_hyphen: bool = False, requires_equals: bool = False, name_transform: ~collections.abc.Callable[[str], str] | None = None, accepts_keys: bool | None = None, consume_multiple: bool | int | ~collections.abc.Sequence[int] | tuple[int, int | None] | None = None, json_dict: bool | None = None, json_list: bool | None = None, count: bool | None = None, allow_repeating: bool | None = None, n_tokens: int | None = None)

  Cyclopts configuration for individual function parameters with `Annotated`.

  Example usage:

      from cyclopts import app, Parameter
      from typing import Annotated

      app = App()

      @app.default
      def main(foo: Annotated[int, Parameter(name="bar")]):
          print(foo)

      app()

      $ my-script 100
      100

      $ my-script --bar 100
      100

  name: None | str | Iterable[str] = None

    Name(s) to expose to the CLI. If not specified, cyclopts will apply `name_transform` to the python parameter name.

        from cyclopts import App, Parameter
        from typing import Annotated

        app = App()

        @app.default
        def main(foo: Annotated[int, Parameter(name=("bar", "-b"))]):
           print(f"{foo=}")

        app()

        $ my-script --help
        Usage: main COMMAND [ARGS] [OPTIONS]

        ╭─ Commands ─────────────────────────────────────────────────────╮
        │ --help -h  Display this message and exit.                      │
        │ --version  Display application version.                        │
        ╰────────────────────────────────────────────────────────────────╯
        ╭─ Parameters ───────────────────────────────────────────────────╮
        │ *  BAR --bar  -b  [required]                                   │
        ╰────────────────────────────────────────────────────────────────╯

        $ my-script --bar 100
        foo=100

        $ my-script -b 100
        foo=100

    If specifying name in a nested data structure (e.g. a dataclass), beginning the name with a hyphen `-` will override any hierarchical dot-notation.

        from cyclopts import App, Parameter
        from dataclasses import dataclass
        from typing import Annotated

        app = App()

        @dataclass
        class User:
           id: int  # default behavior
           email: Annotated[str, Parameter(name="--email")]  # overrides
           pwd: Annotated[str, Parameter(name="password")]  # dot-notation with parent

        @app.command
        def create(user: User):
           print(f"Creating {user=}")

        app()

        $ my-script create --help
        Usage: scratch.py create [ARGS] [OPTIONS]

        ╭─ Parameters ───────────────────────────────────────────────────╮
        │ *  USER.ID --user.id  [required]                               │
        │ *  EMAIL --email      [required]                               │
        │ *  USER.PASSWORD      [required]                               │
        │      --user.password                                           │
        ╰────────────────────────────────────────────────────────────────╯

  alias: None | str | Iterable[str] = None

    Additional name(s) to expose to the CLI. Unlike `name`, this does not override Cyclopts-derived names.

    The following two examples are functionally equivalent:

        @app.default
        def main(foo: Annotated[int, Parameter(name=["--foo", "-f"])]):
            pass

        @app.default
        def main(foo: Annotated[int, Parameter(alias="-f")]):
            pass

  converter: Callable | None = None

    A function that converts tokens into an object. The converter should have signature:

        def converter(type_, tokens) -> Any:
            pass

    Where `type_` is the parameter's type hint, and `tokens` is either:

    - A `list[cyclopts.Token]` of CLI tokens (most commonly).

          from cyclopts import App, Parameter
          from typing import Annotated

          app = App()

          def converter(type_, tokens):
             assert type_ == tuple[int, int]
             return tuple(2 * int(x.value) for x in tokens)

          @app.default
          def main(coordinates: Annotated[tuple[int, int], Parameter(converter=converter)]):
             print(f"{coordinates=}")

          app()

          $ python my-script.py 7 12
          coordinates=(14, 24)

    - A `dict` of `Token` if keys are specified in the CLI. E.g.

          $ python my-script.py --foo.key1=val1

      would be parsed into:

          tokens = {
             "key1": ["val1"],
          }

    If not provided, defaults to Cyclopts's internal coercion engine. If a pydantic type-hint is provided, Cyclopts will disable its internal coercion engine (including this converter argument) and leave the coercion to pydantic.

    The number of tokens passed to the converter is inferred from the type hint by default, but can be explicitly controlled with `n_tokens`. This is useful when the type signature doesn't match the desired CLI token consumption. When loading complex objects with multiple fields, it may also be useful to combine with `accepts_keys`.

    Decorating Converters: Converter functions can be decorated with `Parameter` to define reusable conversion behavior:

        @Parameter(n_tokens=1, accepts_keys=False)
        def load_from_id(type_, tokens):
            """Load object from database by ID."""
            return fetch_from_db(tokens[0].value)

        @app.default
        def main(obj: Annotated[MyType, Parameter(converter=load_from_id)]):
            # Automatically inherits n_tokens=1 and accepts_keys=False
            pass

    Classmethod Support: Converters can be classmethods. Use string references for class decoration or direct references in annotations. Classmethod signature should be `(cls, tokens)` instead of `(type_, tokens)`:

        @Parameter(converter="from_env")
        class Config:
            @Parameter(n_tokens=1, accepts_keys=False)
            @classmethod
            def from_env(cls, tokens):
                env = tokens[0].value
                configs = {"dev": ("localhost", 8080), "prod": ("api.example.com", 443)}
                return cls(*configs[env])

  validator: None | Callable | str | Iterable[Callable | str] = None

    A function (or list of functions) that validates data returned by the `converter`.

        def validator(type_, value: Any) -> None:
            pass  # Raise a TypeError, ValueError, or AssertionError here if data is invalid.

    Classmethod Support: Validators can be classmethods. Use string references for class decoration or direct references in annotations.

        @Parameter(name="*", validator="validate")
        @dataclass
        class TextStyle:
            color: str
            bold: bool = False
            italic: bool = False

            @classmethod
            def validate(cls, value):
                if value.bold and value.italic:
                    raise ValueError("Cannot use both --bold and --italic together.")

  group: None | str | Group | Iterable[str | Group] = None

    The group(s) that this parameter belongs to. This can be used to better organize the help-page, and/or to add additional conversion/validation logic (such as ensuring mutually-exclusive arguments).

    If `None`, defaults to one of the following groups:

    1. Parenting `App.group_arguments` if the parameter is `POSITIONAL_ONLY`. By default, this is `Group("Arguments")`.

    2. Parenting `App.group_parameters` otherwise. By default, this is `Group("Parameters")`.

    See Groups for examples.

  negative: None | str | Iterable[str] = None

    Name(s) for empty iterables or false boolean flags.

    - For booleans, defaults to `no-{name}` (see `negative_bool`).

    - For iterables, defaults to `empty-{name}` (see `negative_iterable`).

    Set to an empty list or string to disable the creation of negative flags.

    Example usage:

        from cyclopts import App, Parameter
        from typing import Annotated

        app = App()

        @app.default
        def main(*, verbose: Annotated[bool, Parameter(negative="--quiet")] = False):
           print(f"{verbose=}")

        app()

        $ my-script --help
        Usage: main COMMAND [ARGS] [OPTIONS]

        ╭─ Commands ─────────────────────────────────────────────────────╮
        │ --help -h  Display this message and exit.                      │
        │ --version  Display application version.                        │
        ╰────────────────────────────────────────────────────────────────╯
        ╭─ Parameters ───────────────────────────────────────────────────╮
        │ --verbose --quiet  [default: False]                            │
        ╰────────────────────────────────────────────────────────────────╯

  negative_bool: str | None = None

    Prefix for negative boolean flags. Defaults to `"no-"`.

  negative_iterable: str | None = None

    Prefix for empty iterables (like lists and sets) flags. Defaults to `"empty-"`.

  negative_none: str | None = None

    Prefix for setting optional parameters to `None`. Not enabled by default (no prefixes set).

    Example:

        from pathlib import Path
        from typing import Annotated

        from cyclopts import App, Parameter

        app = App(
           default_parameter=Parameter(negative_none="none-")
        )

        @app.default
        def default(path: Path | None = Path("data.bin")):
            print(f"{path=}")

        app()

        $ my-script
        path=PosixPath('data.bin')

        $ my-script --path=cat.jpeg
        path=PosixPath('cat.jpeg')

        $ my-script --none-path
        path=None

  allow_leading_hyphen: bool = False

    Allow parsing non-numeric values that begin with a hyphen `-`. This is disabled (`False`) by default, allowing for more helpful error messages for unknown CLI options.

  requires_equals: bool = False

    Require long options to use `=` to separate the option name from its value (e.g., `--option=value`). When enabled, the space-separated form `--option value` is rejected with a `RequiresEqualsError`.

    - Only applies to long-form options (those starting with `--`).

    - Short options (e.g., `-o value`) are not affected.

    - Boolean flags (e.g., `--verbose`) work regardless of this setting.

    - Can be set app-wide via `App.default_parameter`.

    - Cannot be combined with `consume_multiple` (raises `ValueError`). To provide multiple values for a list parameter, repeat the option (e.g., `--urls=a --urls=b`). To pass an empty iterable, use the negative flag (e.g., `--empty-urls`).

        from cyclopts import App, Parameter
        from typing import Annotated

        app = App()

        @app.default
        def main(*, name: Annotated[str, Parameter(requires_equals=True)]):
            print(f"Hello {name}")

        app()

        $ my-script --name=alice
        Hello alice

        $ my-script --name alice
        ╭─ Error ───────────────────────────────────────────────────────╮
        │ Parameter --name requires a value assigned with `=`. Use      │
        │ --name=VALUE.                                                 │
        ╰───────────────────────────────────────────────────────────────╯

  parse: None | bool | str | re.Pattern = None

    Attempt to use this parameter while parsing. Annotated parameter must be keyword-only or have a default value. This is intended to be used with meta apps for injecting values.

    - `True` - Parse this parameter from CLI tokens.

    - `False` - Do not parse; parameter will appear in the `ignored` dict from `App.parse_args()`.

    - `None` - Default behavior (parse).

    - `str` - A regex pattern; parse if the pattern matches the parameter name, otherwise skip. String patterns are automatically compiled to `re.Pattern` for performance.

    - `re.Pattern` - A pre-compiled regex pattern; same behavior as string patterns.

    Regex patterns are primarily intended for use with `App.default_parameter` to define app-wide skip patterns. For example, if we wanted to skip all fields that begin with an underscore `_`:

        import re
        from cyclopts import App, Parameter

        # Skip parsing underscore-prefixed KEYWORD_ONLY parameters (i.e. private parameters)
        # Both string and pre-compiled patterns are supported:
        app = App(default_parameter=Parameter(parse="^(?!_)"))
        # or: app = App(default_parameter=Parameter(parse=re.compile("^(?!_)")))

        @app.default
        def main(visible: str, *, _injected: str = "default"):
            # _injected is NOT parsed from CLI; uses default value
            pass

  required: bool | None = None

    Indicates that the parameter must be supplied. Defaults to inferring from the function signature; i.e. `False` if the parameter has a default, `True` otherwise.

  show: bool | None = None

    Show this parameter on the help screen. Defaults to whether the parameter is `parsed` (usually `True`).

  show_default: None | bool | str | Callable[[Any], Any] = None

    If a variable has a default, display the default on the help page. Defaults to `None`, similar to `True`, but will not display the default if it is `None`.

    If set to a string, that string is displayed verbatim as the default value, regardless of the actual default. This is useful when the real default cannot be known at help-time (e.g. a value resolved at runtime):

        input_file: Annotated[Path | None, Parameter(show_default="automatic")] = None

    Results in `[default: automatic]` on the help page.

    If set to a function with signature:

        def formatter(value: Any) -> Any:
            ...

    Then the function will be called with the default value, and the returned value will be used as the displayed default value.

    Example formatting function:

        def hex_formatter(value: int) -> str
           """Will result in something like "[default: 0xFF]" instead of "[default: 255]"."""
           return f"0x{value:X}"

  show_choices: bool | None = True

    If a variable has a set of choices, display the choices on the help page.

  help: str | None = None

    Help string to be displayed on the help page. If not specified, defaults to the docstring.

  show_env_var: bool | None = True

    If a variable has `env_var` set, display the variable name on the help page.

  env_var: None | str | Iterable[str] = None

    Fallback to environment variable(s) if CLI value not provided. If multiple environment variables are given, the left-most environment variable with a set value will be used. If no environment variable is set, Cyclopts will fallback to the function-signature default.

  env_var_split: Callable = cyclopts.env_var_split

    Function that splits up the read-in `env_var` value. The function must have signature:

        def env_var_split(type_: type, val: str) -> list[str]:
            ...

    where `type_` is the associated parameter type-hint, and `val` is the environment value.

  name_transform: Callable[[str], str] | None = None

    A function that converts python parameter names to their CLI command counterparts.

    The function must have signature:

        def name_transform(s: str) -> str:
            ...

    If `None` (default value), uses `cyclopts.default_name_transform()`.

  accepts_keys: bool | None = None

    If `False`, treat the user-defined class annotation similar to a tuple. Individual class sub-parameters will not be addressable by CLI keywords. The class will consume enough tokens to populate all required positional parameters.

    Default behavior (`accepts_keys=True`):

        from cyclopts import App, Parameter
        from typing import Annotated

        app = App()

        class Image:
           def __init__(self, path, label):
              self.path = path
              self.label = label

           def __repr__(self):
              return f"Image(path={self.path!r}, label={self.label!r})"

        @app.default
        def main(image: Image):
           print(f"{image=}")

        app()

        $ my-program --help
        Usage: main COMMAND [ARGS] [OPTIONS]

        ╭─ Commands ──────────────────────────────────────────────────────────╮
        │ --help -h  Display this message and exit.                           │
        │ --version  Display application version.                             │
        ╰─────────────────────────────────────────────────────────────────────╯
        ╭─ Parameters ────────────────────────────────────────────────────────╮
        │ *  IMAGE.PATH --image.path    [required]                            │
        │ *  IMAGE.LABEL --image.label  [required]                            │
        ╰─────────────────────────────────────────────────────────────────────╯

        $ my-program foo.jpg nature
        image=Image(path='foo.jpg', label='nature')

        $ my-program --image.path foo.jpg --image.label nature
        image=Image(path='foo.jpg', label='nature')

    Behavior when `accepts_keys=False`:

        # Modify the default command function's signature.
        @app.default
        def main(image: Annotated[Image, Parameter(accepts_keys=False)]):
           print(f"{image=}")

        $ my-program --help
        Usage: main COMMAND [ARGS] [OPTIONS]

        ╭─ Commands ──────────────────────────────────────────────────────────╮
        │ --help -h  Display this message and exit.                           │
        │ --version  Display application version.                             │
        ╰─────────────────────────────────────────────────────────────────────╯
        ╭─ Parameters ────────────────────────────────────────────────────────╮
        │ *  IMAGE --image  [required]                                        │
        ╰─────────────────────────────────────────────────────────────────────╯

        $ my-program foo.jpg nature
        image=Image(path='foo.jpg', label='nature')

        $ my-program --image foo.jpg nature
        image=Image(path='foo.jpg', label='nature')

    The `accepts_keys=False` option is commonly used with `converter` and `n_tokens`.

  consume_multiple: None | bool | int | Sequence[int] = None

    Controls how many CLI tokens a list/iterable parameter consumes when specified by keyword. If the parameter is specified positionally, `Parameter.consume_multiple` is ignored.

    The following value types are supported:

    - `False` (default) — only a single element worth of CLI tokens will be consumed per keyword occurrence.

    - `True` — all remaining CLI tokens will be consumed until the stream is exhausted or an option-like token is reached. Providing the keyword with no values creates an empty container.

    - `int` — like `True`, but the integer specifies the minimum number of elements required. For example, `consume_multiple=1` requires at least one value (preventing empty lists), and `consume_multiple=0` is equivalent to `True`.

    - `Sequence`[`int`] — a `(min, max)` pair (e.g. a tuple or list of two ints). All remaining CLI tokens are consumed greedily, and a `ConsumeMultipleError` is raised if the number of elements is outside the `(min, max)` bounds.

    Example: consume_multiple=True

        from cyclopts import App, Parameter
        from typing import Annotated

        app = App()

        @app.command
        def name_ext(
            name: str,
            ext: Annotated[list[str], Parameter(consume_multiple=True)],
        ):
            for extension in ext:
                print(f"{name}.{extension}")

        app()

        $ my-program --name "my_file" --ext "txt" "pdf"  # stream is exhausted
        my_file.txt
        my_file.pdf

        $ my-program --ext "txt" "pdf" --name "my_file"  # a keyword is reached
        my_file.txt
        my_file.pdf

    When `consume_multiple=True`, providing the keyword flag without any values will create an empty container, equivalent to using the `negative_iterable` prefix (e.g., `--empty-ext`):

        $ my-program --name "my_file" --ext
        # No output - ext is an empty list []

        $ my-program --name "my_file" --empty-ext
        # No output - ext is an empty list []

    Example: consume_multiple=1 (require at least one value)

        from cyclopts import App, Parameter
        from typing import Annotated

        app = App()

        @app.default
        def main(
            urls: Annotated[list[str] | None, Parameter(consume_multiple=1)] = None,
        ):
            print(urls)

        app()

        $ my-program --urls http://a.com http://b.com
        ['http://a.com', 'http://b.com']

        $ my-program --urls
        ╭─ Error ────────────────────────────────────────────╮
        │ Parameter --urls requires an argument.              │
        ╰────────────────────────────────────────────────────╯

    Example: consume_multiple=(1, 3) (min/max bounds)

        from cyclopts import App, Parameter
        from typing import Annotated

        app = App()

        @app.default
        def main(
            files: Annotated[list[str], Parameter(consume_multiple=(1, 3))],
        ):
            print(f"Files: {files}")

        app()

        $ my-program --files a.txt b.txt
        Files: ['a.txt', 'b.txt']

        $ my-program --files a.txt b.txt c.txt d.txt
        ╭─ Error ─────────────────────────────────────────╮
        │ Parameter --files accepts at most 3 elements.   │
        │ Got 4.                                          │
        ╰─────────────────────────────────────────────────╯

    In this example, `--files` raises a `ConsumeMultipleError` if fewer than 1 or more than 3 values are provided.

    Example: consume_multiple=False (default)

        from cyclopts import App
        from pathlib import Path

        app = App()

        @app.default
        def name_ext(name: str, ext: list[str]): # same as `ext: Annotated[list[str], Parameter(consume_multiple=False)]``
            for extension in ext:
                print(f"{name}.{extension}")

        app()

        $ my-program --name "my_file" --ext "txt" "pdf"
        ╭─ Error ────────────────────────────────────────────╮
        │ Unused Tokens: ['pdf'].                            │
        ╰────────────────────────────────────────────────────╯

  json_dict: bool | None = None

    Allow for the parsing of json-dict-strings as data. If `None` (default behavior), acts like `True`, unless the annotated type is union'd with `str`. When `True`, data will be parsed as json if the following conditions are met:

    1. The parameter is specified as a keyword option; e.g. `--movie`.

    2. The referenced parameter is dataclass-like.

    3. The first character of the token is a `{`.

  json_list: bool | None = None

    Allow for the parsing of json-list-strings as data. If `None` (default behavior), acts like `True`, unless the annotated type has each element type `str`. When `True`, data will be parsed as json if the following conditions are met:

    1. The referenced parameter is iterable (not including `str`).

    2. The first character of the token is a `[`.

  count: bool = False

    If `True`, count the number of times the flag appears instead of parsing a value. Each occurrence increments the count by 1 (e.g., `-vvv` results in `3`).

    Requirements and behavior:

    - The parameter must have an `int` type hint (or `Optional[int]`).

    - Short flags can be concatenated: `-vvv` is equivalent to `-v -v -v`.

    - Long flags can be repeated: `--verbose --verbose` results in `2`.

    - Negative flag variants (e.g., `--no-verbose`) are not generated.

    Common use case: verbosity levels.

        from cyclopts import App, Parameter
        from typing import Annotated

        app = App()

        @app.default
        def main(verbose: Annotated[int, Parameter(name="-v", count=True)] = 0):
           print(f"Verbosity level: {verbose}")

        app()

        $ my-script -vvv
        Verbosity level: 3

    See Coercion Rules for more details.

  allow_repeating: bool | None = None

    Controls whether a keyword option can be specified multiple times on the CLI (e.g., `--foo a --foo b`).

    - `None` (default): iterable types accumulate values, scalar types raise `RepeatArgumentError`.

    - `False`: always raise `RepeatArgumentError` on repeated options. Useful with `consume_multiple` to allow `--foo a b c` but disallow `--foo a --foo b`.

    - `True`: always allow repeated options. Iterable types accumulate as usual. Scalar types use "last wins" semantics (the last value specified is used).

        from cyclopts import App, Parameter
        from typing import Annotated

        app = App()

        @app.default
        def main(
            values: Annotated[list[str], Parameter(consume_multiple=True, allow_repeating=False)],
        ):
            print(values)

        app()

        $ my-script --values a b c
        ['a', 'b', 'c']

        $ my-script --values a --values b
        ╭─ Error ──────────────────────────────────────────────────╮
        │ Parameter --values specified multiple times.             │
        ╰─────────────────────────────────────────────────────────╯

  n_tokens: int | None = None

    Explicitly override the number of CLI tokens this parameter consumes.

    By default, Cyclopts infers the token count from the parameter's type hint (e.g., `int` consumes 1 token, `tuple[int, int]` consumes 2, `list` consumes all remaining). This attribute allows you to override that inference, which is particularly useful when:

    - Using custom converters that need a different token count than the type suggests.

    - Loading complex types from a single token (e.g., loading from a file path).

    - Implementing selection/lookup patterns where one token identifies an object.

    Values:

    - `None` (default): Infer token count from the type hint.

    - non-negative integer: Consume exactly that many tokens.

    - `-1`: Consume all remaining tokens (similar to iterables).

    For `*args` parameters, `n_tokens` specifies tokens per element. For example, `n_tokens=2` with 6 tokens creates 3 elements.

        from cyclopts import App, Parameter
        from typing import Annotated

        class Config:
            def __init__(self, host: str, port: int):
                self.host = host
                self.port = port

        def load_config(type_, tokens):
            # Load config from a file path (single token)
            filepath = tokens[0].value
            # ... load from file ...
            return Config("example.com", 8080)

        app = App()

        @app.default
        def main(
            config: Annotated[
                Config,
                Parameter(n_tokens=1, converter=load_config, accepts_keys=False)
            ]
        ):
            print(f"Connecting to {config.host}:{config.port}")

        app()

        $ my-script --config prod.conf
        Connecting to example.com:8080

  classmethod combine(*parameters: Parameter | None) → Parameter

    Returns a new Parameter with combined values of all provided `parameters`.

    Parameters:

      *parameters (Parameter | None) -- Parameters who's attributes override `self` attributes. Ordered from least-to-highest attribute priority.

  classmethod default() → Self

    Create a Parameter with all Cyclopts-default values.

    This is different than just `Parameter` because the default values will be recorded and override all upstream parameter values.

  __call__(obj: T) → T

    Decorator interface for annotating a function/class with a `Parameter`.

    Most commonly used for directly configuring a class:

        @Parameter(...)
        class Foo: ...

class cyclopts.Group(name: str = '', help: str = '', *, show: bool | None = None, sort_key: Any = None, validator: None | Callable[[ArgumentCollection], Any] | Iterable[Callable[[ArgumentCollection], Any]] = None, default_parameter: Parameter | None = None, help_formatter: None | Literal['default', 'plain'] | HelpFormatter = None)

  A group of parameters and/or commands in a CLI application.

  name: str = ""

    Group name used for the help-page and for group-referenced-by-string. This is a title, so the first character should be capitalized. If a name is not specified, it will not be shown on the help-page.

  help: str = ""

    Additional documentation shown on the help-page. This will be displayed inside the group's panel, above the parameters/commands.

  show: bool | None = None

    Show this group on the help-page. Defaults to `None`, which will only show the group if a `name` is provided.

  help_formatter: None | Literal['default', 'plain'] | HelpFormatter = None

    Help formatter to use for rendering this group's help panel.

    - If `None` (default), inherits from the `App`'s `help_formatter`.

    - If `"default"`, uses `DefaultFormatter`.

    - If `"plain"`, uses `PlainFormatter` for no-frills plain text output.

    - If a callable (see `HelpFormatter` protocol), uses the provided formatter.

    This allows per-group customization of help appearance:

        from cyclopts import App, Group, Parameter
        from cyclopts.help import DefaultFormatter, PanelSpec
        from typing import Annotated

        app = App()

        # Using string literal
        simple_group = Group(
            "Simple Options",
            help_formatter="plain"
        )

        # Using custom formatter instance
        custom_group = Group(
            "Custom Options",
            help_formatter=DefaultFormatter(
                panel_spec=PanelSpec(border_style="red")
            )
        )

        @app.default
        def main(
            opt1: Annotated[str, Parameter(group=simple_group)],
            opt2: Annotated[str, Parameter(group=custom_group)]
        ):
            pass

    See Help Customization for detailed examples.

  sort_key: Any = None

    Modifies group-panel display order on the help-page.

    1. If `sort_key` is a generator, it will be consumed immediately with `next()` to get the actual value.

    2. If `sort_key`, or any of it's contents, are `Callable`, then invoke it `sort_key(group)` and apply the rules below.

    3. The `App` default groups (`App.group_command`, `App.group_arguments`, `App.group_parameters`) will be displayed first. If you want to further customize the ordering of these default groups, you can define custom values and they will be treated like any other group:

           from cyclopts import App, Group

           app = App(
               group_parameters=Group("Parameters", sort_key=1),
               group_arguments=Group("Arguments", sort_key=2),
               group_commands=Group("Commands", sort_key=3),
           )

           @app.default
           def main(foo, /, bar):
               pass

           if __name__ == "__main__":
               app()

    >     $ python main.py --help
    >     Usage: main [ARGS] [OPTIONS]

    >     ╭─ Parameters ──────────────────────────────────────────────────────────╮
    >     │ *  BAR --bar  [required]                                              │
    >     ╰───────────────────────────────────────────────────────────────────────╯
    >     ╭─ Arguments ───────────────────────────────────────────────────────────╮
    >     │ *  FOO  [required]                                                    │
    >     ╰───────────────────────────────────────────────────────────────────────╯
    >     ╭─ Commands ────────────────────────────────────────────────────────────╮
    >     │ --help -h  Display this message and exit.                             │
    >     │ --version  Display application version.                               │
    >     ╰───────────────────────────────────────────────────────────────────────╯

    4. For all groups with `sort_key!=None`, sort them by `(sort_key, group.name)`. That is, sort them by their `sort_key`, and then break ties alphabetically. It is the user's responsibility that `sort_key` are comparable.

    5. For all groups with `sort_key==None` (default value), sort them alphabetically after (4), `App.group_commands`, `App.group_arguments`, and `App.group_parameters`.

    Example usage:

        from cyclopts import App, Group

        app = App()

        @app.command(group=Group("4", sort_key=5))
        def cmd1():
            pass

        @app.command(group=Group("3", sort_key=lambda x: 10))
        def cmd2():
            pass

        @app.command(group=Group("2", sort_key=lambda x: None))
        def cmd3():
            pass

        @app.command(group=Group("1"))
        def cmd4():
            pass

        app()

    Resulting help-page:

        Usage: app COMMAND

        ╭─ 4 ────────────────────────────────────────────────────────────────╮
        │ cmd1                                                               │
        ╰────────────────────────────────────────────────────────────────────╯
        ╭─ 3 ────────────────────────────────────────────────────────────────╮
        │ cmd2                                                               │
        ╰────────────────────────────────────────────────────────────────────╯
        ╭─ 1 ────────────────────────────────────────────────────────────────╮
        │ cmd4                                                               │
        ╰────────────────────────────────────────────────────────────────────╯
        ╭─ 2 ────────────────────────────────────────────────────────────────╮
        │ cmd3                                                               │
        ╰────────────────────────────────────────────────────────────────────╯
        ╭─ Commands ─────────────────────────────────────────────────────────╮
        │ --help,-h  Display this message and exit.                          │
        │ --version  Display application version.                            │
        ╰────────────────────────────────────────────────────────────────────╯

  default_parameter: Parameter | None = None

    Default `Parameter` in the parameter-resolution-stack that goes between `App.default_parameter` and the function signature's `Annotated` `Parameter`. The provided `Parameter` is not allowed to have a `group` value.

  validator: Callable | None = None

    A function (or list of functions) that validates an `ArgumentCollection`.

    Example usage:

        def validator(argument_collection: ArgumentCollection):
            "Raise an exception if something is invalid."

    The `ArgumentCollection` will contain all arguments that belong to that group. The validator(s) will always be invoked, regardless if any argument within the collection has token(s).

    Validators are not invoked for command groups.

  classmethod create_ordered(name='', help='', *, show=None, sort_key=None, validator=None, default_parameter=None, help_formatter=None) → Self

    Create a group with a globally incrementing `sort_key`.

    Used to create a group that will be displayed after a previously instantiated `Group.create_ordered()` group on the help-page.

    Parameters:

      - name (str) -- Group name used for the help-page and for group-referenced-by-string. This is a title, so the first character should be capitalized. If a name is not specified, it will not be shown on the help-page.

      - help (str) -- Additional documentation shown on the help-page. This will be displayed inside the group's panel, above the parameters/commands.

      - show (bool | None) -- Show this group on the help-page. Defaults to `None`, which will only show the group if a `name` is provided.

      - sort_key (Any) -- If provided, prepended to the globally incremented counter value (i.e. has priority during sorting).

      - validator (None | Callable[[ArgumentCollection], Any] | Iterable[Callable[[ArgumentCollection], Any]]) -- Group validator to collectively apply.

      - default_parameter (cyclopts.Parameter | None) -- Default parameter for elements within the group.

      - help_formatter (cyclopts.help.protocols.HelpFormatter | None) -- Custom help formatter for this group's help display.

class cyclopts.Token(*, keyword: str | None = None, value: str = '', source: str = '', index: int = 0, keys: tuple[str, ...]=(), implicit_value: Any = <UNSET>)

  Tracks how a user supplied a value to the application.

  keyword: str | None = None

    Unadulterated user-supplied keyword like `--foo` or `--foo.bar.baz`; `None` when token was pared positionally. Could also be something like `tool.project.foo` if from non-cli sources.

  value: str = ""

    The parsed token value (unadulterated).

  source: str = ""

    Where the token came from; used for error message purposes. Cyclopts uses the string `cli` for cli-parsed tokens.

  index: int = 0

    The relative positional index in which the value was provided.

  keys: tuple[str, ...] = ()

    The additional parsed python variable keys from `keyword`.

    Only used for Arguments that take arbitrary keys.

  implicit_value: Any = cyclopts.UNSET

    Final value that should be used instead of converting from `value`.

    Commonly used for boolean flags.

    Ignored if `UNSET`.

class cyclopts.field_info.FieldInfo(names: tuple[str, ...] = (), kind: _ParameterKind = _ParameterKind.POSITIONAL_OR_KEYWORD, *, required: bool = False, default: Any, annotation: Any, help: str | None = None)

  Extension of `inspect.Parameter`.

class cyclopts.Argument(*, tokens: list[Token] = NOTHING, field_info: FieldInfo = NOTHING, parameter: Parameter = NOTHING, hint: Any = <class 'str'>, index: int | None = None, keys: tuple[str, ...]=(), value: Any = <UNSET>)

  Encapsulates functionality and additional contextual information for parsing a parameter.

  An argument is defined as anything that would have its own entry in the help page.

  tokens: list[Token]

    List of `Token` parsed from various sources. Do not directly mutate; see `append()`.

  field_info: FieldInfo

    Additional information about the parameter from surrounding python syntax.

  parameter: Parameter

    Fully resolved user-provided `Parameter`.

  hint: Any

    The type hint for this argument; may be different from `FieldInfo.annotation`.

  index: int | None

    Associated python positional index for argument. If `None`, then cannot be assigned positionally.

  keys: tuple[str, ...]

    Python keys that lead to this leaf.

    `self.parameter.name` and `self.keys` can naively disagree! For example, a `self.parameter.name="--foo.bar.baz"` could be aliased to "--fizz". The resulting `self.keys` would be `("bar", "baz")`.

    This is populated based on type-hints and class-structure, not `Parameter.name`.

        from cyclopts import App, Parameter
        from dataclasses import dataclass
        from typing import Annotated

        app = App()

        @dataclass
        class User:
            id: int
            name: Annotated[str, Parameter(name="--fullname")]

        @app.default
        def main(user: User):
            pass

        for argument in app.assemble_argument_collection():
            print(f"name: {argument.name:16} hint: {str(argument.hint):16} keys: {str(argument.keys)}")

        $ my-script
        name: --user.id        hint: <class 'int'>    keys: ('id',)
        name: --fullname       hint: <class 'str'>    keys: ('name',)

  children: ArgumentCollection

    Collection of other `Argument` that eventually culminate into the python variable represented by `field_info`.

  property value

    Converted value from last `convert()` call.

    This value may be stale if fields have changed since last `convert()` call. `UNSET` if `convert()` has not yet been called with tokens.

  property show_default: bool | str | Callable[[Any], str]

    Show the default value on the help page.

  match(term: str | int, *, transform: Callable[[str], str] | None = None, delimiter: str = '.') → tuple[tuple[str, ...], Any]

    Match a name search-term, or a positional integer index.

    Raises:

      ValueError -- If no match is found.

    Returns:

      - tuple[str, ...] -- Leftover keys after matching to this argument. Used if this argument accepts_arbitrary_keywords.

      - Any -- Implicit value. `UNSET` if no implicit value is applicable.

  append(token: Token)

    Safely add a `Token`.

  property has_tokens: bool

    This argument, or a child argument, has at least 1 parsed token.

  property children_recursive: ArgumentCollection
  convert(converter: Callable | None = None)

    Converts `tokens` into `value`.

    Parameters:

      converter (Callable | None) -- Converter function to use. Overrides `self.parameter.converter`

    Returns:

      The converted data. Same as `value`.

    Return type:

      Any

  validate(value)

    Validates provided value.

    Parameters:

      value -- Value to validate.

    Returns:

      The converted data. Same as `value`.

    Return type:

      Any

  convert_and_validate(converter: Callable | None = None)

    Converts and validates `tokens` into `value`.

    Parameters:

      converter (Callable | None) -- Converter function to use. Overrides `self.parameter.converter`

    Returns:

      The converted data. Same as `value`.

    Return type:

      Any

  token_count(keys: tuple[str, ...] = ())

    The number of string tokens this argument consumes.

    Parameters:

      keys (tuple[str, ...]) -- The python keys into this argument. If provided, returns the number of string tokens that specific data type within the argument consumes.

    Returns:

      - int -- Number of string tokens to create 1 element.

      - consume_all (bool) -- `True` if this data type is iterable.

  property negatives

    Negative flags from `Parameter.get_negatives()`.

  property name: str

    The first provided name this argument goes by.

  property names: tuple[str, ...]

    Names the argument goes by (both positive and negative).

  env_var_split(value: str, delimiter: str | None = None) → list[str]

    Split a given value with `Parameter.env_var_split()`.

  property show: bool

    Show this argument on the help page.

    If an argument has child arguments, don't show it on the help-page. Returns False for arguments that won't be parsed (including underscore-prefixed params).

  property parse: bool

    Whether this argument should be parsed from CLI tokens.

    If `Parameter.parse` is a regex pattern, parse if the pattern matches the field name; otherwise don't parse.

  property required: bool

    Whether or not this argument requires a user-provided value.

  is_positional_only() → bool
  is_var_positional() → bool
  is_flag() → bool

    Check if this argument is a flag (consumes no CLI tokens).

    Flags are arguments that don't consume command-line tokens after the option name. They typically have implicit values (e.g., --verbose for bool, --no-items for list).

    Returns:

      True if the argument consumes zero tokens from the command line.

    Return type:

      bool

    Examples

        >>> from cyclopts import Parameter
        >>> bool_arg = Argument(hint=bool, parameter=Parameter(name="--verbose"))
        >>> bool_arg.is_flag()
        True
        >>> str_arg = Argument(hint=str, parameter=Parameter(name="--name"))
        >>> str_arg.is_flag()
        False

  get_choices(force: bool = False) → tuple[str, ...] | None

    Extract completion choices from type hint.

    Extracts choices from Literal types, Enum types, and Union types containing them. Respects the Parameter.show_choices setting unless force=True.

    Parameters:

      force (bool) -- If True, return choices even when show_choices=False. Used by shell completion to always provide choices.

    Returns:

      Tuple of choice strings if choices exist and should be shown, None otherwise.

    Return type:

      tuple[str, ...] | None

    Examples

        >>> argument = Argument(hint=Literal["dev", "staging", "prod"], parameter=Parameter(show_choices=True))
        >>> argument.get_choices()
        ('dev', 'staging', 'prod')
        >>> argument = Argument(hint=Literal["dev", "staging", "prod"], parameter=Parameter(show_choices=False))
        >>> argument.get_choices()  # Returns None for help text
        >>> argument.get_choices(force=True)  # Returns choices for completion
        ('dev', 'staging', 'prod')

class cyclopts.ArgumentCollection(*args)

  A list-like container for `Argument`.

  copy() → ArgumentCollection

    Returns a shallow copy of the `ArgumentCollection`.

  __contains__(item: object, /) → bool

    Check if an argument or argument name exists in the collection.

    Parameters:

      item (Argument | str) -- Either an Argument object or a string name/alias to search for.

    Returns:

      True if the item is in the collection.

    Return type:

      bool

    Examples

        >>> argument_collection = ArgumentCollection(
        ...     [
        ...         Argument(parameter=Parameter(name="--foo")),
        ...         Argument(parameter=Parameter(name=("--bar", "-b"))),
        ...     ]
        ... )
        >>> "--foo" in argument_collection
        True
        >>> "-b" in argument_collection  # Alias matching
        True
        >>> "--baz" in argument_collection
        False

  get(term: str | int, default: type[<UNSET>] = <UNSET>, *, transform: ~collections.abc.Callable[[str], str] | None = None, delimiter: str = '.') → Argument
  get(term: str | int, default: T, *, transform: Callable[[str], str] | None = None, delimiter: str = '.') → Argument | T

    Get an `Argument` by name or index.

    This is a convenience wrapper around `match()` that returns just the `Argument` object instead of a tuple.

    Parameters:

      - term (str | int) -- Either a string keyword or an integer positional index.

      - default (Any) -- Default value to return if term not found. If `UNSET` (default), will raise `KeyError`/`IndexError`.

      - transform (Callable[[str], str] | None) -- Optional function to transform string terms before matching.

      - delimiter (str) -- Delimiter for nested field access.

    Returns:

      The matched `Argument`, or `default` if provided and not found.

    Return type:

      Argument | None

    Raises:

      - KeyError -- If `term` is a string and not found (when `default` is `UNSET`).

      - IndexError -- If `term` is an int and is out-of-range (when `default` is `UNSET`).

    See also

    `match()`

      Returns a tuple of (`Argument`, keys, value) with more detailed information.

  match(term: str | int, *, transform: Callable[[str], str] | None = None, delimiter: str = '.') → tuple[Argument, tuple[str, ...], Any]

    Matches CLI keyword or index to their `Argument`.

    Parameters:

      term (str | int) --

      One of:

      - `str` keyword like `"--foo"` or `"-f"` or `"--foo.bar.baz"`.

      - `int` global positional index.

    Raises:

      ValueError -- If the provided `term` doesn't match.

    Returns:

      - Argument -- Matched `Argument`.

      - tuple[str, ...] -- Python keys into `Argument`. Non-empty iff `Argument` accepts keys.

      - Any -- Implicit value (if a flag). `UNSET` otherwise.

  property groups
  filter_by(*, group: Group | None = None, has_tokens: bool | None = None, has_tree_tokens: bool | None = None, keys_prefix: tuple[str, ...] | None = None, kind: _ParameterKind | None = None, parse: bool | None = None, show: bool | None = None, value_set: bool | None = None) → ArgumentCollection

    Filter the `ArgumentCollection`.

    All non-None filters will be applied.

    Parameters:

      - group (Group | None) -- The `Group` the arguments should be in.

      - has_tokens (bool | None) -- Immediately has tokens (not including children).

      - has_tree_tokens (bool | None) -- `Argument` and/or it's children have parsed tokens.

      - kind (inspect._ParameterKind | None) -- The `kind` of the argument.

      - parse (bool | None) -- If the argument is intended to be parsed or not.

      - show (bool | None) -- The `Argument` is intended to be show on the help page.

      - value_set (bool | None) -- The converted value is set.

class cyclopts.UNSET

  Special sentinel value indicating that no data was provided. Do not instantiate.

cyclopts.default_name_transform(s: str) → str

  Converts a python identifier into a CLI token.

  Performs the following operations (in order):

  1. Convert PascalCase to snake_case.

  2. Convert the string to all lowercase.

  3. Replace `_` with `-`.

  4. Strip any leading/trailing `-` (also stripping `_`, due to point 3).

  Intended to be used with `App.name_transform` and `Parameter.name_transform`.

  Parameters:

    s (str) -- Input python identifier string.

  Returns:

    Transformed name.

  Return type:

    str

cyclopts.env_var_split(type_: Any, val: str, *, delimiter: str | None = None) → list[str]

  Type-dependent environment variable value splitting.

  Converts a single string into a list of strings. Splits when:

  - The `type_` is some variant of `Iterable[pathlib.Path]` objects. If Windows, split on `;`, otherwise split on `:`.

  - Otherwise, if the `type_` is an `Iterable`, split on whitespace. Leading/trailing whitespace of each output element will be stripped.

  This function is the default value for `cyclopts.App.env_var_split`.

  Parameters:

    - type (type) -- Type hint that we will eventually coerce into.

    - val (str) -- String to split.

    - delimiter (str | None) -- Delimiter to split `val` on. If None, defaults to whitespace.

  Returns:

    List of individual string tokens.

  Return type:

    list[str]

cyclopts.edit(initial_text: str = '', *, fallback_editors: Sequence[str] = ('nano', 'vim', 'notepad', 'gedit'), editor_args: Sequence[str] = (), path: str | Path = '', encoding: str = 'utf-8', save: bool = True, required: bool = True) → str

  Get text input from a user by launching their default text editor.

  Parameters:

    - initial_text (str) -- Initial text to populate the text file with.

    - fallback_editors (Sequence[str]) -- If the text editor cannot be determined from the environment variable `EDITOR`, attempt to use these text editors in the order provided.

    - editor_args (Sequence[str]) -- Additional CLI arguments that are passed along to the editor-launch command.

    - path (Union[str, Path]) -- If specified, the path to the file that should be opened. Text editors typically display this, so a custom path may result in a better user-interface. Defaults to a temporary text file.

    - encoding (str) -- File encoding to use.

    - save (bool) -- Require the user to save before exiting the editor. Otherwise raises `EditorDidNotSaveError`.

    - required (bool) -- Require for the saved text to be different from `initial_text`. Otherwise raises `EditorDidNotChangeError`.

  Raises:

    - EditorError -- Base editor error exception. Explicitly raised if editor subcommand returned a non-zero exit code.

    - EditorNotFoundError -- A suitable text editor could not be found.

    - EditorDidNotSaveError -- The user exited the text-editor without saving and `save=True`.

    - EditorDidNotChangeError -- The user did not change the file contents and `required=True`.

  Returns:

    The resulting text that was saved by the text editor.

  Return type:

    str

cyclopts.run(callable: Callable[[...], Coroutine[None, None, V]], /, *, result_action: Literal['return_value']) → V
cyclopts.run(callable: Callable[[...], V], /, *, result_action: Literal['return_value']) → V
cyclopts.run(callable: Callable[[...], Coroutine[None, None, Any]], /, *, result_action: Literal['return_value', 'call_if_callable', 'print_non_int_return_int_as_exit_code', 'print_str_return_int_as_exit_code', 'print_str_return_zero', 'print_non_none_return_int_as_exit_code', 'print_non_none_return_zero', 'return_int_as_exit_code_else_zero', 'print_non_int_sys_exit', 'sys_exit', 'return_none', 'return_zero', 'print_return_zero', 'sys_exit_zero', 'print_sys_exit_zero'] | Callable[[Any], Any] | Iterable[Literal['return_value', 'call_if_callable', 'print_non_int_return_int_as_exit_code', 'print_str_return_int_as_exit_code', 'print_str_return_zero', 'print_non_none_return_int_as_exit_code', 'print_non_none_return_zero', 'return_int_as_exit_code_else_zero', 'print_non_int_sys_exit', 'sys_exit', 'return_none', 'return_zero', 'print_return_zero', 'sys_exit_zero', 'print_sys_exit_zero'] | Callable[[Any], Any]] | None = None) → Any
cyclopts.run(callable: Callable[[...], Any], /, *, result_action: Literal['return_value', 'call_if_callable', 'print_non_int_return_int_as_exit_code', 'print_str_return_int_as_exit_code', 'print_str_return_zero', 'print_non_none_return_int_as_exit_code', 'print_non_none_return_zero', 'return_int_as_exit_code_else_zero', 'print_non_int_sys_exit', 'sys_exit', 'return_none', 'return_zero', 'print_return_zero', 'sys_exit_zero', 'print_sys_exit_zero'] | Callable[[Any], Any] | Iterable[Literal['return_value', 'call_if_callable', 'print_non_int_return_int_as_exit_code', 'print_str_return_int_as_exit_code', 'print_str_return_zero', 'print_non_none_return_int_as_exit_code', 'print_non_none_return_zero', 'return_int_as_exit_code_else_zero', 'print_non_int_sys_exit', 'sys_exit', 'return_none', 'return_zero', 'print_return_zero', 'sys_exit_zero', 'print_sys_exit_zero'] | Callable[[Any], Any]] | None = None) → Any

  Run the given callable as a CLI command.

  The callable may also be a coroutine function. This function is syntax sugar for very simple use cases, and is roughly equivalent to:

      from cyclopts import App

      app = App()
      app.default(callable)
      app()

  Parameters:

    - callable -- The function to execute as a CLI command.

    - result_action -- How to handle the command's return value. If not specified, uses the default `"print_non_int_sys_exit"` which calls `sys.exit()` with the appropriate code. Can be set to `"return_value"` to return the result directly for testing/embedding.

    - usage (Example)

    - code-block: (..) --

      python: import cyclopts

      def main(name: str, age: int):

        print(f"Hello {name}, you are {age} years old.")

      cyclopts.run(main)

cyclopts.resolve_returncode(result: Any, default: int = 0) → int

  Resolve the return code for `result`.

  If `result` defines `__cyclopts_returncode__` (a zero-argument callable), its value is used. Otherwise `default` is returned.

  Custom `result_action` callables can use this helper to honor the `__cyclopts_returncode__` protocol consistently with the built-in actions.

  Parameters:

    - result (Any) -- The command's return value.

    - default (int) -- Fallback exit code when `result` doesn't define a callable `__cyclopts_returncode__`. Defaults to `0`.

  Returns:

    The resolved return code.

  Return type:

    int

class cyclopts.CycloptsPanel(message: Any, title: str = 'Error', style: str = 'red')

  Create a `Panel` with a consistent style.

  The resulting panel can be displayed using a `Console`.

      ╭─ Title ──────────────────────────────────╮
      │ Message content here.                    │
      ╰──────────────────────────────────────────╯

  Parameters:

    - message (Any) -- The body of the panel will be filled with the stringified version of the message.

    - title (str) -- Title of the panel that appears in the top-left corner.

    - style (str) -- Rich style for the panel border.

  Returns:

    Formatted panel object.

  Return type:

    Panel

## Validators

Cyclopts has several builtin validators for common CLI inputs.

class cyclopts.validators.LimitedChoice(min: int = 0, max: int | None = None, allow_none: bool = False)

  Group validator that limits the number of selections per group.

  Commonly used for enforcing mutually-exclusive parameters (default behavior).

  Parameters:

    - min (int) -- The minimum (inclusive) number of CLI parameters allowed. If negative, then all parameters in the group must have CLI values provided.

    - max (int | None) -- The maximum (inclusive) number of CLI parameters allowed. Defaults to `1` if `min==0`, `min` otherwise.

    - allow_none (bool) -- If `True`, also allow 0 CLI parameters (even if `min` is greater than 0). Defaults to `False`.

class cyclopts.validators.MutuallyExclusive

  Alias for `LimitedChoice` to make intentions more obvious.

  Only 1 argument in the group can be supplied a value.

cyclopts.validators.mutually_exclusive = <cyclopts.validators._group.MutuallyExclusive object>

  Instantiated version of `MutuallyExclusive`. Can be used directly in group validators:

      import cyclopts
      from cyclopts import Group

      mutually_exclusive_group = Group(validator=cyclopts.validators.mutually_exclusive)

cyclopts.validators.all_or_none = <cyclopts.validators._group.LimitedChoice object>

  Group validator that enforces that either all parameters in the group must be supplied an argument, or none of them.

class cyclopts.validators.Number(*, lt: int | float | None = None, lte: int | float | None = None, gt: int | float | None = None, gte: int | float | None = None, modulo: int | float | None = None)

  Limit input number to a value range.

  Example Usage:

      from cyclopts import App, Parameter, validators
      from typing import Annotated

      app = App()

      @app.default
      def main(age: Annotated[int, Parameter(validator=validators.Number(gte=0, lte=150))]):
          print(f"You are {age} years old.")

      app()

      $ my-script 100
      You are 100 years old.

      $ my-script -1
      ╭─ Error ───────────────────────────────────────────────────────╮
      │ Invalid value "-1" for "AGE". Must be >= 0.                   │
      ╰───────────────────────────────────────────────────────────────╯

      $ my-script 200
      ╭─ Error ───────────────────────────────────────────────────────╮
      │ Invalid value "200" for "AGE". Must be <= 150.                │
      ╰───────────────────────────────────────────────────────────────╯

  lt: int | float | None

    Input value must be less than this value.

  lte: int | float | None

    Input value must be less than or equal this value.

  gt: int | float | None

    Input value must be greater than this value.

  gte: int | float | None

    Input value must be greater than or equal this value.

  modulo: int | float | None

    Input value must be a multiple of this value.

class cyclopts.validators.Path(*, exists: bool = False, file_okay: bool = True, dir_okay: bool = True, ext: str | Iterable[str] | None = None)

  Assertions on properties of `pathlib.Path`.

  Example Usage:

      from cyclopts import App, Parameter, validators
      from pathlib import Path
      from typing import Annotated

      app = App()

      @app.default
      def main(
          # ``src`` must be a file that exists.
          src: Annotated[Path, Parameter(validator=validators.Path(exists=True, dir_okay=False))],
          # ``dst`` must be a path that does **not** exist.
          dst: Annotated[Path, Parameter(validator=validators.Path(dir_okay=False, file_okay=False))],
      ):
          "Copies src->dst."
          dst.write_bytes(src.read_bytes())

      app()

      $ my-script foo.bin bar.bin  # if foo.bin does not exist
      ╭─ Error ───────────────────────────────────────────────────────╮
      │ Invalid value "foo.bin" for "SRC". "foo.bin" does not exist.  │
      ╰───────────────────────────────────────────────────────────────╯

      $ my-script foo.bin bar.bin  # if bar.bin exists
      ╭─ Error ───────────────────────────────────────────────────────╮
      │ Invalid value "bar.bin" for "DST". "bar.bin" already exists.  │
      ╰───────────────────────────────────────────────────────────────╯

  exists: bool

    If `True`, specified path must exist. Defaults to `False`.

  file_okay: bool

    If path exists, check it's type:

    - If `True`, specified path may be an existing file.

    - If `False`, then existing files are not allowed.

    Defaults to `True`.

  dir_okay: bool

    If path exists, check it's type:

    - If `True`, specified path may be an existing directory.

    - If `False`, then existing directories are not allowed.

    Defaults to `True`.

  ext: str | Sequence[str]

    Supplied path must have this extension (case insensitive). May or may not include the ".".

## Types

Cyclopts has builtin pre-defined annotated-types for common conversion and validation configurations. Most definitions in this section are simply predefined annotations for convenience:

    Annotated[..., Parameter(...)]

Custom classes that provide additional functionality beyond simple annotations will be noted.

Due to Cyclopts's advanced `Parameter` resolution engine, these annotations can themselves be annotated to further configure behavior. E.g:

    Annotated[PositiveInt, Parameter(...)]

### Path

`Path` annotated types for checking existence, type, and performing path-resolution. All of these types will also work on sequence of paths (e.g. `tuple[Path, Path]` or `list[Path]`).

class cyclopts.types.StdioPath

  Note

  This is a custom class, not a simple `Annotated` type alias.

  Requires Python 3.12+ due to `Path` subclassing support.

  A `Path` subclass that treats `-` as stdin (for reading) or stdout (for writing). This follows common Unix convention.

  `StdioPath` is pre-configured with `allow_leading_hyphen=True`, so `-` can be passed as an argument without being interpreted as an option.

  STDIO_STRING: str = "-"

    Class attribute defining the string that triggers stdio behavior. Override in subclasses to use a different string.

  is_stdio: bool

    Returns `True` if this path represents stdin/stdout (i.e., `str(self) == STDIO_STRING`). Override this property in subclasses for custom matching logic (e.g., matching multiple strings).

  Basic usage:

      from cyclopts import App
      from cyclopts.types import StdioPath

      app = App()

      @app.default
      def main(input_file: StdioPath):
          data = input_file.read_text()
          print(data.upper())

      app()

      $ echo "hello" | python my_script.py -
      HELLO

      $ python my_script.py data.txt
      <contents of data.txt uppercased>

  To default to stdin/stdout when no argument is provided:

      @app.default
      def main(input_file: StdioPath = StdioPath("-")):
          data = input_file.read_text()
          print(data.upper())

  See Reading/Writing From File or Stdin/Stdout for more examples.

  Subclassing

  To use a different trigger string or custom matching logic, subclass `StdioPath`:

      from cyclopts.types import StdioPath

      # Simple: different trigger string
      class StdinPath(StdioPath):
          STDIO_STRING = "STDIN"

      class StdoutPath(StdioPath):
          STDIO_STRING = "STDOUT"

      # Advanced: match multiple strings
      class MultiStdioPath(StdioPath):
          @property
          def is_stdio(self) -> bool:
              return str(self) in ("-", "STDIN", "STDOUT")

cyclopts.types.ExistingPath

  A `Path` file or directory that must exist.

  alias of `Annotated`[`Path`, Parameter(validator=(Path(exists=True, file_okay=True, dir_okay=True, ext=()),))]

cyclopts.types.NonExistentPath

  A `Path` file or directory that must not exist.

  alias of `Annotated`[`Path`, Parameter(validator=(Path(exists=False, file_okay=False, dir_okay=False, ext=()),))]

cyclopts.types.ResolvedPath

  A `Path` file or directory. `resolve()` is invoked prior to returning the path.

  alias of `Annotated`[`Path`, Parameter(converter=<function _path_resolve_converter at 0x701a4c97b110>)]

cyclopts.types.ResolvedExistingPath

  A `Path` file or directory that must exist. `resolve()` is invoked prior to returning the path.

  alias of `Annotated`[`Path`, Parameter(validator=(Path(exists=True, file_okay=True, dir_okay=True, ext=()),)), Parameter(converter=<function _path_resolve_converter at 0x701a4c97b110>)]

cyclopts.types.Directory

  A `Path` that must be a directory (or not exist).

  alias of `Annotated`[`Path`, Parameter(validator=(Path(exists=False, file_okay=False, dir_okay=True, ext=()),))]

cyclopts.types.ExistingDirectory

  A `Path` directory that must exist.

  alias of `Annotated`[`Path`, Parameter(validator=(Path(exists=True, file_okay=False, dir_okay=True, ext=()),))]

cyclopts.types.NonExistentDirectory

  A `Path` directory that must not exist.

  alias of `Annotated`[`Path`, Parameter(validator=(Path(exists=False, file_okay=False, dir_okay=False, ext=()),))]

cyclopts.types.ResolvedDirectory

  A `Path` directory. `resolve()` is invoked prior to returning the path.

  alias of `Annotated`[`Path`, Parameter(validator=(Path(exists=False, file_okay=False, dir_okay=True, ext=()),)), Parameter(converter=<function _path_resolve_converter at 0x701a4c97b110>)]

cyclopts.types.ResolvedExistingDirectory

  A `Path` directory that must exist. `resolve()` is invoked prior to returning the path.

  alias of `Annotated`[`Path`, Parameter(validator=(Path(exists=True, file_okay=False, dir_okay=True, ext=()),)), Parameter(converter=<function _path_resolve_converter at 0x701a4c97b110>)]

cyclopts.types.File

  A `File` that must be a file (or not exist).

  alias of `Annotated`[`Path`, Parameter(validator=(Path(exists=False, file_okay=True, dir_okay=False, ext=()),))]

cyclopts.types.ExistingFile

  A `Path` file that must exist.

  alias of `Annotated`[`Path`, Parameter(validator=(Path(exists=True, file_okay=True, dir_okay=False, ext=()),))]

cyclopts.types.NonExistentFile

  A `Path` file that must not exist.

  alias of `Annotated`[`Path`, Parameter(validator=(Path(exists=False, file_okay=False, dir_okay=False, ext=()),))]

cyclopts.types.ResolvedFile

  A `Path` file. `resolve()` is invoked prior to returning the path.

  alias of `Annotated`[`Path`, Parameter(validator=(Path(exists=False, file_okay=True, dir_okay=False, ext=()),)), Parameter(converter=<function _path_resolve_converter at 0x701a4c97b110>)]

cyclopts.types.ResolvedExistingFile

  A `Path` file that must exist. `resolve()` is invoked prior to returning the path.

  alias of `Annotated`[`Path`, Parameter(validator=(Path(exists=True, file_okay=True, dir_okay=False, ext=()),)), Parameter(converter=<function _path_resolve_converter at 0x701a4c97b110>)]

cyclopts.types.BinPath

  A `Path` that must have extension `bin`.

  alias of `Annotated`[`Path`, Parameter(validator=(Path(exists=False, file_okay=True, dir_okay=False, ext=('bin',)),))]

cyclopts.types.ExistingBinPath

  A `Path` that must exist and have extension `bin`.

  alias of `Annotated`[`Path`, Parameter(validator=(Path(exists=True, file_okay=True, dir_okay=False, ext=('bin',)),))]

cyclopts.types.NonExistentBinPath

  A `Path` that must not exist and have extension `bin`.

  alias of `Annotated`[`Path`, Parameter(validator=(Path(exists=False, file_okay=False, dir_okay=False, ext=('bin',)),))]

cyclopts.types.CsvPath

  A `Path` that must have extension `csv`.

  alias of `Annotated`[`Path`, Parameter(validator=(Path(exists=False, file_okay=True, dir_okay=False, ext=('csv',)),))]

cyclopts.types.ExistingCsvPath

  A `Path` that must exist and have extension `csv`.

  alias of `Annotated`[`Path`, Parameter(validator=(Path(exists=True, file_okay=True, dir_okay=False, ext=('csv',)),))]

cyclopts.types.NonExistentCsvPath

  A `Path` that must not exist and have extension `csv`.

  alias of `Annotated`[`Path`, Parameter(validator=(Path(exists=False, file_okay=False, dir_okay=False, ext=('csv',)),))]

cyclopts.types.TxtPath

  A `Path` that must have extension `txt`.

  alias of `Annotated`[`Path`, Parameter(validator=(Path(exists=False, file_okay=True, dir_okay=False, ext=('txt',)),))]

cyclopts.types.ExistingTxtPath

  A `Path` that must exist and have extension `txt`.

  alias of `Annotated`[`Path`, Parameter(validator=(Path(exists=True, file_okay=True, dir_okay=False, ext=('txt',)),))]

cyclopts.types.NonExistentTxtPath

  A `Path` that must not exist and have extension `txt`.

  alias of `Annotated`[`Path`, Parameter(validator=(Path(exists=False, file_okay=False, dir_okay=False, ext=('txt',)),))]

cyclopts.types.ImagePath

  A `Path` that must have extension in {`png`, `jpg`, `jpeg`}.

  alias of `Annotated`[`Path`, Parameter(validator=(Path(exists=False, file_okay=True, dir_okay=False, ext=('png', 'jpg', 'jpeg')),))]

cyclopts.types.ExistingImagePath

  A `Path` that must exist and have extension in {`png`, `jpg`, `jpeg`}.

  alias of `Annotated`[`Path`, Parameter(validator=(Path(exists=True, file_okay=True, dir_okay=False, ext=('png', 'jpg', 'jpeg')),))]

cyclopts.types.NonExistentImagePath

  A `Path` that must not exist and have extension in {`png`, `jpg`, `jpeg`}.

  alias of `Annotated`[`Path`, Parameter(validator=(Path(exists=False, file_okay=False, dir_okay=False, ext=('png', 'jpg', 'jpeg')),))]

cyclopts.types.Mp4Path

  A `Path` that must have extension `mp4`.

  alias of `Annotated`[`Path`, Parameter(validator=(Path(exists=False, file_okay=True, dir_okay=False, ext=('mp4',)),))]

cyclopts.types.ExistingMp4Path

  A `Path` that must exist and have extension `mp4`.

  alias of `Annotated`[`Path`, Parameter(validator=(Path(exists=True, file_okay=True, dir_okay=False, ext=('mp4',)),))]

cyclopts.types.NonExistentMp4Path

  A `Path` that must not exist and have extension `mp4`.

  alias of `Annotated`[`Path`, Parameter(validator=(Path(exists=False, file_okay=False, dir_okay=False, ext=('mp4',)),))]

cyclopts.types.JsonPath

  A `Path` that must have extension `json`.

  alias of `Annotated`[`Path`, Parameter(validator=(Path(exists=False, file_okay=True, dir_okay=False, ext=('json',)),))]

cyclopts.types.ExistingJsonPath

  A `Path` that must exist and have extension `json`.

  alias of `Annotated`[`Path`, Parameter(validator=(Path(exists=True, file_okay=True, dir_okay=False, ext=('json',)),))]

cyclopts.types.NonExistentJsonPath

  A `Path` that must not exist and have extension `json`.

  alias of `Annotated`[`Path`, Parameter(validator=(Path(exists=False, file_okay=False, dir_okay=False, ext=('json',)),))]

cyclopts.types.TomlPath

  A `Path` that must have extension `toml`.

  alias of `Annotated`[`Path`, Parameter(validator=(Path(exists=False, file_okay=True, dir_okay=False, ext=('toml',)),))]

cyclopts.types.ExistingTomlPath

  A `Path` that must exist and have extension `toml`.

  alias of `Annotated`[`Path`, Parameter(validator=(Path(exists=True, file_okay=True, dir_okay=False, ext=('toml',)),))]

cyclopts.types.NonExistentTomlPath

  A `Path` that must not exist and have extension `toml`.

  alias of `Annotated`[`Path`, Parameter(validator=(Path(exists=False, file_okay=False, dir_okay=False, ext=('toml',)),))]

cyclopts.types.YamlPath

  A `Path` that must have extension `yaml`.

  alias of `Annotated`[`Path`, Parameter(validator=(Path(exists=False, file_okay=True, dir_okay=False, ext=('yaml',)),))]

cyclopts.types.ExistingYamlPath

  A `Path` that must exist and have extension `yaml`.

  alias of `Annotated`[`Path`, Parameter(validator=(Path(exists=True, file_okay=True, dir_okay=False, ext=('yaml',)),))]

cyclopts.types.NonExistentYamlPath

  A `Path` that must not exist and have extension `yaml`.

  alias of `Annotated`[`Path`, Parameter(validator=(Path(exists=False, file_okay=False, dir_okay=False, ext=('yaml',)),))]

### Number

Annotated types for checking common int/float value constraints. All of these types will also work on sequence of numbers (e.g. `tuple[int, int]` or `list[float]`).

cyclopts.types.PositiveFloat

  A float that must be `>0`.

  alias of `Annotated`[`float`, Parameter(validator=(Number(lt=None, lte=None, gt=0, gte=None, modulo=None),))]

cyclopts.types.NonNegativeFloat

  A float that must be `>=0`.

  alias of `Annotated`[`float`, Parameter(validator=(Number(lt=None, lte=None, gt=None, gte=0, modulo=None),))]

cyclopts.types.NegativeFloat

  A float that must be `<0`.

  alias of `Annotated`[`float`, Parameter(validator=(Number(lt=0, lte=None, gt=None, gte=None, modulo=None),))]

cyclopts.types.NonPositiveFloat

  A float that must be `<=0`.

  alias of `Annotated`[`float`, Parameter(validator=(Number(lt=None, lte=0, gt=None, gte=None, modulo=None),))]

cyclopts.types.NormFloat

  A float in the range `[0, 1]`.

  alias of `Annotated`[`float`, Parameter(validator=(Number(lt=None, lte=1, gt=None, gte=0, modulo=None),))]

cyclopts.types.SignedNormFloat

  A float in the range `[-1, 1]`.

  alias of `Annotated`[`float`, Parameter(validator=(Number(lt=None, lte=1, gt=None, gte=-1, modulo=None),))]

cyclopts.types.PositiveInt

  An int that must be `>0`.

  alias of `Annotated`[`int`, Parameter(validator=(Number(lt=None, lte=None, gt=0, gte=None, modulo=None),))]

cyclopts.types.NonNegativeInt

  An int that must be `>=0`.

  alias of `Annotated`[`int`, Parameter(validator=(Number(lt=None, lte=None, gt=None, gte=0, modulo=None),))]

cyclopts.types.NegativeInt

  An int that must be `<0`.

  alias of `Annotated`[`int`, Parameter(validator=(Number(lt=0, lte=None, gt=None, gte=None, modulo=None),))]

cyclopts.types.NonPositiveInt

  An int that must be `<=0`.

  alias of `Annotated`[`int`, Parameter(validator=(Number(lt=None, lte=0, gt=None, gte=None, modulo=None),))]

cyclopts.types.PercentInt

  An int in the range `[0, 100]`.

  alias of `Annotated`[`int`, Parameter(validator=(Number(lt=None, lte=100, gt=None, gte=0, modulo=None),))]

cyclopts.types.UInt8

  An unsigned 8-bit integer.

  alias of `Annotated`[`int`, Parameter(validator=(Number(lt=None, lte=255, gt=None, gte=0, modulo=None),))]

cyclopts.types.HexUInt8

  An unsigned 8-bit integer who's default value will be displayed as hexadecimal in the help-page.

  alias of `Annotated`[`int`, Parameter(validator=(Number(lt=None, lte=255, gt=None, gte=0, modulo=None),)), Parameter(show_default=functools.partial(<function _hex_formatter at 0x701a4c97bab0>, digits=2))]

cyclopts.types.Int8

  A signed 8-bit integer.

  alias of `Annotated`[`int`, Parameter(validator=(Number(lt=None, lte=127, gt=None, gte=-128, modulo=None),))]

cyclopts.types.UInt16

  An unsigned 16-bit integer.

  alias of `Annotated`[`int`, Parameter(validator=(Number(lt=None, lte=65535, gt=None, gte=0, modulo=None),))]

cyclopts.types.HexUInt16

  An unsigned 16-bit integer who's default value will be displayed as hexadecimal in the help-page.

  alias of `Annotated`[`int`, Parameter(validator=(Number(lt=None, lte=65535, gt=None, gte=0, modulo=None),)), Parameter(show_default=functools.partial(<function _hex_formatter at 0x701a4c97bab0>, digits=4))]

cyclopts.types.Int16

  A signed 16-bit integer.

  alias of `Annotated`[`int`, Parameter(validator=(Number(lt=None, lte=32767, gt=None, gte=-32768, modulo=None),))]

cyclopts.types.UInt32

  An unsigned 32-bit integer.

  alias of `Annotated`[`int`, Parameter(validator=(Number(lt=4294967296, lte=None, gt=None, gte=0, modulo=None),))]

cyclopts.types.HexUInt32

  An unsigned 32-bit integer who's default value will be displayed as hexadecimal in the help-page.

  alias of `Annotated`[`int`, Parameter(validator=(Number(lt=4294967296, lte=None, gt=None, gte=0, modulo=None),)), Parameter(show_default=functools.partial(<function _hex_formatter at 0x701a4c97bab0>, digits=8))]

cyclopts.types.Int32

  A signed 32-bit integer.

  alias of `Annotated`[`int`, Parameter(validator=(Number(lt=2147483648, lte=None, gt=None, gte=-2147483648, modulo=None),))]

cyclopts.types.UInt64

  An unsigned 64-bit integer.

  alias of `Annotated`[`int`, Parameter(validator=(Number(lt=18446744073709551616, lte=None, gt=None, gte=0, modulo=None),))]

cyclopts.types.HexUInt64

  An unsigned 64-bit integer who's default value will be displayed as hexadecimal in the help-page.

  alias of `Annotated`[`int`, Parameter(validator=(Number(lt=18446744073709551616, lte=None, gt=None, gte=0, modulo=None),)), Parameter(show_default=functools.partial(<function _hex_formatter at 0x701a4c97bab0>, digits=16))]

cyclopts.types.Int64

  A signed 64-bit integer.

  alias of `Annotated`[`int`, Parameter(validator=(Number(lt=9223372036854775808, lte=None, gt=None, gte=-9223372036854775808, modulo=None),))]

### Json

Annotated types for parsing a json-string from the CLI.

cyclopts.types.Json

  Parse a json-string from the CLI.

  Note: Since Cyclopts v3.6.0, all dataclass-like classes now natively attempt to parse json-strings, so practical use-case of this annotation is limited.

  Usage example:

      from cyclopts import App, types

      app = App()

      @app.default
      def main(json: types.Json):
          print(json)

      app()

      $ my-script '{"foo": 1, "bar": 2}'
      {'foo': 1, 'bar': 2}

  alias of `Annotated`[`Any`, Parameter(converter=<function _json_converter at 0x701a4c6bcf60>)]

### Web

Annotated types for common web-related values.

cyclopts.types.Email

  An email address string with simple validation.

  alias of `Annotated`[`str`, Parameter(validator=(<function _email_validator at 0x701a4c6bcbf0>,))]

cyclopts.types.Port

  An `int` limited to range `[0, 65535]`.

  alias of `Annotated`[`int`, Parameter(validator=(Number(lt=None, lte=65535, gt=None, gte=0, modulo=None),))]

cyclopts.types.URL

  A `str` URL string with some simple validation.

  alias of `Annotated`[`str`, Parameter(validator=(<function _url_validator at 0x701a4c6bc7d0>,))]

## Help Formatting

Cyclopts provides a flexible help formatting system for customizing the help-page's appearance.

class cyclopts.help.protocols.HelpFormatter(*args, **kwargs)

  Protocol for help formatter functions.

  It's the Formatter's job to transform a `HelpPanel` into rendered text on the display.

  Implementations may optionally provide the following methods for custom rendering of "usage" and "description". If these methods are not provided, default rendering will be used.

      def render_usage(self, console: Console, options: ConsoleOptions, usage: Any) -> None:
          """Render the usage line."""
          ...

      def render_description(self, console: Console, options: ConsoleOptions, description: Any) -> None:
          """Render the description."""
          ...

  __call__(console: Console, options: ConsoleOptions, panel: HelpPanel) → None

    Format and render a single help panel.

    Parameters:

      - console (Console) -- Console to render to.

      - options (ConsoleOptions) -- Console rendering options.

      - panel (HelpPanel) -- Help panel to render (commands, parameters, etc).

class cyclopts.help.DefaultFormatter(*, panel_spec: PanelSpec | None = None, table_spec: TableSpec | None = None, column_specs: tuple[ColumnSpec, ...] | ColumnSpecBuilder | None = None)

  Default help formatter using Rich library with customizable specs.

  Parameters:

    - panel_spec (Optional[PanelSpec]) -- Panel specification for the outer box/panel styling.

    - table_spec (Optional[TableSpec]) -- Table specification for table styling (borders, padding, etc).

    - column_specs (Optional[Union[tuple[ColumnSpec, ...], ColumnSpecBuilder]]) -- Column specifications or builder function for table columns.

  Notes

  The relationship between these specs can be visualized as:

      ╭─ Commands ───────────────────────────────────────────────────────╮  ← panel_spec
      │ serve     Start the development server                           │     (border, title)
      │ --help    Display this message and exit.                         │
      ╰──────────────────────────────────────────────────────────────────╯
       ↑         ↑
       col[0]    col[1]
       (name)    (description)

      ╭─ Parameters ─────────────────────────────────────────────────────╮  ← panel_spec
      │ *  PORT --port        Server port number [required]              │
      │    VERBOSE --verbose  Enable verbose output [default: False]     │
      ╰──────────────────────────────────────────────────────────────────╯
       ↑  ↑                  ↑
       │  col[1]             col[2]
       │  (name/flags)       (description)
       │
       col[0]
       (required marker)

  Where:

  - `panel_spec` controls the outer panel appearance (border, title, etc.)

  - `table_spec` controls the inner table styling (no visible borders by default)

  - `column_specs` defines individual columns (width, style, alignment, etc.)

  panel_spec: PanelSpec | None

    Panel specification for the outer box/panel styling (border, title, padding, etc).

  table_spec: TableSpec | None

    Table specification for table styling (borders, padding, column separation, etc).

  column_specs: tuple[ColumnSpec, ...] | ColumnSpecBuilder | None

    Column specifications or builder function for table columns (width, style, alignment, etc).

  classmethod with_newline_metadata(**kwargs)

    Create formatter with metadata on separate lines.

    Returns a DefaultFormatter configured to display parameter metadata (choices, env vars, defaults) on separate indented lines rather than inline with descriptions.

    Parameters:

      **kwargs -- Additional keyword arguments to pass to DefaultFormatter constructor.

    Returns:

      Configured formatter instance with newline metadata display.

    Return type:

      DefaultFormatter

    Examples

        >>> from cyclopts import App
        >>> from cyclopts.help import DefaultFormatter
        >>> app = App(help_formatter=DefaultFormatter.with_newline_metadata())

  __call__(console: Console, options: ConsoleOptions, panel: HelpPanel) → None

    Format and render a single help panel using Rich.

    Parameters:

      - console (Console) -- Console to render to.

      - options (ConsoleOptions) -- Console rendering options.

      - panel (HelpPanel) -- Help panel to render.

  render_usage(console: Console, options: ConsoleOptions, usage: Any) → None

    Render the usage line.

    Parameters:

      - console (Console) -- Console to render to.

      - options (ConsoleOptions) -- Console rendering options.

      - usage (Any) -- The usage line (Text or str).

  render_description(console: Console, options: ConsoleOptions, description: Any) → None

    Render the description.

    Parameters:

      - console (Console) -- Console to render to.

      - options (ConsoleOptions) -- Console rendering options.

      - description (Any) -- The description (can be various Rich renderables).

class cyclopts.help.PlainFormatter(indent_width: int = 2, max_width: int | None = None)

  Plain text formatter for improved accessibility.

  Parameters:

    - indent_width (int) -- Number of spaces to indent entries (default: 2).

    - max_width (Optional[int]) -- Maximum line width for wrapping text.

  __call__(console: Console, options: ConsoleOptions, panel: HelpPanel) → None

    Format and render a single help panel as plain text.

    Parameters:

      - console (Console) -- Console to render to.

      - options (ConsoleOptions) -- Console rendering options.

      - panel (HelpPanel) -- Help panel to render.

  render_usage(console: Console, options: ConsoleOptions, usage: Any) → None

    Render the usage line.

    Parameters:

      - console (Console) -- Console to render to.

      - options (ConsoleOptions) -- Console rendering options.

      - usage (Any) -- The usage line (Text or str).

  render_description(console: Console, options: ConsoleOptions, description: Any) → None

    Render the description.

    Parameters:

      - console (Console) -- Console to render to.

      - options (ConsoleOptions) -- Console rendering options.

      - description (Any) -- The description (can be various Rich renderables).

class cyclopts.help.protocols.ColumnSpecBuilder(*args, **kwargs)

  Protocol for ColumnSpecBuilders.

  __call__(console: Console, options: ConsoleOptions, entries: list[HelpEntry]) → tuple[ColumnSpec, ...]

    Build column specifications based on console settings and entries.

    Parameters:

      - console (Console) -- The Rich console instance.

      - options (ConsoleOptions) -- Console rendering options.

      - entries (list[HelpEntry]) -- List of help entries to be displayed.

    Returns:

      Tuple of column specifications for table rendering.

    Return type:

      tuple[ColumnSpec, ...]

class cyclopts.help.PanelSpec(title: RenderableType | None = None, subtitle: RenderableType | None = None, title_align: Literal['left', 'center', 'right'] = 'left', subtitle_align: Literal['left', 'center', 'right'] = 'center', style: StyleType | None = 'none', border_style: StyleType | None = 'none', box: Box | None = None, padding: PaddingDimensions = (0, 1), expand: bool = True, width: int | None = None, height: int | None = None, safe_box: bool | None = None, highlight: bool = False)

  Specification for panel (outer box) styling.

  Used by `DefaultFormatter` to control the appearance of the outer panel that wraps help sections. This spec defines the panel's border, title, subtitle, and overall styling.

  See also

  `DefaultFormatter`

    The formatter that uses these specs.

  `TableSpec`

    Specification for the inner table.

  `ColumnSpec`

    Specification for individual columns.

  title: RenderableType | None

    Title text displayed at the top of the panel.

    Corresponds to the `title` parameter of `Panel`.

  subtitle: RenderableType | None

    Subtitle text displayed at the bottom of the panel.

    Corresponds to the `subtitle` parameter of `Panel`.

  title_align: Literal['left', 'center', 'right']

    Alignment of the title text within the panel.

    Corresponds to the `title_align` parameter of `Panel`.

  subtitle_align: Literal['left', 'center', 'right']

    Alignment of the subtitle text within the panel.

    Corresponds to the `subtitle_align` parameter of `Panel`.

  style: StyleType | None

    Style applied to the panel background.

    Corresponds to the `style` parameter of `Panel`.

  border_style: StyleType | None

    Style applied to the panel border.

    Corresponds to the `border_style` parameter of `Panel`.

  box: Box | None

    Box drawing style for the panel border.

    Corresponds to the `box` parameter of `Panel`. See `rich.box` for available styles. Defaults to `rich.box.ROUNDED`.

  padding: PaddingDimensions

    Padding inside the panel (top/bottom, left/right) or (top, right, bottom, left).

    Corresponds to the `padding` parameter of `Panel`.

  expand: bool

    Whether the panel should expand to fill available width.

    Corresponds to the `expand` parameter of `Panel`.

  width: int | None

    Fixed width for the panel in characters.

    Corresponds to the `width` parameter of `Panel`.

  height: int | None

    Fixed height for the panel in lines.

    Corresponds to the `height` parameter of `Panel`.

  safe_box: bool | None

    Whether to use ASCII-safe box characters for compatibility.

    Corresponds to the `safe_box` parameter of `Panel`.

  highlight: bool

    Enable automatic highlighting of panel contents.

    Corresponds to the `highlight` parameter of `Panel`.

  build(renderable: RenderableType, **overrides) → Panel

    Create a Panel around renderable. Use kwargs to override spec per render.

  copy(**kwargs)

class cyclopts.help.TableSpec(title: str | None = None, caption: str | None = None, style: StyleType | None = None, border_style: StyleType | None = None, header_style: StyleType | None = None, footer_style: StyleType | None = None, box: Box | None = None, show_header: bool = False, show_footer: bool = False, show_lines: bool = False, show_edge: bool = True, expand: bool = False, pad_edge: bool = False, padding: PaddingDimensions = (0, 2, 0, 0), collapse_padding: bool = False, width: int | None = None, min_width: int | None = None, safe_box: bool | None = None)

  Specification for table layout and styling.

  Used by `DefaultFormatter` to control the appearance of tables that display commands and parameters. This spec defines table-wide properties like borders, headers, and padding.

  See also

  `DefaultFormatter`

    The formatter that uses these specs.

  `ColumnSpec`

    Specification for individual columns.

  `PanelSpec`

    Specification for the outer panel.

  title: str | None

    Title text displayed above the table.

    Corresponds to the `title` parameter of `Table`.

  caption: str | None

    Caption text displayed below the table.

    Corresponds to the `caption` parameter of `Table`.

  style: StyleType | None

    Default style applied to the entire table.

    Corresponds to the `style` parameter of `Table`.

  border_style: StyleType | None

    Style applied to table borders.

    Corresponds to the `border_style` parameter of `Table`.

  header_style: StyleType | None

    Default style for all table headers (can be overridden per column).

    Corresponds to the `header_style` parameter of `Table`.

  footer_style: StyleType | None

    Default style for all table footers (can be overridden per column).

    Corresponds to the `footer_style` parameter of `Table`.

  box: Box | None

    Box drawing style for the table borders.

    Corresponds to the `box` parameter of `Table`. See `rich.box` for available styles.

  show_header: bool

    Whether to display column headers.

    Corresponds to the `show_header` parameter of `Table`.

  show_footer: bool

    Whether to display column footers.

    Corresponds to the `show_footer` parameter of `Table`.

  show_lines: bool

    Whether to show horizontal lines between rows.

    Corresponds to the `show_lines` parameter of `Table`.

  show_edge: bool

    Whether to draw a box around the outside of the table.

    Corresponds to the `show_edge` parameter of `Table`.

  expand: bool

    Whether the table should expand to fill available width.

    Corresponds to the `expand` parameter of `Table`.

  pad_edge: bool

    Whether to add padding to the table edges.

    Corresponds to the `pad_edge` parameter of `Table`.

  padding: PaddingDimensions

    Padding around cell content (top, right, bottom, left).

    Corresponds to the `padding` parameter of `Table`.

  collapse_padding: bool

    Whether to collapse padding when adjacent cells are empty.

    Corresponds to the `collapse_padding` parameter of `Table`.

  width: int | None

    Fixed width for the table in characters.

    Corresponds to the `width` parameter of `Table`.

  min_width: int | None

    Minimum width for the table in characters.

    Corresponds to the `min_width` parameter of `Table`.

  safe_box: bool | None

    Whether to use ASCII-safe box characters for compatibility.

    Corresponds to the `safe_box` parameter of `Table`.

  build(columns: tuple[ColumnSpec, ...], entries: Iterable[HelpEntry], **overrides) → Table

    Construct and populate a rich.Table.

    Parameters:

      - columns (tuple[ColumnSpec, ...]) -- Column specifications defining the table structure.

      - entries (Iterable[HelpEntry]) -- Table entries to populate the table with.

      - **overrides -- Per-render overrides for table settings.

    Returns:

      A populated Rich Table.

    Return type:

      Table

  copy(**kwargs)

class cyclopts.help.ColumnSpec(renderer: str | Renderer, header: str = '', footer: str = '', header_style: StyleType | None = None, footer_style: StyleType | None = None, style: StyleType | None = None, justify: Literal['default', 'left', 'center', 'right', 'full'] = 'left', vertical: Literal['top', 'middle', 'bottom'] = 'top', overflow: Literal['fold', 'crop', 'ellipsis', 'ignore'] = 'ellipsis', width: int | None = None, min_width: int | None = None, max_width: int | None = None, ratio: int | None = None, no_wrap: bool = False, highlight: bool | None = None)

  Specification for a single column in a help table.

  Used by `DefaultFormatter` to define how individual columns are rendered in help tables. Each column can have its own renderer, styling, and layout properties.

  See also

  `DefaultFormatter`

    The formatter that uses these specs.

  `TableSpec`

    Specification for the entire table.

  `PanelSpec`

    Specification for the outer panel.

  renderer: str | Renderer

    Specifies how to extract and render cell content from a `HelpEntry`.

    Can be either:

    - A string: The attribute name to retrieve from `HelpEntry` (e.g., 'names', 'description', 'required', 'type'). The string is displayed as-is.

    - A callable: A function matching the `Renderer` protocol. The function receives a `HelpEntry` and should return a `RenderableType` (str, `Text`, or other Rich renderable).

    Examples:

        # String renderer - get attribute directly
        ColumnSpec(renderer="description")

        # Callable renderer - custom formatting
        def format_names(entry: HelpEntry) -> str:
            return ", ".join(entry.names) if entry.names else ""
        ColumnSpec(renderer=format_names)

  header: str

    Column header text displayed at the top of the column.

    Example:

        header="Options" renders:
        ┌─────────┬─────────────┐
        │ Options │ Description │
        ├─────────┼─────────────┤
        │ --help  │ Show help   │
        └─────────┴─────────────┘

  footer: str

    Column footer text displayed at the bottom of the column.

    Example:

        footer="Required" renders:
        ┌──────────┬────────────┐
        │ --help   │ Show help  │
        ├──────────┼────────────┤
        │ Required │            │
        └──────────┴────────────┘

  header_style: StyleType | None

    Style applied to the column header text.

    Corresponds to the `header_style` parameter of `rich.table.Table.add_column()`.

  footer_style: StyleType | None

    Style applied to the column footer text.

    Corresponds to the `footer_style` parameter of `rich.table.Table.add_column()`.

  style: StyleType | None

    Default style applied to all cells in this column.

    Corresponds to the `style` parameter of `rich.table.Table.add_column()`.

  justify: Literal['default', 'left', 'center', 'right', 'full']

    Text justification within the column.

    Corresponds to the `justify` parameter of `rich.table.Table.add_column()`.

  vertical: Literal['top', 'middle', 'bottom']

    Vertical alignment of text within cells.

    Corresponds to the `vertical` parameter of `rich.table.Table.add_column()`.

  overflow: Literal['fold', 'crop', 'ellipsis', 'ignore']

    How to handle text that exceeds column width.

    Corresponds to the `overflow` parameter of `rich.table.Table.add_column()`.

  width: int | None

    Fixed width for the column in characters.

    Corresponds to the `width` parameter of `rich.table.Table.add_column()`.

  min_width: int | None

    Minimum width for the column in characters.

    Corresponds to the `min_width` parameter of `rich.table.Table.add_column()`.

  max_width: int | None

    Maximum width for the column in characters.

    Corresponds to the `max_width` parameter of `rich.table.Table.add_column()`.

  ratio: int | None

    Relative width ratio compared to other columns.

    Corresponds to the `ratio` parameter of `rich.table.Table.add_column()`.

  no_wrap: bool

    Prevent text wrapping in the column.

    Corresponds to the `no_wrap` parameter of `rich.table.Table.add_column()`.

  highlight: bool | None

    Enable automatic highlighting of text in the column.

    Corresponds to the `highlight` parameter of `rich.table.Table.add_column()`.

  copy(**kwargs)

class cyclopts.help.NameRenderer(max_width: int | None = None)

  Renderer for parameter/command names with optional text wrapping.

  Parameters:

    max_width (int | None) -- Maximum width for wrapping. If None, no wrapping is applied.

  Initialize the renderer with formatting options.

  Parameters:

    max_width (int | None) -- Maximum width for wrapping. If None, no wrapping is applied.

  __call__(entry: HelpEntry) → RenderableType

    Render the names column with optional text wrapping.

    Parameters:

      entry (HelpEntry) -- The table entry to render.

    Returns:

      Combined names and shorts, optionally wrapped. Order: positive_names, positive_shorts, negative_names, negative_shorts

    Return type:

      RenderableType

class cyclopts.help.DescriptionRenderer(newline_metadata: bool = False)

  Renderer for descriptions with configurable metadata formatting.

  Parameters:

    newline_metadata (bool) -- If True, display metadata (choices, env vars, defaults) on separate lines. If False (default), display metadata inline with the description.

  Initialize the renderer with formatting options.

  Parameters:

    newline_metadata (bool) -- If True, display metadata on separate lines instead of inline.

  __call__(entry: HelpEntry) → RenderableType

    Render parameter description with metadata annotations.

    Enriches the base description with choices, environment variables, default values, and required status.

    Parameters:

      entry (HelpEntry) -- The table entry to render.

    Returns:

      Description with appended metadata.

    Return type:

      RenderableType

class cyclopts.help.AsteriskRenderer

  Renderer for required parameter asterisk indicator.

  A simple renderer that displays an asterisk (*) for required parameters.

  __call__(entry: HelpEntry) → RenderableType

    Render an asterisk for required parameters.

    Parameters:

      entry (HelpEntry) -- The table entry to render.

    Returns:

      An asterisk if the entry is required, empty string otherwise.

    Return type:

      RenderableType

class cyclopts.help.HelpPanel(format: Literal['command', 'parameter'], title: RenderableType, description: Any | None = None, entries: list[HelpEntry] = NOTHING)

  Data container for help panel information.

  format: Literal['command', 'parameter']

    Panel format type.

  title: RenderableType

    The title text displayed at the top of the help panel.

  description: Any

    Optional description text displayed below the title.

    Typically a `str` or a `RenderableType`

  entries: list[HelpEntry]

    List of help entries to display (in order) in the panel.

  copy(**kwargs)

class cyclopts.help.HelpEntry(*, positive_names: tuple[str, ...] = (), positive_shorts: tuple[str, ...] = (), negative_names: tuple[str, ...] = (), negative_shorts: tuple[str, ...] = (), description: Any = None, required: bool = False, sort_key: Any = None, type: Any | None = None, choices: tuple[str, ...] | None = None, env_var: tuple[str, ...] | None = None, default: str | None = None)

  Container for help table entry data.

  positive_names: tuple[str, ...]

    Positive long option names (e.g., "--verbose", "--dry-run").

  positive_shorts: tuple[str, ...]

    Positive short option names (e.g., "-v", "-n").

  negative_names: tuple[str, ...]

    Negative long option names (e.g., "--no-verbose", "--no-dry-run").

  negative_shorts: tuple[str, ...]

    Negative short option names (e.g., "-N"). Rarely used.

  property names: tuple[str, ...]

    All long option names (positive + negative). For backward compatibility.

  property shorts: tuple[str, ...]

    All short option names (positive + negative). For backward compatibility.

  property all_options: tuple[str, ...]

    positive longs, positive shorts, negative longs, negative shorts.

    Type:

      All options in display order

  description: Any

    Help text description for this entry.

    Typically a `str` or a `RenderableType`

  required: bool

    Whether this parameter/command is required.

  sort_key: Any

    Custom sorting key for ordering entries.

  type: Any | None

    Type annotation of the parameter.

  choices: tuple[str, ...] | None

    Available choices for this parameter.

  env_var: tuple[str, ...] | None

    Environment variable names that can set this parameter.

  default: str | None

    Default value for this parameter to display. None means no default to show.

  copy(**kwargs)

## Config

Cyclopts has builtin configuration classes to be used with `App.config` for loading user-defined defaults in many common scenarios. All Cyclopts builtins index into the configuration file with the following rules:

1. Apply `root_keys` (if provided) to enter the project's configuration namespace.

2. Apply the command name(s) to enter the current command's configuration namespace.

3. Apply each key/value pair if CLI arguments have not been provided for that parameter.

class cyclopts.config.Toml(path, *, root_keys: Iterable[str] = (), allow_unknown: bool = False, use_commands_as_keys: bool = True, source: str | None = None, must_exist: bool = False, search_parents: bool = False)

  Automatically read configuration from Toml file.

  path: str | pathlib.Path

    Path to TOML configuration file.

  source: str | None = None

    Identifier for the configuration source, used in error messages. If not provided, defaults to the absolute path of the configuration file.

  root_keys: Iterable[str] = None

    The key or sequence of keys that lead to the root configuration structure for this app. For example, if referencing a `pyproject.toml`, it is common to store all of your projects configuration under:

        [tool.myproject]

    So, your Cyclopts `App` should be configured as:

        app = cyclopts.App(config=cyclopts.config.Toml("pyproject.toml", root_keys=("tool", "myproject")))

  must_exist: bool = False

    The configuration file MUST exist. Raises `FileNotFoundError` if it does not exist.

  search_parents: bool = False

    If `path` doesn't exist, iteratively search parenting directories for a same-named configuration file. Raises `FileNotFoundError` if no configuration file is found.

  allow_unknown: bool = False

    Allow for unknown keys. Otherwise, if an unknown key is provided, raises `UnknownOptionError`.

  use_commands_as_keys: bool = True

    Use the sequence of commands as keys into the configuration.

    For example, the following CLI invocation:

        $ python my-script.py my-command

    Would search into `["my-command"]` for values.

class cyclopts.config.Yaml(path, *, root_keys: Iterable[str] = (), allow_unknown: bool = False, use_commands_as_keys: bool = True, source: str | None = None, must_exist: bool = False, search_parents: bool = False)

  Automatically read configuration from YAML file.

  path: str | pathlib.Path

    Path to YAML configuration file.

  source: str | None = None

    Identifier for the configuration source, used in error messages. If not provided, defaults to the absolute path of the configuration file.

  root_keys: Iterable[str] = None

    The key or sequence of keys that lead to the root configuration structure for this app. For example, if referencing a common `config.yaml` that is shared with other applications, it is common to store your projects configuration under a key like `myproject:`.

    Your Cyclopts `App` would be configured as:

        app = cyclopts.App(config=cyclopts.config.Yaml("config.yaml", root_keys="myproject"))

  must_exist: bool = False

    The configuration file MUST exist. Raises `FileNotFoundError` if it does not exist.

  search_parents: bool = False

    If `path` doesn't exist, iteratively search parenting directories for a same-named configuration file. Raises `FileNotFoundError` if no configuration file is found.

  allow_unknown: bool = False

    Allow for unknown keys. Otherwise, if an unknown key is provided, raises `UnknownOptionError`.

  use_commands_as_keys: bool = True

    Use the sequence of commands as keys into the configuration.

    For example, the following CLI invocation:

        $ python my-script.py my-command

    Would search into `["my-command"]` for values.

class cyclopts.config.Json(path, *, root_keys: Iterable[str] = (), allow_unknown: bool = False, use_commands_as_keys: bool = True, source: str | None = None, must_exist: bool = False, search_parents: bool = False)

  Automatically read configuration from Json file.

  path: str | pathlib.Path

    Path to JSON configuration file.

  source: str | None = None

    Identifier for the configuration source, used in error messages. If not provided, defaults to the absolute path of the configuration file. Can be customized to provide more descriptive error context.

    Example:

        app = cyclopts.App(config=cyclopts.config.Json("config.json", source="production-config"))

  root_keys: Iterable[str] = None

    The key or sequence of keys that lead to the root configuration structure for this app. For example, if referencing a common `config.json` that is shared with other applications, it is common to store your projects configuration under a key like `"myproject":`.

    Your Cyclopts `App` would be configured as:

        app = cyclopts.App(config=cyclopts.config.Json("config.json", root_keys="myproject"))

  must_exist: bool = False

    The configuration file MUST exist. Raises `FileNotFoundError` if it does not exist.

  search_parents: bool = False

    If `path` doesn't exist, iteratively search parenting directories for a same-named configuration file. Raises `FileNotFoundError` if no configuration file is found.

  allow_unknown: bool = False

    Allow for unknown keys. Otherwise, if an unknown key is provided, raises `UnknownOptionError`.

  use_commands_as_keys: bool = True

    Use the sequence of commands as keys into the configuration.

    For example, the following CLI invocation:

        $ python my-script.py my-command

    Would search into `["my-command"]` for values.

class cyclopts.config.Dict(data: dict[str, Any], *, root_keys: Iterable[str] = (), allow_unknown: bool = False, use_commands_as_keys: bool = True, source: str | None = None)

  Configuration source from an in-memory dictionary.

  Useful for programmatically generated configurations.

  Use an in-memory Python dictionary as configuration source.

  data: dict[str, Any]

    The configuration dictionary.

  source: str = "dict"

    Identifier for the configuration source, used in error messages.

  root_keys: Iterable[str] = ()

    The key or sequence of keys that lead to the root configuration structure for this app.

  allow_unknown: bool = False

    Allow for unknown keys. Otherwise, if an unknown key is provided, raises `UnknownOptionError`.

  use_commands_as_keys: bool = True

    Use the sequence of commands as keys into the configuration.

class cyclopts.config.Env(prefix: str = '', *, source: str = 'env', command: bool = True, show: bool = True)

  Automatically derive environment variable names to read configurations from.

  For example, consider the following app:

      import cyclopts

      app = cyclopts.App(config=cyclopts.config.Env("MY_SCRIPT_"))

      @app.command
      def my_command(foo, bar):
          print(f"{foo=} {bar=}")

      app()

  If values for `foo` and `bar` are not supplied by the command line, the app will check the environment variables `MY_SCRIPT_MY_COMMAND_FOO` and `MY_SCRIPT_MY_COMMAND_BAR`, respectively:

      $ python my_script.py my-command 1 2
      foo=1 bar=2

      $ export MY_SCRIPT_MY_COMMAND_FOO=100
      $ python my_script.py my-command --bar=2
      foo=100 bar=2
      $ python my_script.py my-command 1 2
      foo=1 bar=2

  prefix: str = ""

    String to prepend to all autogenerated environment variable names. Typically ends in `_`, and is something like `MY_APP_`.

  source: str = "env"

    Identifier for the configuration source, used in error messages and token tracking. Defaults to `"env"`.

  command: bool = True

    If `True`, add the command's name (uppercase) after `prefix`.

  show: bool = True

    If `True`, then show the environment variables on the help-page.

## Exceptions

exception cyclopts.CycloptsError

  Bases: `Exception`

  Root exception for runtime errors.

  As CycloptsErrors bubble up the Cyclopts call-stack, more information is added to it.

  msg: str | Text | None

    If set, override automatic message generation.

    A `str` is rendered as literal text. To apply styling, pass a `rich.text.Text` instance — either constructed from Rich console markup:

        from rich.text import Text
        raise CycloptsError(msg=Text.from_markup("Invalid value [bold red]foo[/]."))

    or assembled directly using the built-in palette (`STYLE_OFFENDING_VALUE`, `STYLE_NAME`, `STYLE_VALID_CHOICE`, `STYLE_SUGGESTION`, `STYLE_SOURCE`) to keep custom errors visually consistent with the framework's output:

        from rich.text import Text
        from cyclopts.exceptions import STYLE_NAME, STYLE_OFFENDING_VALUE

        t = Text("Invalid value ")
        t.append("foo", style=STYLE_OFFENDING_VALUE)
        t.append(" for ")
        t.append("--name", style=STYLE_NAME)
        raise CycloptsError(msg=t)

  verbose: bool

    More verbose error messages; aimed towards developers debugging their Cyclopts app. Defaults to `False`.

  root_input_tokens: list[str] | None

    The parsed CLI tokens that were initially fed into the `App`.

  unused_tokens: list[str] | None

    Leftover tokens after parsing is complete.

  target: Callable | None

    The python function associated with the command being parsed.

  argument: Argument | None

    `Argument` that was matched.

  command_chain: Sequence[str] | None

    List of command that lead to `target`.

  app: App | None

    The Cyclopts application itself.

  console: Console | None

    `Console` to display runtime errors.

exception cyclopts.ValidationError

  Bases: `CycloptsError`

  Validator function raised an exception.

  exception_message: str

    Parenting Assertion/Value/Type Error message.

  group: Group | None

    If a group validator caused the exception.

  value: Any

    Converted value that failed validation.

exception cyclopts.UnknownOptionError

  Bases: `CycloptsError`

  Unknown/unregistered option provided by the cli.

  A nearest-neighbor parameter suggestion may be printed.

  token: Token

    Token without a matching parameter.

  argument_collection: ArgumentCollection

    Argument collection of plausible options.

exception cyclopts.CoercionError

  Bases: `CycloptsError`

  There was an error performing automatic type coercion.

  token: Token | None

    Input token that couldn't be coerced.

  target_type: type | None

    Intended type to coerce into.

exception cyclopts.UnknownCommandError

  Bases: `CycloptsError`

  CLI token combination did not yield a valid command.

  msg

    If set, override automatic message generation.

    A `str` is rendered as literal text. To apply styling, pass a `rich.text.Text` instance — either constructed from Rich console markup:

        from rich.text import Text
        raise CycloptsError(msg=Text.from_markup("Invalid value [bold red]foo[/]."))

    or assembled directly using the built-in palette (`STYLE_OFFENDING_VALUE`, `STYLE_NAME`, `STYLE_VALID_CHOICE`, `STYLE_SUGGESTION`, `STYLE_SOURCE`) to keep custom errors visually consistent with the framework's output:

        from rich.text import Text
        from cyclopts.exceptions import STYLE_NAME, STYLE_OFFENDING_VALUE

        t = Text("Invalid value ")
        t.append("foo", style=STYLE_OFFENDING_VALUE)
        t.append(" for ")
        t.append("--name", style=STYLE_NAME)
        raise CycloptsError(msg=t)

  verbose

    More verbose error messages; aimed towards developers debugging their Cyclopts app. Defaults to `False`.

  root_input_tokens

    The parsed CLI tokens that were initially fed into the `App`.

  unused_tokens

    Leftover tokens after parsing is complete.

  target

    The python function associated with the command being parsed.

  argument

    `Argument` that was matched.

  command_chain

    List of command that lead to `target`.

  app

    The Cyclopts application itself.

  console

    `Console` to display runtime errors.

exception cyclopts.UnusedCliTokensError

  Bases: `CycloptsError`

  Not all CLI tokens were used as expected.

exception cyclopts.MissingArgumentError

  Bases: `CycloptsError`

  A required argument was not provided.

  tokens_so_far: list[str]

    If the matched parameter requires multiple tokens, these are the ones we have parsed so far.

  keyword: str | None

    The keyword that was used when the error was raised (e.g., '-o' instead of '--option').

exception cyclopts.ConsumeMultipleError

  Bases: `MissingArgumentError`

  The number of values provided doesn't meet consume_multiple constraints.

  min_required: int
  max_allowed: int | None
  actual_count: int

exception cyclopts.RequiresEqualsError

  Bases: `CycloptsError`

  A long option requires `=` to assign a value (e.g., `--option=value`).

  keyword: str | None

    The keyword that was used (e.g., '--name').

exception cyclopts.RepeatArgumentError

  Bases: `CycloptsError`

  The same parameter has erroneously been specified multiple times.

  token: Token

    The repeated token.

exception cyclopts.MixedArgumentError

  Bases: `CycloptsError`

  Cannot supply keywords and non-keywords to the same argument.

exception cyclopts.CombinedShortOptionError

  Bases: `CycloptsError`

  Cannot combine short, token-consuming options with short flags.

### Style Constants

Palette used by the built-in error messages. See `CycloptsError.msg` for example usage.

cyclopts.exceptions.STYLE_OFFENDING_VALUE = 'bold red'

  Rich style for an offending user-supplied value.

cyclopts.exceptions.STYLE_NAME = 'bold'

  Rich style for a parameter, option, or command name.

cyclopts.exceptions.STYLE_VALID_CHOICE = 'cyan'

  Rich style for valid choices in `Choose from:` lists.

cyclopts.exceptions.STYLE_SUGGESTION = 'bold green'

  Rich style for `Did you mean ...` suggestions.

cyclopts.exceptions.STYLE_SOURCE = 'dim'

  Rich style for source suffixes like `from <CONFIG>`.