Action Completer Package

Below is autogenerated documentation directly from docstrings in the source.
If you are just getting started, I would recommend you first read the Getting Started documentation. The package documentation included here should mostly just be used for reference or a slightly more simple look into the internals of the project.

Types

Contains the base data types used to power the completion and validation of actions.

action_completer.types.ActionCompletable_T

Defines the base data types that are typically used for completion. This type feels like it should be used more, but it really isn’t necessary that often.

Type

typing.Type

action_completer.types.ActionContext_T

Defines the value types to expect from the extraction of the context for the provided prompt document. Since we need various details about the current state of the prompt buffer, we explicitly define the types of the extracted context tuple through this type.

Type

typing.Type

action_completer.types.ActionParamBasic_T

Defines the allowable types for basic completion and validation. Typically just a single value, in this case a string.

Type

typing.Type

action_completer.types.ActionParamIterable_T

Defines the allowable types for iterable completion and validation. Only supports hashable iterables (tuples, lists) of strings.

Type

typing.Type

action_completer.types.ActionParamCompleter_T

Defines the allowable types for nested completer completion (not validation). Currently just an alias of Completer.

Type

typing.Type

action_completer.types.ActionParamCallable_T

Defines the allowable type for callable completions and validation.

Type

typing.Type

action_completer.types.ActionParamSource_T

Defines the allowable types for action parameter sources that can be completed and validated. This is a union of previously defined action param types.

Type

typing.Type

action_completer.types.ActionParamValidator_T

Defines the allowable types for validation callables or instances.

Type

typing.Type

action_completer.types.LazyString_T

Defines the allowable types for optionally lazy evaluated strings. This is either just an instance of a string or a callable that results in a string.

Type

typing.Type

action_completer.types.LazyText_T

Similar to LazyString_T, this defines the allowable types for optionally lazy evaluated strings or instances of FormattedText. This is either just an instance or a callable that results in an instance.

Type

typing.Type

class action_completer.types.Action(action=None, params=None, style=None, selected_style=None, display=None, display_meta=None, active=None, capture_all=False)[source]

Defines a completable action.

action

The callable function that should be completeable and can be called after validation of the given action and associated parameters

Type

Optional[Callable[.., Any]], optional

params

The list of action parameters in the same order of positional arguments for the action callable.

Type

Optional[List[ActionParam]], optional

style

The style string to apply to completion results for the action

Type

Optional[LazyString_T], optional

selected_style

The style string to apply to selected completion results for the action

Type

Optional[LazyString_T], optional

display

The custom display to apply to completion results for the action

Type

Optional[LazyText_T], optional

display_meta

The custom display meta (description) to apply to completion results for the action

Type

Optional[LazyText_T], optional

active

A callable filter that results in a boolean to indicate if the action should be considred as active and displayed as a completion result

Type

Optional[Filter], optional

capture_all

If there is the option for this action to accept more arguments than defined by the provided parameters, this flag will allow for any number of following arguments (after parameters) as additional positional arguments to the provided action callable, defaults to False

Type

bool, optional

class action_completer.types.ActionGroup(children, style=None, selected_style=None, display=None, display_meta=None, active=None)[source]

Defines a completable group of either nested action groups or leaf actions.

Important

It is crucial for proper fragment extraction that no children keys contain spaces. Each non-escaped space is considered a new fragment and used to find the context for both completion and validation. Although it would technically be possible to support child key completion with spaces, it involves more complex features of prompt-toolkit than just completion.

Therefore, I have decided to hold the opinion that no spaces should be allowable as keys in a group’s children. A post-initialization validator exists to ensure this is true for any action group you define.

children

The dictionary of completion text (keys) to a nested action group or a callable action (value) that forms the group’s children

Type

Dict[str, Union[ActionGroup, Action]]

style

The style string to apply to completion results for the action group

Type

Optional[LazyString_T], optional

selected_style

The style string to apply to selected completion results for the action group

Type

Optional[LazyString_T], optional

display

The custom display to apply to completion results for the action group

Type

Optional[LazyText_T], optional

display_meta

The custom display meta (description) to apply to completion results for the action group

Type

Optional[LazyText_T], optional

active

A callable filter that results in a boolean to indicate if the action group should be considred as active and displayed as a completion result

Type

Optional[Filter], optional

action(name, params=None, style=None, selected_style=None, display=None, display_meta=None, active=None, capture_all=False)[source]

Decorate a callable as an action within the current group.

Basic root level actions are easily defined directly off of the completer instance like follows:

from prompt_toolkit.shortcuts import prompt
from action_completer import ActionCompleter
completer = ActionCompleter()

@completer.action("hello")
def _hello_action():
    print("Hello, World!")

completer.run_action(prompt(">>> ", completer=completer))

# available through the following prompt:
# >>> hello
# Hello, World!

You can nest actions in sub-groups by first calling group() to define a new group and base all actions from the action decorator provided on that new group.

Parameters
  • name (str) – The completion name that triggers this action

  • params (Optional[List[ActionParam]], optional) – The list of action parameters to complete and handle within the action

  • style (Optional[LazyString_T], optional) – The style string to apply to completion results for the action

  • selected_style (Optional[LazyString_T], optional) – The style string to apply to selected completion results for the action

  • display (Optional[LazyText_T], optional) – The custom display to apply to completion results for the action

  • display_meta (Optional[LazyText_T], optional) – The custom display meta (description) to apply to completion results for the action

  • active (Optional[Filter], optional) – A callable filter that results in a boolean to indicate if the action group should be considred as active and displayed as a completion result

  • capture_all (bool, optional) – If there is the option for this action to accept more arguments than defined by the provided parameters, this flag will allow for any number of following arguments (after parameters) as additional positional arguments to the provided action callable, defaults to False

Raises
  • ValueError – When the given action name contains spaces

  • ValueError – When the given action name is already present in the group

Returns

The newly wrapped action callable

Return type

Callable[.., Any]

group(name, children=None, style=None, selected_style=None, display=None, display_meta=None, active=None)[source]

Create a new subgroup for the current group.

By default the ActionCompleter comes with a root group to extend from. However, if you want to build a set of nested commands, you can use this function to register a new group on the completer.

from prompt_toolkit.shortcuts import prompt
from action_completer import ActionCompleter
completer = ActionCompleter()

nested_group = completer.group("hello")

@nested_group.action("world")
def _hello_world_action():
    print("Hello, World!")


completer.run_action(prompt(">>> ", completer=completer))
# available through the following prompt:
# >>> hello world
# Hello, World!
Parameters
  • name (str) – The completion text that triggers this group

  • children (Dict[str, Union[ActionGroup, Action]]) – The dictionary of completion text (keys) to a nested action group or a callable action (value) that forms the group’s children

  • style (Optional[LazyString_T], optional) – The style string to apply to completion results for the action group

  • selected_style (Optional[LazyString_T], optional) – The style string to apply to selected completion results for the action group

  • display (Optional[LazyText_T], optional) – The custom display to apply to completion results for the action group

  • display_meta (Optional[LazyText_T], optional) – The custom display meta (description) to apply to completion results for the action group

  • active (Optional[Filter], optional) – A callable filter that results in a boolean to indicate if the action group should be considred as active and displayed as a completion result

Raises
  • ValueError – When the provided group name contains spaces

  • ValueError – When the provided group name is already in the current group

Returns

The created action group

Return type

ActionGroup

class action_completer.types.ActionParam(source, cast=None, style=None, selected_style=None, display=None, display_meta=None, validators=None)[source]

Defines a completable action parameter.

source

The completion source for the parameter

Type

ActionParamSource_T

cast

The type to cast the action parameter to during execution of the action tied to this parameter

Type

Optional[Type], optional

style

The style string to apply to completion results for the action parameter

Type

Optional[LazyString_T], optional

selected_style

The style string to apply to selected completion results for the action parameter

Type

Optional[LazyString_T], optional

display

The custom display to apply to completion results for the action parameter

Type

Optional[LazyText_T], optional

display_meta

The custom display meta (description) to apply to completion results for the action parameter

Type

Optional[LazyText_T], optional

validators

The list of validators to run in-order against the parameter value during validation

Type

Optional[List[ActionParamValidator_T]], optional

action_completer.types.param(source, cast=None, style=None, selected_style=None, display=None, display_meta=None, validators=None)[source]

Create a new action parameter for an action.

Basic parameters can be defined right before defining a method as an action.

from pathlib import Path
from prompt_toolkit.shortcuts import prompt
from prompt_toolkit.validation import Validator
from action_completer import ActionCompleter
completer = ActionCompleter()

@completer.action("cat")
@completer.param(
    PathCompleter(),
    cast=Path,
    validators=[Validator.from_callable(lambda p: Path(p).is_file())]
)
def _cat_action(filepath: Path):
    with filepath.open("r") as file_handle:
        print(file_handle.read())

completer.run_action(prompt(">>> ", completer=completer))
# available through the following prompt:
# # $ echo "my content" > ./my-file.txt
# >>> cat ./my-file.txt
# my content

Important

The application order of param decorators is very important. Since these defined action parameters are applied as positional arguments to the action, we are opinionated on the ordering that decorators should be applied.

We purposefully reverse the traditional decorator application order to make the readability of actions created purely through decorators a bit easier. This means that the last parameter should be the first decorator applied to the action callable, and the very last decorator applied to the action callable should be the action decorator. This benefits readability by ordering the defined param decorators top-to-bottom as arguments applied left-to-right in the action callable.

# valid
@action("test")
@param("source1")
@param("source2")
def _valid_action(source1: str, source2: str):
    ...

# invalid
@param("source2")
@param("source1")
@action("test")
def _invalid_action(source1: str, source2: str):
    ...

# also invalid
@action("test")
@param("source2")
@param("source1")
def _also_invalid_action(source1: str, source2: str):
    ...

We have some checks to raise warnings in case you accidentally use an invalid spec for applying the decorators. Although I’m not 100% sure it will capture all the possible states of defining actions that you might come up with.

If you don’t like this design, I would recommend you instead pass ActionParam instances to the params keyword argument when using the action() decorator.

Parameters
  • source (ActionParamSource_T) – The completion source for the parameter

  • cast (Optional[Type], optional) – The type to cast the action parameter to during execution of the action tied to this parameter

  • style (Optional[LazyString_T], optional) – The style string to apply to completion results for the action parameter

  • selected_style (Optional[LazyString_T], optional) – The style string to apply to selected completion results for the action parameter

  • display (Optional[LazyText_T], optional) – The custom display to apply to completion results for the action parameter

  • display_meta (Optional[LazyText_T], optional) – The custom display meta (description) to apply to completion results for the action parameter

  • validators (Optional[List[ActionParamValidator_T]], optional) – The list of validators to run in-order against the parameter value during validation

Returns

The newly wrapped action with the defined parameters

Return type

Callable[.., Any]

Completer

Contains the completer for a single root ActionGroup instance.

Registering actions for the completer can be done in several different ways. The simplest way, is to use the provided action() decorator:

from prompt_toolkit.shortcuts import prompt
from action_completer import ActionCompleter
completer = ActionCompleter()

@completer.action("hello")
def _hello_world():
    print("Hello, World!")

completer.run_action(prompt(">>> ", completer=completer))

Another common way is to build the root ActionGroup structure yourself:

from prompt_toolkit.shortcuts import prompt
from action_completer import ActionCompleter, ActionGroup, Action

def _hello_world():
    print("Hello, World!")

root_group = ActionGroup({"hello": Action(_hello_world)})
completer = ActionCompleter(root_group)

completer.run_action(prompt(">>> ", completer=completer))

Lastly, if you really need it, you can specify the starting structure of the completer through a very specific dictionary structure. I personally needed this in the past and haven’t yet had the chance to remove the need of it.

from prompt_toolkit.shortcuts import prompt
from action_completer import ActionCompleter

def _hello_world():
    print("Hello, World!")

completer = ActionCompleter.from_dict({
    "root": {
        "hello": {
            "action": _hello_world
        }
    },
    "fuzzy_tolerance: 75
})

completer.run_action(prompt(">>> ", completer=completer))
class action_completer.completer.ActionCompleter(root=None, fuzzy_tolerance=75)[source]

Custom completer for actions.

This completer should be relatively easy to consume and provides features for extending completions with custom styles and display properties.

The most straight forward method of defining actions is to use the action() decorator right off of the completer:

from prompt_toolkit.shortcuts import prompt
from action_completer import ActionCompleter
completer = ActionCompleter()

@completer.action("hello")
def _hello_world():
    print("Hello, World!")

output = prompt(">>> ", completer=completer)
completer.run_action(output)

# >>> hello
# Hello, World!

If you want to go a more declarative route, you can explicitly build the tree structure of ActionGroup, Action, and ActionParam yourself.

from prompt_toolkit.shortcuts import prompt
from action_completer import ActionCompelter, ActionGroup, Action, ActionParam

def _hello_world():
    print("Hello, World!")

ACTIONS = ActionGroup({
    "hello": Action(_hello_world)
})

completer = ActionCompleter(ACTIONS)

output = prompt(">>> ", completer=completer)
completer.run_action(output)

# >>> hello
# Hello, World!
get_completions(document, complete_event)[source]

Generate completions for the given prompt document.

Parameters
  • document (Document) – The document directly from the prompt to generate completions for

  • complete_event (CompleteEvent) – The completion event for the completions

Yields

prompt_toolkit.completion.Completion – A completion for the given prompt document

Return type

Generator[Completion, None, None]

get_partial_action(prompt_result)[source]

Get the partial for the action callable with action parameters included.

Parameters

prompt_result (str) – The result of the completer’s prompt call

Raises

ValueError – When no actionable action can be determined from the given prompt result

Returns

A partial callable for the related action including clean parameters

Return type

Callable[.., Any]

get_validator()[source]

Get an instance of the validator for the current completer.

Returns

A prompt validator for the current state of the completer

Return type

ActionValidator

run_action(prompt_result, *args, **kwargs)[source]

Run the related action from the given prompt result.

Parameters

prompt_result (str) – The result of the completer’s prompt call

Returns

Whatever the return value of the related action callable is

Return type

Any

class action_completer.completer.ActionParamCompletionIterator_T(*args, **kwds)[source]

Protocol typing for param-level Completion generators.

Required for dynamic switching between various action param completion interators.

class action_completer.completer.CompletionIterator_T(*args, **kwds)[source]

Protocol typing for top-level (non-param) Completion generators.

Required for dynamic switching between group and action completion iterators since both ActionGroup and Action can appear as values in ActionGroup.children.

Validator

Contains the validator used to validate data produced by the action completer.

To retreive this validator, it is highly recommend that you utilize the get_validator() method. If your completer instance is dynamic, you probably want to fetch this validator instance for every call to prompt().

For example:

from prompt_toolkit.shortcuts import prompt
from action_completer import ActionCompleter
completer = ActionCompleter()

# ... register completer actions

while True:
    # note the call to `get_validator` for every call to prompt
    prompt_result = prompt(
        ">>> ",
        completer=completer,
        validator=completer.get_validator()
    )

You could also initialize the ActionValidator yourself by passing through the root group of the ActionCompleter:

from prompt_toolkit.shortcuts import prompt
from action_completer import ActionCompleter, ActionValidator
completer = ActionCompleter()

# ... register completer actions

while True:
    validator = ActionValidator(completer.root)
    prompt_result = prompt(
        ">>> ",
        completer=completer,
        validator=validator
    )
class action_completer.validator.ActionValidator(root)[source]

Custom validator for a ActionCompleter.

Most of the time you should get this instance from get_validator() however if you need to build an instance of it yourself you can use the following logic:

from action_completer.completer import ActionCompleter
from action_completer.validator import ActionValidator

completer = ActionCompleter()
validator = ActionValidator(completer.root)
validate(document)[source]

Validate the current document from the ActionCompleter.

Parameters

document (Document) – The document to validate

Raises

ValidationError – When validation of the given document fails.

Utilities

Contains utility functions used throughout various points of the module.

action_completer.utils.decode_completion(text)[source]

Reverse the encoding process for completion text.

Parameters

text (str) – The text to decode for use in action parameters and displaying

Returns

The properly decoded text

Return type

str

action_completer.utils.encode_completion(text)[source]

Encode some completion text for writing to the user’s current prompt buffer.

Parameters

text (str) – The text to encode for writing

Returns

The properly encoded text for the user’s prompt buffer

Return type

str

action_completer.utils.extract_context(action_group, fragments)[source]

Extract the current context for a root action group and buffer fragments.

Parameters
  • action_group (ActionGroup) – The root action group to start context extraction

  • fragments (List[str]) – The text fragments extracted from the current user’s prompt buffer

Returns

A tuple of (parent ActionGroup, parent name, current ActionGroup/Action, list of remaining fragments [parameters])

Return type

ActionContext_T

action_completer.utils.format_dynamic_value(template, text)[source]

Format the given template text for the dynamic value.

Parameters
  • template (str) – The template text to be formatted

  • text (str) – The current text fragment that triggered the completion

Returns

The formatted text

Return type

str

action_completer.utils.get_best_choice(choices, user_value)[source]

Guess the best choice from an interable of choice strings given a target value.

This method has a few caveats to make using it with completion a bit easier:

  • If no choices are given, nothing is returned.

  • If only 1 choice is given, that choice is always returned.

  • If the given value (taget) text is not alphanumerical, the first available choice is returned.

Parameters
  • choices (Iterable[str]) – The iterable of choices to guess from

  • user_value (str) – The target value to base the best guess off of

Returns

The best choice if available, otherwise None

Return type

Optional[str]

action_completer.utils.get_dynamic_value(source, value, text, default=None)[source]

Resolve a lazy/dynamic completion format value.

The given value will be formatted in place of any {completion} usage within the dynamic text. The following example will display the description containing the completion value in place of the given value

@completer.action("hello-world")
@completer.param(["1", "2", "3"], display_meta="Will display {completion}")
def _hello_world(number_value: str):
    print(f"Hello, {number_value!s}!")
Parameters
  • source (ActionCompletable_T) – The source for the completion

  • value (LazyText_T) – The dynamic value that needs to be resolved for the source

  • text (str) – The current text fragment that triggered the given source

  • default (Optional[Union[str, FormattedText]]) – A default if the given value resolves to None. Defaults to None.

Returns

Either a string or FormattedText instance if the value is properly resolved, otherwise defaults to the default

Return type

Optional[Union[str, FormattedText]]

action_completer.utils.get_fragments(text)[source]

Get the properly split fragments from the current user’s prompt buffer.

Parameters

text (str) – The text of the current user’s prompt buffer

Returns

A list of string fragments

Return type

List[str]

action_completer.utils.iter_best_choices(choices, user_value, fuzzy_tolerance=None)[source]

Iterate over the sorted closest strings from some choices using fuzzy matching.

This iterator has a few caveats that make using it with completion a bit easier:

  • If no choices are given, nothing is ever yielded.

  • If only 1 choice is given, that choice will always be yielded.

    Basically no fuzzy matching will occur against to allow for filtering out just a single choice.

  • If the given value (target) text is empty, all choices will be yielded.

  • If the given value (target) text is not alphanumerical, all choices are yielded.

Parameters
  • choices (Iterable[str]) – An interable of strings to apply fuzzy matching to

  • user_value (str) – The value to use for fuzzy comparison against choices

  • fuzzy_tolerance (Optional[int], optional) – The percentage integer 0-100 to tolerate the resulting fuzzy matches. Defaults to None.

Yields

str – Sorted best matching strings from choices in comparison to user_value

Return type

Generator[str, None, None]

action_completer.utils.noop(*args, **kwargs)[source]

Noop function that does absolutely nothing.

Return type

None