falyx 0.1.22__py3-none-any.whl → 0.1.24__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
falyx/falyx.py CHANGED
@@ -51,12 +51,13 @@ from falyx.exceptions import (
51
51
  )
52
52
  from falyx.execution_registry import ExecutionRegistry as er
53
53
  from falyx.hook_manager import Hook, HookManager, HookType
54
+ from falyx.logger import logger
54
55
  from falyx.options_manager import OptionsManager
55
56
  from falyx.parsers import get_arg_parsers
56
57
  from falyx.retry import RetryPolicy
57
58
  from falyx.signals import BackSignal, QuitSignal
58
59
  from falyx.themes.colors import OneColors, get_nord_theme
59
- from falyx.utils import CaseInsensitiveDict, chunks, get_program_invocation, logger
60
+ from falyx.utils import CaseInsensitiveDict, chunks, get_program_invocation
60
61
  from falyx.version import __version__
61
62
 
62
63
 
@@ -78,7 +79,8 @@ class Falyx:
78
79
  Key Features:
79
80
  - Interactive menu with Rich rendering and Prompt Toolkit input handling
80
81
  - Dynamic command management with alias and abbreviation matching
81
- - Full lifecycle hooks (before, success, error, after, teardown) at both menu and command levels
82
+ - Full lifecycle hooks (before, success, error, after, teardown) at both menu and
83
+ command levels
82
84
  - Built-in retry support, spinner visuals, and confirmation prompts
83
85
  - Submenu nesting and action chaining
84
86
  - History tracking, help generation, and run key execution modes
@@ -99,12 +101,14 @@ class Falyx:
99
101
  force_confirm (bool): Seed default for `OptionsManager["force_confirm"]`
100
102
  cli_args (Namespace | None): Parsed CLI arguments, usually from argparse.
101
103
  options (OptionsManager | None): Declarative option mappings.
102
- custom_table (Callable[[Falyx], Table] | Table | None): Custom menu table generator.
104
+ custom_table (Callable[[Falyx], Table] | Table | None): Custom menu table
105
+ generator.
103
106
 
104
107
  Methods:
105
- run(): Main entry point for CLI argument-based workflows. Most users will use this.
108
+ run(): Main entry point for CLI argument-based workflows. Suggested for
109
+ most use cases.
106
110
  menu(): Run the interactive menu loop.
107
- run_key(command_key, return_context): Run a command directly without showing the menu.
111
+ run_key(command_key, return_context): Run a command directly without the menu.
108
112
  add_command(): Add a single command to the menu.
109
113
  add_commands(): Add multiple commands at once.
110
114
  register_all_hooks(): Register hooks across all commands and submenus.
@@ -184,8 +188,10 @@ class Falyx:
184
188
 
185
189
  @property
186
190
  def _name_map(self) -> dict[str, Command]:
187
- """Builds a mapping of all valid input names (keys, aliases, normalized names) to Command objects.
188
- If a collision occurs, logs a warning and keeps the first registered command.
191
+ """
192
+ Builds a mapping of all valid input names (keys, aliases, normalized names) to
193
+ Command objects. If a collision occurs, logs a warning and keeps the first
194
+ registered command.
189
195
  """
190
196
  mapping: dict[str, Command] = {}
191
197
 
@@ -195,8 +201,11 @@ class Falyx:
195
201
  existing = mapping[norm]
196
202
  if existing is not cmd:
197
203
  logger.warning(
198
- f"[alias conflict] '{name}' already assigned to '{existing.description}'."
199
- f" Skipping for '{cmd.description}'."
204
+ "[alias conflict] '%s' already assigned to '%s'. "
205
+ "Skipping for '%s'.",
206
+ name,
207
+ existing.description,
208
+ cmd.description,
200
209
  )
201
210
  else:
202
211
  mapping[norm] = cmd
@@ -238,7 +247,7 @@ class Falyx:
238
247
  key="Y",
239
248
  description="History",
240
249
  aliases=["HISTORY"],
241
- action=er.get_history_action(),
250
+ action=Action(name="View Execution History", action=er.summary),
242
251
  style=OneColors.DARK_YELLOW,
243
252
  )
244
253
 
@@ -283,7 +292,8 @@ class Falyx:
283
292
  self.console.print(table, justify="center")
284
293
  if self.mode == FalyxMode.MENU:
285
294
  self.console.print(
286
- f"📦 Tip: '[{OneColors.LIGHT_YELLOW}]?[KEY][/]' to preview a command before running it.\n",
295
+ f"📦 Tip: '[{OneColors.LIGHT_YELLOW}]?[KEY][/]' to preview a command "
296
+ "before running it.\n",
287
297
  justify="center",
288
298
  )
289
299
 
@@ -291,7 +301,7 @@ class Falyx:
291
301
  """Returns the help command for the menu."""
292
302
  return Command(
293
303
  key="H",
294
- aliases=["HELP"],
304
+ aliases=["HELP", "?"],
295
305
  description="Help",
296
306
  action=self._show_help,
297
307
  style=OneColors.LIGHT_YELLOW,
@@ -346,7 +356,7 @@ class Falyx:
346
356
  is_preview, choice = self.get_command(text, from_validate=True)
347
357
  if is_preview and choice is None:
348
358
  return True
349
- return True if choice else False
359
+ return bool(choice)
350
360
 
351
361
  return Validator.from_callable(
352
362
  validator,
@@ -444,43 +454,10 @@ class Falyx:
444
454
 
445
455
  def debug_hooks(self) -> None:
446
456
  """Logs the names of all hooks registered for the menu and its commands."""
447
-
448
- def hook_names(hook_list):
449
- return [hook.__name__ for hook in hook_list]
450
-
451
- logger.debug(
452
- "Menu-level before hooks: "
453
- f"{hook_names(self.hooks._hooks[HookType.BEFORE])}"
454
- )
455
- logger.debug(
456
- f"Menu-level success hooks: {hook_names(self.hooks._hooks[HookType.ON_SUCCESS])}"
457
- )
458
- logger.debug(
459
- f"Menu-level error hooks: {hook_names(self.hooks._hooks[HookType.ON_ERROR])}"
460
- )
461
- logger.debug(
462
- f"Menu-level after hooks: {hook_names(self.hooks._hooks[HookType.AFTER])}"
463
- )
464
- logger.debug(
465
- f"Menu-level on_teardown hooks: {hook_names(self.hooks._hooks[HookType.ON_TEARDOWN])}"
466
- )
457
+ logger.debug("Menu-level hooks:\n%s", str(self.hooks))
467
458
 
468
459
  for key, command in self.commands.items():
469
- logger.debug(
470
- f"[Command '{key}'] before: {hook_names(command.hooks._hooks[HookType.BEFORE])}"
471
- )
472
- logger.debug(
473
- f"[Command '{key}'] success: {hook_names(command.hooks._hooks[HookType.ON_SUCCESS])}"
474
- )
475
- logger.debug(
476
- f"[Command '{key}'] error: {hook_names(command.hooks._hooks[HookType.ON_ERROR])}"
477
- )
478
- logger.debug(
479
- f"[Command '{key}'] after: {hook_names(command.hooks._hooks[HookType.AFTER])}"
480
- )
481
- logger.debug(
482
- f"[Command '{key}'] on_teardown: {hook_names(command.hooks._hooks[HookType.ON_TEARDOWN])}"
483
- )
460
+ logger.debug("[Command '%s'] hooks:\n%s", key, str(command.hooks))
484
461
 
485
462
  def is_key_available(self, key: str) -> bool:
486
463
  key = key.upper()
@@ -560,10 +537,24 @@ class Falyx:
560
537
  self.add_command(key, description, submenu.menu, style=style)
561
538
  submenu.update_exit_command(key="B", description="Back", aliases=["BACK"])
562
539
 
563
- def add_commands(self, commands: list[dict]) -> None:
564
- """Adds multiple commands to the menu."""
540
+ def add_commands(self, commands: list[Command] | list[dict]) -> None:
541
+ """Adds a list of Command instances or config dicts."""
565
542
  for command in commands:
566
- self.add_command(**command)
543
+ if isinstance(command, dict):
544
+ self.add_command(**command)
545
+ elif isinstance(command, Command):
546
+ self.add_command_from_command(command)
547
+ else:
548
+ raise FalyxError(
549
+ "Command must be a dictionary or an instance of Command."
550
+ )
551
+
552
+ def add_command_from_command(self, command: Command) -> None:
553
+ """Adds a command to the menu from an existing Command object."""
554
+ if not isinstance(command, Command):
555
+ raise FalyxError("command must be an instance of Command.")
556
+ self._validate_command_key(command.key)
557
+ self.commands[command.key] = command
567
558
 
568
559
  def add_command(
569
560
  self,
@@ -572,7 +563,7 @@ class Falyx:
572
563
  action: BaseAction | Callable[[], Any],
573
564
  *,
574
565
  args: tuple = (),
575
- kwargs: dict[str, Any] = {},
566
+ kwargs: dict[str, Any] | None = None,
576
567
  hidden: bool = False,
577
568
  aliases: list[str] | None = None,
578
569
  help_text: str = "",
@@ -605,7 +596,7 @@ class Falyx:
605
596
  description=description,
606
597
  action=action,
607
598
  args=args,
608
- kwargs=kwargs,
599
+ kwargs=kwargs if kwargs else {},
609
600
  hidden=hidden,
610
601
  aliases=aliases if aliases else [],
611
602
  help_text=help_text,
@@ -651,20 +642,26 @@ class Falyx:
651
642
  bottom_row = []
652
643
  if self.history_command:
653
644
  bottom_row.append(
654
- f"[{self.history_command.key}] [{self.history_command.style}]{self.history_command.description}"
645
+ f"[{self.history_command.key}] [{self.history_command.style}]"
646
+ f"{self.history_command.description}"
655
647
  )
656
648
  if self.help_command:
657
649
  bottom_row.append(
658
- f"[{self.help_command.key}] [{self.help_command.style}]{self.help_command.description}"
650
+ f"[{self.help_command.key}] [{self.help_command.style}]"
651
+ f"{self.help_command.description}"
659
652
  )
660
653
  bottom_row.append(
661
- f"[{self.exit_command.key}] [{self.exit_command.style}]{self.exit_command.description}"
654
+ f"[{self.exit_command.key}] [{self.exit_command.style}]"
655
+ f"{self.exit_command.description}"
662
656
  )
663
657
  return bottom_row
664
658
 
665
659
  def build_default_table(self) -> Table:
666
- """Build the standard table layout. Developers can subclass or call this in custom tables."""
667
- table = Table(title=self.title, show_header=False, box=box.SIMPLE, expand=True)
660
+ """
661
+ Build the standard table layout. Developers can subclass or call this
662
+ in custom tables.
663
+ """
664
+ table = Table(title=self.title, show_header=False, box=box.SIMPLE, expand=True) # type: ignore[arg-type]
668
665
  visible_commands = [item for item in self.commands.items() if not item[1].hidden]
669
666
  for chunk in chunks(visible_commands, self.columns):
670
667
  row = []
@@ -694,12 +691,18 @@ class Falyx:
694
691
  def get_command(
695
692
  self, choice: str, from_validate=False
696
693
  ) -> tuple[bool, Command | None]:
697
- """Returns the selected command based on user input. Supports keys, aliases, and abbreviations."""
694
+ """
695
+ Returns the selected command based on user input.
696
+ Supports keys, aliases, and abbreviations.
697
+ """
698
698
  is_preview, choice = self.parse_preview_command(choice)
699
- if is_preview and not choice:
699
+ if is_preview and not choice and self.help_command:
700
+ is_preview = False
701
+ choice = "?"
702
+ elif is_preview and not choice:
700
703
  if not from_validate:
701
704
  self.console.print(
702
- f"[{OneColors.DARK_RED}]❌ You must enter a command for preview mode.[/]"
705
+ f"[{OneColors.DARK_RED}]❌ You must enter a command for preview mode."
703
706
  )
704
707
  return is_preview, None
705
708
 
@@ -717,7 +720,8 @@ class Falyx:
717
720
  if fuzzy_matches:
718
721
  if not from_validate:
719
722
  self.console.print(
720
- f"[{OneColors.LIGHT_YELLOW}]⚠️ Unknown command '{choice}'. Did you mean:[/] "
723
+ f"[{OneColors.LIGHT_YELLOW}]⚠️ Unknown command '{choice}'. "
724
+ "Did you mean:"
721
725
  )
722
726
  for match in fuzzy_matches:
723
727
  cmd = name_map[match]
@@ -742,7 +746,7 @@ class Falyx:
742
746
  self, selected_command: Command, error: Exception
743
747
  ) -> None:
744
748
  """Handles errors that occur during the action of the selected command."""
745
- logger.exception(f"Error executing '{selected_command.description}': {error}")
749
+ logger.exception("Error executing '%s': %s", selected_command.description, error)
746
750
  self.console.print(
747
751
  f"[{OneColors.DARK_RED}]An error occurred while executing "
748
752
  f"{selected_command.description}:[/] {error}"
@@ -753,27 +757,27 @@ class Falyx:
753
757
  choice = await self.prompt_session.prompt_async()
754
758
  is_preview, selected_command = self.get_command(choice)
755
759
  if not selected_command:
756
- logger.info(f"Invalid command '{choice}'.")
760
+ logger.info("Invalid command '%s'.", choice)
757
761
  return True
758
762
 
759
763
  if is_preview:
760
- logger.info(f"Preview command '{selected_command.key}' selected.")
764
+ logger.info("Preview command '%s' selected.", selected_command.key)
761
765
  await selected_command.preview()
762
766
  return True
763
767
 
764
768
  if selected_command.requires_input:
765
769
  program = get_program_invocation()
766
770
  self.console.print(
767
- f"[{OneColors.LIGHT_YELLOW}]⚠️ Command '{selected_command.key}' requires input "
768
- f"and must be run via [{OneColors.MAGENTA}]'{program} run'[{OneColors.LIGHT_YELLOW}] "
769
- "with proper piping or arguments.[/]"
771
+ f"[{OneColors.LIGHT_YELLOW}]⚠️ Command '{selected_command.key}' requires"
772
+ f" input and must be run via [{OneColors.MAGENTA}]'{program} run"
773
+ f"'[{OneColors.LIGHT_YELLOW}] with proper piping or arguments.[/]"
770
774
  )
771
775
  return True
772
776
 
773
777
  self.last_run_command = selected_command
774
778
 
775
779
  if selected_command == self.exit_command:
776
- logger.info(f"🔙 Back selected: exiting {self.get_title()}")
780
+ logger.info("🔙 Back selected: exiting %s", self.get_title())
777
781
  return False
778
782
 
779
783
  context = self._create_context(selected_command)
@@ -804,7 +808,7 @@ class Falyx:
804
808
  return None
805
809
 
806
810
  if is_preview:
807
- logger.info(f"Preview command '{selected_command.key}' selected.")
811
+ logger.info("Preview command '%s' selected.", selected_command.key)
808
812
  await selected_command.preview()
809
813
  return None
810
814
 
@@ -823,13 +827,13 @@ class Falyx:
823
827
 
824
828
  await self.hooks.trigger(HookType.ON_SUCCESS, context)
825
829
  logger.info("[run_key] ✅ '%s' complete.", selected_command.description)
826
- except (KeyboardInterrupt, EOFError):
830
+ except (KeyboardInterrupt, EOFError) as error:
827
831
  logger.warning(
828
- "[run_key] ⚠️ Interrupted by user: ", selected_command.description
832
+ "[run_key] ⚠️ Interrupted by user: %s", selected_command.description
829
833
  )
830
834
  raise FalyxError(
831
835
  f"[run_key] ⚠️ '{selected_command.description}' interrupted by user."
832
- )
836
+ ) from error
833
837
  except Exception as error:
834
838
  context.exception = error
835
839
  await self.hooks.trigger(HookType.ON_ERROR, context)
@@ -868,7 +872,8 @@ class Falyx:
868
872
  selected_command.action.set_retry_policy(selected_command.retry_policy)
869
873
  else:
870
874
  logger.warning(
871
- f"[Command:{selected_command.key}] Retry requested, but action is not an Action instance."
875
+ "[Command:%s] Retry requested, but action is not an Action instance.",
876
+ selected_command.key,
872
877
  )
873
878
 
874
879
  def print_message(self, message: str | Markdown | dict[str, Any]) -> None:
@@ -887,32 +892,33 @@ class Falyx:
887
892
 
888
893
  async def menu(self) -> None:
889
894
  """Runs the menu and handles user input."""
890
- logger.info(f"Running menu: {self.get_title()}")
895
+ logger.info("Running menu: %s", self.get_title())
891
896
  self.debug_hooks()
892
897
  if self.welcome_message:
893
898
  self.print_message(self.welcome_message)
894
- while True:
895
- if callable(self.render_menu):
896
- self.render_menu(self)
897
- else:
898
- self.console.print(self.table, justify="center")
899
- try:
900
- task = asyncio.create_task(self.process_command())
901
- should_continue = await task
902
- if not should_continue:
899
+ try:
900
+ while True:
901
+ if callable(self.render_menu):
902
+ self.render_menu(self)
903
+ else:
904
+ self.console.print(self.table, justify="center")
905
+ try:
906
+ task = asyncio.create_task(self.process_command())
907
+ should_continue = await task
908
+ if not should_continue:
909
+ break
910
+ except (EOFError, KeyboardInterrupt):
911
+ logger.info("EOF or KeyboardInterrupt. Exiting menu.")
912
+ break
913
+ except QuitSignal:
914
+ logger.info("QuitSignal received. Exiting menu.")
903
915
  break
904
- except (EOFError, KeyboardInterrupt):
905
- logger.info("EOF or KeyboardInterrupt. Exiting menu.")
906
- break
907
- except QuitSignal:
908
- logger.info("QuitSignal received. Exiting menu.")
909
- break
910
- except BackSignal:
911
- logger.info("BackSignal received.")
912
- finally:
913
- logger.info(f"Exiting menu: {self.get_title()}")
914
- if self.exit_message:
915
- self.print_message(self.exit_message)
916
+ except BackSignal:
917
+ logger.info("BackSignal received.")
918
+ finally:
919
+ logger.info("Exiting menu: %s", self.get_title())
920
+ if self.exit_message:
921
+ self.print_message(self.exit_message)
916
922
 
917
923
  async def run(self) -> None:
918
924
  """Run Falyx CLI with structured subcommands."""
@@ -946,7 +952,7 @@ class Falyx:
946
952
  _, command = self.get_command(self.cli_args.name)
947
953
  if not command:
948
954
  self.console.print(
949
- f"[{OneColors.DARK_RED}]❌ Command '{self.cli_args.name}' not found.[/]"
955
+ f"[{OneColors.DARK_RED}]❌ Command '{self.cli_args.name}' not found."
950
956
  )
951
957
  sys.exit(1)
952
958
  self.console.print(
@@ -961,7 +967,7 @@ class Falyx:
961
967
  if is_preview:
962
968
  if command is None:
963
969
  sys.exit(1)
964
- logger.info(f"Preview command '{command.key}' selected.")
970
+ logger.info("Preview command '%s' selected.", command.key)
965
971
  await command.preview()
966
972
  sys.exit(0)
967
973
  if not command:
@@ -986,12 +992,14 @@ class Falyx:
986
992
  ]
987
993
  if not matching:
988
994
  self.console.print(
989
- f"[{OneColors.LIGHT_YELLOW}]⚠️ No commands found with tag: '{self.cli_args.tag}'[/]"
995
+ f"[{OneColors.LIGHT_YELLOW}]⚠️ No commands found with tag: "
996
+ f"'{self.cli_args.tag}'"
990
997
  )
991
998
  sys.exit(1)
992
999
 
993
1000
  self.console.print(
994
- f"[{OneColors.CYAN_b}]🚀 Running all commands with tag:[/] {self.cli_args.tag}"
1001
+ f"[{OneColors.CYAN_b}]🚀 Running all commands with tag:[/] "
1002
+ f"{self.cli_args.tag}"
995
1003
  )
996
1004
  for cmd in matching:
997
1005
  self._set_retry_policy(cmd)
falyx/hook_manager.py CHANGED
@@ -7,7 +7,7 @@ from enum import Enum
7
7
  from typing import Awaitable, Callable, Dict, List, Optional, Union
8
8
 
9
9
  from falyx.context import ExecutionContext
10
- from falyx.utils import logger
10
+ from falyx.logger import logger
11
11
 
12
12
  Hook = Union[
13
13
  Callable[[ExecutionContext], None], Callable[[ExecutionContext], Awaitable[None]]
@@ -34,6 +34,8 @@ class HookType(Enum):
34
34
 
35
35
 
36
36
  class HookManager:
37
+ """HookManager"""
38
+
37
39
  def __init__(self) -> None:
38
40
  self._hooks: Dict[HookType, List[Hook]] = {
39
41
  hook_type: [] for hook_type in HookType
@@ -62,8 +64,11 @@ class HookManager:
62
64
  hook(context)
63
65
  except Exception as hook_error:
64
66
  logger.warning(
65
- f"⚠️ Hook '{hook.__name__}' raised an exception during '{hook_type}'"
66
- f" for '{context.name}': {hook_error}"
67
+ "⚠️ Hook '%s' raised an exception during '%s' for '%s': %s",
68
+ hook.__name__,
69
+ hook_type,
70
+ context.name,
71
+ hook_error,
67
72
  )
68
73
 
69
74
  if hook_type == HookType.ON_ERROR:
@@ -71,3 +76,15 @@ class HookManager:
71
76
  context.exception, Exception
72
77
  ), "Context exception should be set for ON_ERROR hook"
73
78
  raise context.exception from hook_error
79
+
80
+ def __str__(self) -> str:
81
+ """Return a formatted string of registered hooks grouped by hook type."""
82
+
83
+ def format_hook_list(hooks: list[Hook]) -> str:
84
+ return ", ".join(h.__name__ for h in hooks) if hooks else "—"
85
+
86
+ lines = ["<HookManager>"]
87
+ for hook_type in HookType:
88
+ hook_list = self._hooks.get(hook_type, [])
89
+ lines.append(f" {hook_type.value}: {format_hook_list(hook_list)}")
90
+ return "\n".join(lines)
falyx/hooks.py CHANGED
@@ -5,11 +5,13 @@ from typing import Any, Callable
5
5
 
6
6
  from falyx.context import ExecutionContext
7
7
  from falyx.exceptions import CircuitBreakerOpen
8
+ from falyx.logger import logger
8
9
  from falyx.themes.colors import OneColors
9
- from falyx.utils import logger
10
10
 
11
11
 
12
12
  class ResultReporter:
13
+ """Reports the success of an action."""
14
+
13
15
  def __init__(self, formatter: Callable[[Any], str] | None = None):
14
16
  """
15
17
  Optional result formatter. If not provided, uses repr(result).
@@ -41,6 +43,8 @@ class ResultReporter:
41
43
 
42
44
 
43
45
  class CircuitBreaker:
46
+ """Circuit Breaker pattern to prevent repeated failures."""
47
+
44
48
  def __init__(self, max_failures=3, reset_timeout=10):
45
49
  self.max_failures = max_failures
46
50
  self.reset_timeout = reset_timeout
@@ -55,7 +59,7 @@ class CircuitBreaker:
55
59
  f"🔴 Circuit open for '{name}' until {time.ctime(self.open_until)}."
56
60
  )
57
61
  else:
58
- logger.info(f"🟢 Circuit closed again for '{name}'.")
62
+ logger.info("🟢 Circuit closed again for '%s'.")
59
63
  self.failures = 0
60
64
  self.open_until = None
61
65
 
@@ -63,15 +67,18 @@ class CircuitBreaker:
63
67
  name = context.name
64
68
  self.failures += 1
65
69
  logger.warning(
66
- f"⚠️ CircuitBreaker: '{name}' failure {self.failures}/{self.max_failures}."
70
+ "⚠️ CircuitBreaker: '%s' failure %s/%s.",
71
+ name,
72
+ self.failures,
73
+ self.max_failures,
67
74
  )
68
75
  if self.failures >= self.max_failures:
69
76
  self.open_until = time.time() + self.reset_timeout
70
77
  logger.error(
71
- f"🔴 Circuit opened for '{name}' until {time.ctime(self.open_until)}."
78
+ "🔴 Circuit opened for '%s' until %s.", name, time.ctime(self.open_until)
72
79
  )
73
80
 
74
- def after_hook(self, context: ExecutionContext):
81
+ def after_hook(self, _: ExecutionContext):
75
82
  self.failures = 0
76
83
 
77
84
  def is_open(self):
falyx/http_action.py CHANGED
@@ -16,8 +16,8 @@ from rich.tree import Tree
16
16
  from falyx.action import Action
17
17
  from falyx.context import ExecutionContext, SharedContext
18
18
  from falyx.hook_manager import HookManager, HookType
19
+ from falyx.logger import logger
19
20
  from falyx.themes.colors import OneColors
20
- from falyx.utils import logger
21
21
 
22
22
 
23
23
  async def close_shared_http_session(context: ExecutionContext) -> None:
@@ -35,9 +35,9 @@ class HTTPAction(Action):
35
35
  """
36
36
  An Action for executing HTTP requests using aiohttp with shared session reuse.
37
37
 
38
- This action integrates seamlessly into Falyx pipelines, with automatic session management,
39
- result injection, and lifecycle hook support. It is ideal for CLI-driven API workflows
40
- where you need to call remote services and process their responses.
38
+ This action integrates seamlessly into Falyx pipelines, with automatic session
39
+ management, result injection, and lifecycle hook support. It is ideal for CLI-driven
40
+ API workflows where you need to call remote services and process their responses.
41
41
 
42
42
  Features:
43
43
  - Uses aiohttp for asynchronous HTTP requests
@@ -97,7 +97,7 @@ class HTTPAction(Action):
97
97
  retry_policy=retry_policy,
98
98
  )
99
99
 
100
- async def _request(self, *args, **kwargs) -> dict[str, Any]:
100
+ async def _request(self, *_, **__) -> dict[str, Any]:
101
101
  if self.shared_context:
102
102
  context: SharedContext = self.shared_context
103
103
  session = context.get("http_session")
@@ -153,6 +153,7 @@ class HTTPAction(Action):
153
153
  def __str__(self):
154
154
  return (
155
155
  f"HTTPAction(name={self.name!r}, method={self.method!r}, url={self.url!r}, "
156
- f"headers={self.headers!r}, params={self.params!r}, json={self.json!r}, data={self.data!r}, "
157
- f"retry={self.retry_policy.enabled}, inject_last_result={self.inject_last_result})"
156
+ f"headers={self.headers!r}, params={self.params!r}, json={self.json!r}, "
157
+ f"data={self.data!r}, retry={self.retry_policy.enabled}, "
158
+ f"inject_last_result={self.inject_last_result})"
158
159
  )