Add register_teardown, Rename session -> prompt_session, Add sets, tuples to SelectionAction
This commit is contained in:
parent
53729f089f
commit
ad803e01be
|
@ -448,6 +448,8 @@ class ChainedAction(BaseAction, ActionListMixin):
|
|||
if self.actions and self.auto_inject and not action.inject_last_result:
|
||||
action.inject_last_result = True
|
||||
super().add_action(action)
|
||||
if hasattr(action, "register_teardown") and callable(action.register_teardown):
|
||||
action.register_teardown(self.hooks)
|
||||
|
||||
async def _run(self, *args, **kwargs) -> list[Any]:
|
||||
if not self.actions:
|
||||
|
@ -617,6 +619,22 @@ class ActionGroup(BaseAction, ActionListMixin):
|
|||
if actions:
|
||||
self.set_actions(actions)
|
||||
|
||||
def _wrap_if_needed(self, action: BaseAction | Any) -> BaseAction:
|
||||
if isinstance(action, BaseAction):
|
||||
return action
|
||||
elif callable(action):
|
||||
return Action(name=action.__name__, action=action)
|
||||
else:
|
||||
raise TypeError(
|
||||
f"ActionGroup only accepts BaseAction or callable, got {type(action).__name__}"
|
||||
)
|
||||
|
||||
def add_action(self, action: BaseAction | Any) -> None:
|
||||
action = self._wrap_if_needed(action)
|
||||
super().add_action(action)
|
||||
if hasattr(action, "register_teardown") and callable(action.register_teardown):
|
||||
action.register_teardown(self.hooks)
|
||||
|
||||
async def _run(self, *args, **kwargs) -> list[tuple[str, Any]]:
|
||||
shared_context = SharedContext(name=self.name, is_parallel=True)
|
||||
if self.shared_context:
|
||||
|
|
|
@ -148,7 +148,7 @@ class Falyx:
|
|||
self.render_menu: Callable[["Falyx"], None] | None = render_menu
|
||||
self.custom_table: Callable[["Falyx"], Table] | Table | None = custom_table
|
||||
self.validate_options(cli_args, options)
|
||||
self._session: PromptSession | None = None
|
||||
self._prompt_session: PromptSession | None = None
|
||||
|
||||
def validate_options(
|
||||
self,
|
||||
|
@ -337,11 +337,11 @@ class Falyx:
|
|||
move_cursor_to_end=True,
|
||||
)
|
||||
|
||||
def _invalidate_session_cache(self):
|
||||
"""Forces the session to be recreated on the next access."""
|
||||
if hasattr(self, "session"):
|
||||
del self.session
|
||||
self._session = None
|
||||
def _invalidate_prompt_session_cache(self):
|
||||
"""Forces the prompt session to be recreated on the next access."""
|
||||
if hasattr(self, "prompt_session"):
|
||||
del self.prompt_session
|
||||
self._prompt_session = None
|
||||
|
||||
def add_help_command(self):
|
||||
"""Adds a help command to the menu if it doesn't already exist."""
|
||||
|
@ -375,7 +375,7 @@ class Falyx:
|
|||
raise FalyxError(
|
||||
"Bottom bar must be a string, callable, or BottomBar instance."
|
||||
)
|
||||
self._invalidate_session_cache()
|
||||
self._invalidate_prompt_session_cache()
|
||||
|
||||
def _get_bottom_bar_render(self) -> Callable[[], Any] | str | None:
|
||||
"""Returns the bottom bar for the menu."""
|
||||
|
@ -390,10 +390,10 @@ class Falyx:
|
|||
return None
|
||||
|
||||
@cached_property
|
||||
def session(self) -> PromptSession:
|
||||
def prompt_session(self) -> PromptSession:
|
||||
"""Returns the prompt session for the menu."""
|
||||
if self._session is None:
|
||||
self._session = PromptSession(
|
||||
if self._prompt_session is None:
|
||||
self._prompt_session = PromptSession(
|
||||
message=self.prompt,
|
||||
multiline=False,
|
||||
completer=self._get_completer(),
|
||||
|
@ -402,7 +402,7 @@ class Falyx:
|
|||
bottom_toolbar=self._get_bottom_bar_render(),
|
||||
key_bindings=self.key_bindings,
|
||||
)
|
||||
return self._session
|
||||
return self._prompt_session
|
||||
|
||||
def register_all_hooks(self, hook_type: HookType, hooks: Hook | list[Hook]) -> None:
|
||||
"""Registers hooks for all commands in the menu and actions recursively."""
|
||||
|
@ -717,7 +717,7 @@ class Falyx:
|
|||
|
||||
async def process_command(self) -> bool:
|
||||
"""Processes the action of the selected command."""
|
||||
choice = await self.session.prompt_async()
|
||||
choice = await self.prompt_session.prompt_async()
|
||||
selected_command = self.get_command(choice)
|
||||
if not selected_command:
|
||||
logger.info(f"Invalid command '{choice}'.")
|
||||
|
|
|
@ -15,6 +15,7 @@ from rich.tree import Tree
|
|||
|
||||
from falyx.action import Action
|
||||
from falyx.context import ExecutionContext, SharedContext
|
||||
from falyx.hook_manager import HookManager, HookType
|
||||
from falyx.themes.colors import OneColors
|
||||
from falyx.utils import logger
|
||||
|
||||
|
@ -97,7 +98,6 @@ class HTTPAction(Action):
|
|||
)
|
||||
|
||||
async def _request(self, *args, **kwargs) -> dict[str, Any]:
|
||||
# TODO: Add check for HOOK registration
|
||||
if self.shared_context:
|
||||
context: SharedContext = self.shared_context
|
||||
session = context.get("http_session")
|
||||
|
@ -128,6 +128,9 @@ class HTTPAction(Action):
|
|||
if not self.shared_context:
|
||||
await session.close()
|
||||
|
||||
def register_teardown(self, hooks: HookManager):
|
||||
hooks.register(HookType.ON_TEARDOWN, close_shared_http_session)
|
||||
|
||||
async def preview(self, parent: Tree | None = None):
|
||||
label = [
|
||||
f"[{OneColors.CYAN_b}]🌐 HTTPAction[/] '{self.name}'",
|
||||
|
|
|
@ -33,8 +33,10 @@ async def cleanup():
|
|||
"""
|
||||
|
||||
GLOBAL_CONFIG = """\
|
||||
async def cleanup():
|
||||
print("🧹 Cleaning temp files...")
|
||||
- key: C
|
||||
description: Cleanup temp files
|
||||
action: tasks.cleanup
|
||||
aliases: [clean, cleanup]
|
||||
"""
|
||||
|
||||
console = Console(color_system="auto")
|
||||
|
|
|
@ -168,15 +168,13 @@ class MenuAction(BaseAction):
|
|||
await self.hooks.trigger(HookType.BEFORE, context)
|
||||
key = effective_default
|
||||
if not self.never_prompt:
|
||||
console = self.console
|
||||
session = self.prompt_session
|
||||
table = self._build_table()
|
||||
key = await prompt_for_selection(
|
||||
self.menu_options.keys(),
|
||||
table,
|
||||
default_selection=self.default_selection,
|
||||
console=console,
|
||||
session=session,
|
||||
console=self.console,
|
||||
prompt_session=self.prompt_session,
|
||||
prompt_message=self.prompt_message,
|
||||
show_table=self.show_table,
|
||||
)
|
||||
|
|
|
@ -203,17 +203,17 @@ async def prompt_for_index(
|
|||
min_index: int = 0,
|
||||
default_selection: str = "",
|
||||
console: Console | None = None,
|
||||
session: PromptSession | None = None,
|
||||
prompt_session: PromptSession | None = None,
|
||||
prompt_message: str = "Select an option > ",
|
||||
show_table: bool = True,
|
||||
):
|
||||
session = session or PromptSession()
|
||||
prompt_session = prompt_session or PromptSession()
|
||||
console = console or Console(color_system="auto")
|
||||
|
||||
if show_table:
|
||||
console.print(table)
|
||||
|
||||
selection = await session.prompt_async(
|
||||
selection = await prompt_session.prompt_async(
|
||||
message=prompt_message,
|
||||
validator=int_range_validator(min_index, max_index),
|
||||
default=default_selection,
|
||||
|
@ -226,18 +226,18 @@ async def prompt_for_selection(
|
|||
table: Table,
|
||||
default_selection: str = "",
|
||||
console: Console | None = None,
|
||||
session: PromptSession | None = None,
|
||||
prompt_session: PromptSession | None = None,
|
||||
prompt_message: str = "Select an option > ",
|
||||
show_table: bool = True,
|
||||
) -> str:
|
||||
"""Prompt the user to select a key from a set of options. Return the selected key."""
|
||||
session = session or PromptSession()
|
||||
prompt_session = prompt_session or PromptSession()
|
||||
console = console or Console(color_system="auto")
|
||||
|
||||
if show_table:
|
||||
console.print(table, justify="center")
|
||||
|
||||
selected = await session.prompt_async(
|
||||
selected = await prompt_session.prompt_async(
|
||||
message=prompt_message,
|
||||
validator=key_validator(keys),
|
||||
default=default_selection,
|
||||
|
@ -250,7 +250,7 @@ async def select_value_from_list(
|
|||
title: str,
|
||||
selections: Sequence[str],
|
||||
console: Console | None = None,
|
||||
session: PromptSession | None = None,
|
||||
prompt_session: PromptSession | None = None,
|
||||
prompt_message: str = "Select an option > ",
|
||||
default_selection: str = "",
|
||||
columns: int = 4,
|
||||
|
@ -283,7 +283,7 @@ async def select_value_from_list(
|
|||
caption_style,
|
||||
highlight,
|
||||
)
|
||||
session = session or PromptSession()
|
||||
prompt_session = prompt_session or PromptSession()
|
||||
console = console or Console(color_system="auto")
|
||||
|
||||
selection_index = await prompt_for_index(
|
||||
|
@ -291,7 +291,7 @@ async def select_value_from_list(
|
|||
table,
|
||||
default_selection=default_selection,
|
||||
console=console,
|
||||
session=session,
|
||||
prompt_session=prompt_session,
|
||||
prompt_message=prompt_message,
|
||||
)
|
||||
|
||||
|
@ -302,12 +302,12 @@ async def select_key_from_dict(
|
|||
selections: dict[str, SelectionOption],
|
||||
table: Table,
|
||||
console: Console | None = None,
|
||||
session: PromptSession | None = None,
|
||||
prompt_session: PromptSession | None = None,
|
||||
prompt_message: str = "Select an option > ",
|
||||
default_selection: str = "",
|
||||
) -> Any:
|
||||
"""Prompt for a key from a dict, returns the key."""
|
||||
session = session or PromptSession()
|
||||
prompt_session = prompt_session or PromptSession()
|
||||
console = console or Console(color_system="auto")
|
||||
|
||||
console.print(table)
|
||||
|
@ -317,7 +317,7 @@ async def select_key_from_dict(
|
|||
table,
|
||||
default_selection=default_selection,
|
||||
console=console,
|
||||
session=session,
|
||||
prompt_session=prompt_session,
|
||||
prompt_message=prompt_message,
|
||||
)
|
||||
|
||||
|
@ -326,12 +326,12 @@ async def select_value_from_dict(
|
|||
selections: dict[str, SelectionOption],
|
||||
table: Table,
|
||||
console: Console | None = None,
|
||||
session: PromptSession | None = None,
|
||||
prompt_session: PromptSession | None = None,
|
||||
prompt_message: str = "Select an option > ",
|
||||
default_selection: str = "",
|
||||
) -> Any:
|
||||
"""Prompt for a key from a dict, but return the value."""
|
||||
session = session or PromptSession()
|
||||
prompt_session = prompt_session or PromptSession()
|
||||
console = console or Console(color_system="auto")
|
||||
|
||||
console.print(table)
|
||||
|
@ -341,7 +341,7 @@ async def select_value_from_dict(
|
|||
table,
|
||||
default_selection=default_selection,
|
||||
console=console,
|
||||
session=session,
|
||||
prompt_session=prompt_session,
|
||||
prompt_message=prompt_message,
|
||||
)
|
||||
|
||||
|
@ -352,7 +352,7 @@ async def get_selection_from_dict_menu(
|
|||
title: str,
|
||||
selections: dict[str, SelectionOption],
|
||||
console: Console | None = None,
|
||||
session: PromptSession | None = None,
|
||||
prompt_session: PromptSession | None = None,
|
||||
prompt_message: str = "Select an option > ",
|
||||
default_selection: str = "",
|
||||
):
|
||||
|
@ -366,7 +366,7 @@ async def get_selection_from_dict_menu(
|
|||
selections,
|
||||
table,
|
||||
console,
|
||||
session,
|
||||
prompt_session,
|
||||
prompt_message,
|
||||
default_selection,
|
||||
)
|
||||
|
|
|
@ -26,7 +26,7 @@ class SelectionAction(BaseAction):
|
|||
def __init__(
|
||||
self,
|
||||
name: str,
|
||||
selections: list[str] | dict[str, SelectionOption],
|
||||
selections: list[str] | set[str] | tuple[str, ...] | dict[str, SelectionOption],
|
||||
*,
|
||||
title: str = "Select an option",
|
||||
columns: int = 2,
|
||||
|
@ -36,7 +36,7 @@ class SelectionAction(BaseAction):
|
|||
inject_last_result_as: str = "last_result",
|
||||
return_key: bool = False,
|
||||
console: Console | None = None,
|
||||
session: PromptSession | None = None,
|
||||
prompt_session: PromptSession | None = None,
|
||||
never_prompt: bool = False,
|
||||
show_table: bool = True,
|
||||
):
|
||||
|
@ -51,7 +51,7 @@ class SelectionAction(BaseAction):
|
|||
self.title = title
|
||||
self.columns = columns
|
||||
self.console = console or Console(color_system="auto")
|
||||
self.session = session or PromptSession()
|
||||
self.prompt_session = prompt_session or PromptSession()
|
||||
self.default_selection = default_selection
|
||||
self.prompt_message = prompt_message
|
||||
self.show_table = show_table
|
||||
|
@ -61,9 +61,11 @@ class SelectionAction(BaseAction):
|
|||
return self._selections
|
||||
|
||||
@selections.setter
|
||||
def selections(self, value: list[str] | dict[str, SelectionOption]):
|
||||
if isinstance(value, list):
|
||||
self._selections: list[str] | CaseInsensitiveDict = value
|
||||
def selections(
|
||||
self, value: list[str] | set[str] | tuple[str, ...] | dict[str, SelectionOption]
|
||||
):
|
||||
if isinstance(value, (list, tuple, set)):
|
||||
self._selections: list[str] | CaseInsensitiveDict = list(value)
|
||||
elif isinstance(value, dict):
|
||||
cid = CaseInsensitiveDict()
|
||||
cid.update(value)
|
||||
|
@ -123,7 +125,7 @@ class SelectionAction(BaseAction):
|
|||
table,
|
||||
default_selection=effective_default,
|
||||
console=self.console,
|
||||
session=self.session,
|
||||
prompt_session=self.prompt_session,
|
||||
prompt_message=self.prompt_message,
|
||||
show_table=self.show_table,
|
||||
)
|
||||
|
@ -140,7 +142,7 @@ class SelectionAction(BaseAction):
|
|||
table,
|
||||
default_selection=effective_default,
|
||||
console=self.console,
|
||||
session=self.session,
|
||||
prompt_session=self.prompt_session,
|
||||
prompt_message=self.prompt_message,
|
||||
show_table=self.show_table,
|
||||
)
|
||||
|
|
|
@ -1 +1 @@
|
|||
__version__ = "0.1.18"
|
||||
__version__ = "0.1.19"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[tool.poetry]
|
||||
name = "falyx"
|
||||
version = "0.1.18"
|
||||
version = "0.1.19"
|
||||
description = "Reliable and introspectable async CLI action framework."
|
||||
authors = ["Roland Thomas Jr <roland@rtj.dev>"]
|
||||
license = "MIT"
|
||||
|
|
Loading…
Reference in New Issue