Add ResultReport hook

This commit is contained in:
Roland Thomas Jr 2025-04-17 22:34:52 -04:00
parent 7b74b98168
commit ebcd4b43c6
4 changed files with 25 additions and 8 deletions

View File

@ -6,8 +6,6 @@ from typing import Any
from pydantic import BaseModel, ConfigDict, Field from pydantic import BaseModel, ConfigDict, Field
from rich.console import Console from rich.console import Console
console = Console(color_system="auto")
class ExecutionContext(BaseModel): class ExecutionContext(BaseModel):
name: str name: str
@ -23,6 +21,7 @@ class ExecutionContext(BaseModel):
end_wall: datetime | None = None end_wall: datetime | None = None
extra: dict[str, Any] = Field(default_factory=dict) extra: dict[str, Any] = Field(default_factory=dict)
console: Console = Field(default_factory=lambda: Console(color_system="auto"))
model_config = ConfigDict(arbitrary_types_allowed=True) model_config = ConfigDict(arbitrary_types_allowed=True)
@ -75,7 +74,7 @@ class ExecutionContext(BaseModel):
message.append(f"❌ Exception: {summary['exception']}") message.append(f"❌ Exception: {summary['exception']}")
else: else:
message.append(f"✅ Result: {summary['result']}") message.append(f"✅ Result: {summary['result']}")
(logger or console.print)("".join(message)) (logger or self.console.print)("".join(message))
def to_log_line(self) -> str: def to_log_line(self) -> str:
"""Structured flat-line format for logging and metrics.""" """Structured flat-line format for logging and metrics."""

View File

@ -791,11 +791,10 @@ class Falyx:
sys.exit(1) sys.exit(1)
self._set_retry_policy(command) self._set_retry_policy(command)
try: try:
result = await self.headless(self.cli_args.name) await self.headless(self.cli_args.name)
except FalyxError as error: except FalyxError as error:
self.console.print(f"[{OneColors.DARK_RED}]❌ Error: {error}[/]") self.console.print(f"[{OneColors.DARK_RED}]❌ Error: {error}[/]")
sys.exit(1) sys.exit(1)
self.console.print(f"[{OneColors.GREEN}]✅ Result:[/] {result}")
sys.exit(0) sys.exit(0)
if self.cli_args.command == "run-all": if self.cli_args.command == "run-all":
@ -807,7 +806,7 @@ class Falyx:
self.console.print(f"[{OneColors.LIGHT_YELLOW}]⚠️ No commands found with tag: '{self.cli_args.tag}'[/]") self.console.print(f"[{OneColors.LIGHT_YELLOW}]⚠️ No commands found with tag: '{self.cli_args.tag}'[/]")
sys.exit(1) sys.exit(1)
self.console.print(f"[bold cyan]🚀 Running all commands with tag:[/] {self.cli_args.tag}") self.console.print(f"[{OneColors.CYAN_b}]🚀 Running all commands with tag:[/] {self.cli_args.tag}")
for cmd in matching: for cmd in matching:
self._set_retry_policy(cmd) self._set_retry_policy(cmd)
await self.headless(cmd.key) await self.headless(cmd.key)

View File

@ -3,9 +3,29 @@ import time
from falyx.context import ExecutionContext from falyx.context import ExecutionContext
from falyx.exceptions import CircuitBreakerOpen from falyx.exceptions import CircuitBreakerOpen
from falyx.themes.colors import OneColors
from falyx.utils import logger from falyx.utils import logger
class ResultReporter:
def __init__(self, formatter: callable = None):
"""
Optional result formatter. If not provided, uses repr(result).
"""
self.formatter = formatter or (lambda r: repr(r))
@property
def __name__(self):
return "ResultReporter"
async def report(self, context: ExecutionContext):
if context.result is not None:
result_text = self.formatter(context.result)
duration = f"{context.duration:.3f}s" if context.duration is not None else "n/a"
context.console.print(f"[{OneColors.GREEN}]✅ '{context.name}' "
f"completed:[/] {result_text} in {duration}.")
class CircuitBreaker: class CircuitBreaker:
def __init__(self, max_failures=3, reset_timeout=10): def __init__(self, max_failures=3, reset_timeout=10):
self.max_failures = max_failures self.max_failures = max_failures
@ -41,4 +61,3 @@ class CircuitBreaker:
self.failures = 0 self.failures = 0
self.open_until = None self.open_until = None
logger.info("🔄 Circuit reset.") logger.info("🔄 Circuit reset.")

View File

@ -1,6 +1,6 @@
[tool.poetry] [tool.poetry]
name = "falyx" name = "falyx"
version = "0.1.2" version = "0.1.4"
description = "Reliable and introspectable async CLI action framework." description = "Reliable and introspectable async CLI action framework."
authors = ["Roland Thomas Jr <roland@rtj.dev>"] authors = ["Roland Thomas Jr <roland@rtj.dev>"]
license = "MIT" license = "MIT"