Create action submodule, add various examples
This commit is contained in:
48
examples/action_factory_demo.py
Normal file
48
examples/action_factory_demo.py
Normal file
@ -0,0 +1,48 @@
|
||||
import asyncio
|
||||
|
||||
from falyx import Falyx
|
||||
from falyx.action import ActionFactoryAction, ChainedAction, HTTPAction, SelectionAction
|
||||
|
||||
# Selection of a post ID to fetch (just an example set)
|
||||
post_selector = SelectionAction(
|
||||
name="Pick Post ID",
|
||||
selections=["1", "2", "3", "4", "5"],
|
||||
title="Choose a Post ID to submit",
|
||||
prompt_message="Post ID > ",
|
||||
show_table=True,
|
||||
)
|
||||
|
||||
|
||||
# Factory that builds and executes the actual HTTP POST request
|
||||
def build_post_action(post_id) -> HTTPAction:
|
||||
print(f"Building HTTPAction for Post ID: {post_id}")
|
||||
return HTTPAction(
|
||||
name=f"POST to /posts (id={post_id})",
|
||||
method="POST",
|
||||
url="https://jsonplaceholder.typicode.com/posts",
|
||||
json={"title": "foo", "body": "bar", "userId": int(post_id)},
|
||||
)
|
||||
|
||||
|
||||
post_factory = ActionFactoryAction(
|
||||
name="Build HTTPAction from Post ID",
|
||||
factory=build_post_action,
|
||||
inject_last_result=True,
|
||||
inject_into="post_id",
|
||||
preview_kwargs={"post_id": "100"},
|
||||
)
|
||||
|
||||
# Wrap in a ChainedAction
|
||||
chain = ChainedAction(
|
||||
name="Submit Post Flow",
|
||||
actions=[post_selector, post_factory],
|
||||
auto_inject=True,
|
||||
)
|
||||
|
||||
flx = Falyx()
|
||||
flx.add_command(
|
||||
key="S",
|
||||
description="Submit a Post",
|
||||
action=chain,
|
||||
)
|
||||
asyncio.run(flx.run())
|
10
examples/config_loading.py
Normal file
10
examples/config_loading.py
Normal file
@ -0,0 +1,10 @@
|
||||
"""config_loading.py"""
|
||||
|
||||
from falyx.config import loader
|
||||
|
||||
flx = loader("falyx.yaml")
|
||||
|
||||
if __name__ == "__main__":
|
||||
import asyncio
|
||||
|
||||
asyncio.run(flx.run())
|
22
examples/falyx.yaml
Normal file
22
examples/falyx.yaml
Normal file
@ -0,0 +1,22 @@
|
||||
commands:
|
||||
- key: P
|
||||
description: Pipeline Demo
|
||||
action: pipeline_demo.pipeline
|
||||
tags: [pipeline, demo]
|
||||
help_text: Run Demployment Pipeline with retries.
|
||||
|
||||
- key: G
|
||||
description: Run HTTP Action Group
|
||||
action: http_demo.action_group
|
||||
tags: [http, demo]
|
||||
|
||||
- key: S
|
||||
description: Select a file
|
||||
action: file_select.sf
|
||||
tags: [file, select, demo]
|
||||
|
||||
- key: M
|
||||
description: Menu Demo
|
||||
action: menu_demo.menu
|
||||
tags: [menu, demo]
|
||||
help_text: Run a menu demo with multiple options.
|
171
examples/falyx_demo.py
Normal file
171
examples/falyx_demo.py
Normal file
@ -0,0 +1,171 @@
|
||||
"""
|
||||
Falyx CLI Framework
|
||||
|
||||
Copyright (c) 2025 rtj.dev LLC.
|
||||
Licensed under the MIT License. See LICENSE file for details.
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
import random
|
||||
from argparse import Namespace
|
||||
|
||||
from falyx.action import Action, ActionGroup, ChainedAction
|
||||
from falyx.falyx import Falyx
|
||||
from falyx.parsers import FalyxParsers, get_arg_parsers
|
||||
from falyx.version import __version__
|
||||
|
||||
|
||||
class Foo:
|
||||
def __init__(self, flx: Falyx) -> None:
|
||||
self.flx = flx
|
||||
|
||||
async def build(self):
|
||||
await asyncio.sleep(1)
|
||||
print("✅ Build complete!")
|
||||
return "Build complete!"
|
||||
|
||||
async def test(self):
|
||||
await asyncio.sleep(1)
|
||||
print("✅ Tests passed!")
|
||||
return "Tests passed!"
|
||||
|
||||
async def deploy(self):
|
||||
await asyncio.sleep(1)
|
||||
print("✅ Deployment complete!")
|
||||
return "Deployment complete!"
|
||||
|
||||
async def clean(self):
|
||||
print("🧹 Cleaning...")
|
||||
await asyncio.sleep(1)
|
||||
print("✅ Clean complete!")
|
||||
return "Clean complete!"
|
||||
|
||||
async def build_package(self):
|
||||
print("🔨 Building...")
|
||||
await asyncio.sleep(1)
|
||||
print("✅ Build finished!")
|
||||
return "Build finished!"
|
||||
|
||||
async def package(self):
|
||||
print("📦 Packaging...")
|
||||
await asyncio.sleep(1)
|
||||
print("✅ Package complete!")
|
||||
return "Package complete!"
|
||||
|
||||
async def run_tests(self):
|
||||
print("🧪 Running tests...")
|
||||
await asyncio.sleep(random.randint(1, 3))
|
||||
print("✅ Tests passed!")
|
||||
return "Tests passed!"
|
||||
|
||||
async def run_integration_tests(self):
|
||||
print("🔗 Running integration tests...")
|
||||
await asyncio.sleep(random.randint(1, 3))
|
||||
print("✅ Integration tests passed!")
|
||||
return "Integration tests passed!"
|
||||
|
||||
async def run_linter(self):
|
||||
print("🧹 Running linter...")
|
||||
await asyncio.sleep(random.randint(1, 3))
|
||||
print("✅ Linter passed!")
|
||||
return "Linter passed!"
|
||||
|
||||
async def run(self):
|
||||
await self.flx.run()
|
||||
|
||||
|
||||
def parse_args() -> Namespace:
|
||||
parsers: FalyxParsers = get_arg_parsers()
|
||||
return parsers.parse_args()
|
||||
|
||||
|
||||
async def main() -> None:
|
||||
"""Build and return a Falyx instance with all your commands."""
|
||||
args = parse_args()
|
||||
flx = Falyx(
|
||||
title="🚀 Falyx CLI",
|
||||
cli_args=args,
|
||||
columns=5,
|
||||
welcome_message="Welcome to Falyx CLI!",
|
||||
exit_message="Goodbye!",
|
||||
)
|
||||
foo = Foo(flx)
|
||||
|
||||
# --- Bottom bar info ---
|
||||
flx.bottom_bar.columns = 3
|
||||
flx.bottom_bar.add_toggle_from_option("V", "Verbose", flx.options, "verbose")
|
||||
flx.bottom_bar.add_toggle_from_option("U", "Debug Hooks", flx.options, "debug_hooks")
|
||||
flx.bottom_bar.add_static("Version", f"Falyx v{__version__}")
|
||||
|
||||
# --- Command actions ---
|
||||
|
||||
# --- Single Actions ---
|
||||
flx.add_command(
|
||||
key="B",
|
||||
description="Build project",
|
||||
action=Action("Build", foo.build),
|
||||
tags=["build"],
|
||||
spinner=True,
|
||||
spinner_message="📦 Building...",
|
||||
)
|
||||
flx.add_command(
|
||||
key="T",
|
||||
description="Run tests",
|
||||
action=Action("Test", foo.test),
|
||||
tags=["test"],
|
||||
spinner=True,
|
||||
spinner_message="🧪 Running tests...",
|
||||
)
|
||||
flx.add_command(
|
||||
key="D",
|
||||
description="Deploy project",
|
||||
action=Action("Deploy", foo.deploy),
|
||||
tags=["deploy"],
|
||||
spinner=True,
|
||||
spinner_message="🚀 Deploying...",
|
||||
)
|
||||
|
||||
# --- Build pipeline (ChainedAction) ---
|
||||
pipeline = ChainedAction(
|
||||
name="Full Build Pipeline",
|
||||
actions=[
|
||||
Action("Clean", foo.clean),
|
||||
Action("Build", foo.build_package),
|
||||
Action("Package", foo.package),
|
||||
],
|
||||
)
|
||||
flx.add_command(
|
||||
key="P",
|
||||
description="Run Build Pipeline",
|
||||
action=pipeline,
|
||||
tags=["build", "pipeline"],
|
||||
spinner=True,
|
||||
spinner_message="🔨 Running build pipeline...",
|
||||
spinner_type="line",
|
||||
)
|
||||
|
||||
# --- Test suite (ActionGroup) ---
|
||||
test_suite = ActionGroup(
|
||||
name="Test Suite",
|
||||
actions=[
|
||||
Action("Unit Tests", foo.run_tests),
|
||||
Action("Integration Tests", foo.run_integration_tests),
|
||||
Action("Lint", foo.run_linter),
|
||||
],
|
||||
)
|
||||
flx.add_command(
|
||||
key="G",
|
||||
description="Run All Tests",
|
||||
action=test_suite,
|
||||
tags=["test", "parallel"],
|
||||
spinner=True,
|
||||
spinner_type="line",
|
||||
)
|
||||
await foo.run()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
asyncio.run(main())
|
||||
except (KeyboardInterrupt, EOFError):
|
||||
pass
|
26
examples/file_select.py
Normal file
26
examples/file_select.py
Normal file
@ -0,0 +1,26 @@
|
||||
import asyncio
|
||||
|
||||
from falyx import Falyx
|
||||
from falyx.action import SelectFileAction
|
||||
from falyx.action.types import FileReturnType
|
||||
|
||||
sf = SelectFileAction(
|
||||
name="select_file",
|
||||
suffix_filter=".py",
|
||||
title="Select a YAML file",
|
||||
prompt_message="Choose > ",
|
||||
return_type=FileReturnType.TEXT,
|
||||
columns=3,
|
||||
)
|
||||
|
||||
flx = Falyx()
|
||||
|
||||
flx.add_command(
|
||||
key="S",
|
||||
description="Select a file",
|
||||
action=sf,
|
||||
help_text="Select a file from the current directory",
|
||||
)
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(flx.run())
|
67
examples/http_demo.py
Normal file
67
examples/http_demo.py
Normal file
@ -0,0 +1,67 @@
|
||||
import asyncio
|
||||
|
||||
from rich.console import Console
|
||||
|
||||
from falyx import ActionGroup, Falyx
|
||||
from falyx.action import HTTPAction
|
||||
from falyx.hook_manager import HookType
|
||||
from falyx.hooks import ResultReporter
|
||||
|
||||
console = Console()
|
||||
|
||||
|
||||
action_group = ActionGroup(
|
||||
"HTTP Group",
|
||||
actions=[
|
||||
HTTPAction(
|
||||
name="Get Example",
|
||||
method="GET",
|
||||
url="https://jsonplaceholder.typicode.com/posts/1",
|
||||
headers={"Accept": "application/json"},
|
||||
retry=True,
|
||||
),
|
||||
HTTPAction(
|
||||
name="Post Example",
|
||||
method="POST",
|
||||
url="https://jsonplaceholder.typicode.com/posts",
|
||||
headers={"Content-Type": "application/json"},
|
||||
json={"title": "foo", "body": "bar", "userId": 1},
|
||||
retry=True,
|
||||
),
|
||||
HTTPAction(
|
||||
name="Put Example",
|
||||
method="PUT",
|
||||
url="https://jsonplaceholder.typicode.com/posts/1",
|
||||
headers={"Content-Type": "application/json"},
|
||||
json={"id": 1, "title": "foo", "body": "bar", "userId": 1},
|
||||
retry=True,
|
||||
),
|
||||
HTTPAction(
|
||||
name="Delete Example",
|
||||
method="DELETE",
|
||||
url="https://jsonplaceholder.typicode.com/posts/1",
|
||||
headers={"Content-Type": "application/json"},
|
||||
retry=True,
|
||||
),
|
||||
],
|
||||
)
|
||||
|
||||
reporter = ResultReporter()
|
||||
|
||||
action_group.hooks.register(
|
||||
HookType.ON_SUCCESS,
|
||||
reporter.report,
|
||||
)
|
||||
|
||||
flx = Falyx("HTTP Demo")
|
||||
|
||||
flx.add_command(
|
||||
key="G",
|
||||
description="Run HTTP Action Group",
|
||||
action=action_group,
|
||||
spinner=True,
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(flx.run())
|
113
examples/menu_demo.py
Normal file
113
examples/menu_demo.py
Normal file
@ -0,0 +1,113 @@
|
||||
import asyncio
|
||||
import time
|
||||
|
||||
from falyx import Falyx
|
||||
from falyx.action import Action, ActionGroup, ChainedAction, MenuAction, ProcessAction
|
||||
from falyx.menu import MenuOption, MenuOptionMap
|
||||
|
||||
|
||||
# Basic coroutine for Action
|
||||
async def greet_user():
|
||||
print("👋 Hello from a regular Action!")
|
||||
await asyncio.sleep(0.5)
|
||||
return "Greeted user."
|
||||
|
||||
|
||||
# Chain of tasks
|
||||
async def fetch_data():
|
||||
print("📡 Fetching data...")
|
||||
await asyncio.sleep(1)
|
||||
return "data123"
|
||||
|
||||
|
||||
async def process_data(last_result):
|
||||
print(f"⚙️ Processing: {last_result}")
|
||||
await asyncio.sleep(1)
|
||||
return f"processed({last_result})"
|
||||
|
||||
|
||||
async def save_data(last_result):
|
||||
print(f"💾 Saving: {last_result}")
|
||||
await asyncio.sleep(1)
|
||||
return f"saved({last_result})"
|
||||
|
||||
|
||||
# Parallel tasks
|
||||
async def fetch_users():
|
||||
print("👥 Fetching users...")
|
||||
await asyncio.sleep(1)
|
||||
return ["alice", "bob", "carol"]
|
||||
|
||||
|
||||
async def fetch_logs():
|
||||
print("📝 Fetching logs...")
|
||||
await asyncio.sleep(2)
|
||||
return ["log1", "log2"]
|
||||
|
||||
|
||||
# CPU-bound task (simulate via blocking sleep)
|
||||
def heavy_computation():
|
||||
print("🧠 Starting heavy computation...")
|
||||
time.sleep(3)
|
||||
print("✅ Finished computation.")
|
||||
return 42
|
||||
|
||||
|
||||
# Define actions
|
||||
|
||||
basic_action = Action("greet", greet_user)
|
||||
|
||||
chained = ChainedAction(
|
||||
name="data-pipeline",
|
||||
actions=[
|
||||
Action("fetch", fetch_data),
|
||||
Action("process", process_data, inject_last_result=True),
|
||||
Action("save", save_data, inject_last_result=True),
|
||||
],
|
||||
auto_inject=True,
|
||||
)
|
||||
|
||||
parallel = ActionGroup(
|
||||
name="parallel-fetch",
|
||||
actions=[
|
||||
Action("fetch-users", fetch_users),
|
||||
Action("fetch-logs", fetch_logs),
|
||||
],
|
||||
)
|
||||
|
||||
process = ProcessAction(name="compute", action=heavy_computation)
|
||||
|
||||
|
||||
# Menu setup
|
||||
|
||||
menu = MenuAction(
|
||||
name="main-menu",
|
||||
title="Choose a task to run",
|
||||
menu_options=MenuOptionMap(
|
||||
{
|
||||
"1": MenuOption("Run basic Action", basic_action),
|
||||
"2": MenuOption("Run ChainedAction", chained),
|
||||
"3": MenuOption("Run ActionGroup (parallel)", parallel),
|
||||
"4": MenuOption("Run ProcessAction (heavy task)", process),
|
||||
}
|
||||
),
|
||||
)
|
||||
|
||||
flx = Falyx(
|
||||
title="🚀 Falyx Menu Demo",
|
||||
welcome_message="Welcome to the Menu Demo!",
|
||||
exit_message="Goodbye!",
|
||||
columns=2,
|
||||
never_prompt=False,
|
||||
)
|
||||
|
||||
flx.add_command(
|
||||
key="M",
|
||||
description="Show Menu",
|
||||
action=menu,
|
||||
logging_hooks=True,
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(flx.run())
|
78
examples/pipeline_demo.py
Normal file
78
examples/pipeline_demo.py
Normal file
@ -0,0 +1,78 @@
|
||||
import asyncio
|
||||
|
||||
from falyx import Action, ActionGroup, ChainedAction
|
||||
from falyx import ExecutionRegistry as er
|
||||
from falyx import ProcessAction
|
||||
from falyx.hook_manager import HookType
|
||||
from falyx.retry import RetryHandler, RetryPolicy
|
||||
|
||||
|
||||
# Step 1: Fast I/O-bound setup (standard Action)
|
||||
async def checkout_code():
|
||||
print("📥 Checking out code...")
|
||||
await asyncio.sleep(0.5)
|
||||
|
||||
|
||||
# Step 2: CPU-bound task (ProcessAction)
|
||||
def run_static_analysis():
|
||||
print("🧠 Running static analysis (CPU-bound)...")
|
||||
total = 0
|
||||
for i in range(10_000_000):
|
||||
total += i % 3
|
||||
return total
|
||||
|
||||
|
||||
# Step 3: Simulated flaky test with retry
|
||||
async def flaky_tests():
|
||||
import random
|
||||
|
||||
await asyncio.sleep(0.3)
|
||||
if random.random() < 0.3:
|
||||
raise RuntimeError("❌ Random test failure!")
|
||||
print("🧪 Tests passed.")
|
||||
return "ok"
|
||||
|
||||
|
||||
# Step 4: Multiple deploy targets (parallel ActionGroup)
|
||||
async def deploy_to(target: str):
|
||||
print(f"🚀 Deploying to {target}...")
|
||||
await asyncio.sleep(0.2)
|
||||
return f"{target} complete"
|
||||
|
||||
|
||||
def build_pipeline():
|
||||
retry_handler = RetryHandler(RetryPolicy(max_retries=3, delay=0.5))
|
||||
|
||||
# Base actions
|
||||
checkout = Action("Checkout", checkout_code)
|
||||
analysis = ProcessAction("Static Analysis", run_static_analysis)
|
||||
tests = Action("Run Tests", flaky_tests)
|
||||
tests.hooks.register(HookType.ON_ERROR, retry_handler.retry_on_error)
|
||||
|
||||
# Parallel deploys
|
||||
deploy_group = ActionGroup(
|
||||
"Deploy to All",
|
||||
[
|
||||
Action("Deploy US", deploy_to, args=("us-west",)),
|
||||
Action("Deploy EU", deploy_to, args=("eu-central",)),
|
||||
Action("Deploy Asia", deploy_to, args=("asia-east",)),
|
||||
],
|
||||
)
|
||||
|
||||
# Full pipeline
|
||||
return ChainedAction("CI/CD Pipeline", [checkout, analysis, tests, deploy_group])
|
||||
|
||||
|
||||
pipeline = build_pipeline()
|
||||
|
||||
|
||||
# Run the pipeline
|
||||
async def main():
|
||||
pipeline = build_pipeline()
|
||||
await pipeline()
|
||||
er.summary()
|
||||
await pipeline.preview()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
@ -1,7 +1,7 @@
|
||||
from rich.console import Console
|
||||
|
||||
from falyx import Falyx, ProcessAction
|
||||
from falyx.themes.colors import NordColors as nc
|
||||
from falyx.themes import NordColors as nc
|
||||
|
||||
console = Console()
|
||||
falyx = Falyx(title="🚀 Process Pool Demo")
|
||||
|
22
examples/selection_demo.py
Normal file
22
examples/selection_demo.py
Normal file
@ -0,0 +1,22 @@
|
||||
import asyncio
|
||||
|
||||
from falyx.selection import (
|
||||
SelectionOption,
|
||||
prompt_for_selection,
|
||||
render_selection_dict_table,
|
||||
)
|
||||
|
||||
menu = {
|
||||
"A": SelectionOption("Run diagnostics", lambda: print("Running diagnostics...")),
|
||||
"B": SelectionOption("Deploy to staging", lambda: print("Deploying...")),
|
||||
}
|
||||
|
||||
table = render_selection_dict_table(
|
||||
title="Main Menu",
|
||||
selections=menu,
|
||||
)
|
||||
|
||||
key = asyncio.run(prompt_for_selection(menu.keys(), table))
|
||||
print(f"You selected: {key}")
|
||||
|
||||
menu[key.upper()].value()
|
90
examples/shell_example.py
Executable file
90
examples/shell_example.py
Executable file
@ -0,0 +1,90 @@
|
||||
#!/usr/bin/env python
|
||||
import asyncio
|
||||
|
||||
from falyx import Action, ChainedAction, Falyx
|
||||
from falyx.action import ShellAction
|
||||
from falyx.hook_manager import HookType
|
||||
from falyx.hooks import ResultReporter
|
||||
from falyx.utils import setup_logging
|
||||
|
||||
# Setup logging
|
||||
setup_logging()
|
||||
|
||||
|
||||
fx = Falyx("🚀 Falyx Demo")
|
||||
|
||||
e = ShellAction("Shell", "echo Hello, {}!")
|
||||
|
||||
fx.add_command(
|
||||
key="R",
|
||||
description="Echo a message",
|
||||
action=e,
|
||||
)
|
||||
|
||||
s = ShellAction("Ping", "ping -c 1 {}")
|
||||
|
||||
fx.add_command(
|
||||
key="P",
|
||||
description="Ping a host",
|
||||
action=s,
|
||||
)
|
||||
|
||||
|
||||
async def a1(last_result):
|
||||
return f"Hello, {last_result}"
|
||||
|
||||
|
||||
async def a2(last_result):
|
||||
return f"World! {last_result}"
|
||||
|
||||
|
||||
reporter = ResultReporter()
|
||||
|
||||
a1 = Action("a1", a1, inject_last_result=True)
|
||||
a1.hooks.register(
|
||||
HookType.ON_SUCCESS,
|
||||
reporter.report,
|
||||
)
|
||||
a2 = Action("a2", a2, inject_last_result=True)
|
||||
a2.hooks.register(
|
||||
HookType.ON_SUCCESS,
|
||||
reporter.report,
|
||||
)
|
||||
|
||||
|
||||
async def normal():
|
||||
print("Normal")
|
||||
return "Normal"
|
||||
|
||||
|
||||
async def annotate(last_result):
|
||||
return f"Annotated: {last_result}"
|
||||
|
||||
|
||||
async def whisper(last_result):
|
||||
return last_result.lower()
|
||||
|
||||
|
||||
c1 = ChainedAction(
|
||||
name="ShellDemo",
|
||||
actions=[
|
||||
# host,
|
||||
ShellAction("Ping", "ping -c 1 {}"),
|
||||
Action("Annotate", annotate),
|
||||
Action("Whisper", whisper),
|
||||
],
|
||||
auto_inject=True,
|
||||
)
|
||||
|
||||
fx.add_command(
|
||||
key="C",
|
||||
description="Run a chain of actions",
|
||||
action=c1,
|
||||
)
|
||||
|
||||
|
||||
async def main():
|
||||
await fx.run()
|
||||
|
||||
|
||||
asyncio.run(main())
|
52
examples/submenu.py
Normal file
52
examples/submenu.py
Normal file
@ -0,0 +1,52 @@
|
||||
import asyncio
|
||||
import random
|
||||
|
||||
from falyx import Action, ChainedAction, Falyx
|
||||
from falyx.utils import setup_logging
|
||||
|
||||
setup_logging()
|
||||
|
||||
|
||||
# A flaky async step that fails randomly
|
||||
async def flaky_step():
|
||||
await asyncio.sleep(0.2)
|
||||
if random.random() < 0.5:
|
||||
raise RuntimeError("Random failure!")
|
||||
return "ok"
|
||||
|
||||
|
||||
step1 = Action(name="step_1", action=flaky_step, retry=True)
|
||||
step2 = Action(name="step_2", action=flaky_step, retry=True)
|
||||
|
||||
# Chain the actions
|
||||
chain = ChainedAction(name="my_pipeline", actions=[step1, step2])
|
||||
|
||||
# Create the CLI menu
|
||||
falyx = Falyx("🚀 Falyx Demo")
|
||||
falyx.add_command(
|
||||
key="R",
|
||||
description="Run My Pipeline",
|
||||
action=chain,
|
||||
logging_hooks=True,
|
||||
preview_before_confirm=True,
|
||||
confirm=True,
|
||||
)
|
||||
|
||||
# Create a submenu
|
||||
submenu = Falyx("Submenu")
|
||||
submenu.add_command(
|
||||
key="T",
|
||||
description="Test",
|
||||
action=lambda: "test",
|
||||
logging_hooks=True,
|
||||
preview_before_confirm=True,
|
||||
confirm=True,
|
||||
)
|
||||
falyx.add_submenu(
|
||||
key="S",
|
||||
description="Submenu",
|
||||
submenu=submenu,
|
||||
)
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(falyx.run())
|
Reference in New Issue
Block a user