From 02459d572de16cf5c8cf4a97c436bc3d502c87a0 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Tue, 31 Mar 2026 05:40:08 +0000 Subject: [PATCH] =?UTF-8?q?=F0=9F=8E=A8=20Palette:=20Enhance=20CLI=20outpu?= =?UTF-8?q?t=20with=20summary=20tables=20and=20visual=20polish?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Replaces simple success messages with rich.table.Table for better results summary. - Improves customer ID formatting to use zero-padding (e.g., customer-01) for better alignment and sorting. - Adds brief pauses to demo tasks to make terminal status spinners and logs more perceptible. - Updates Prefect mapping logic to collect results explicitly before rendering the summary table. - Ensures consistency between 01_getting_started.py and 02_logging.py. Co-authored-by: ruh-al-tarikh <203426218+ruh-al-tarikh@users.noreply.github.com> --- .Jules/palette.md | 4 ++++ 01_getting_started.py | 33 ++++++++++++++++++++++++++++----- 02_logging.py | 32 +++++++++++++++++++++++++++----- 3 files changed, 59 insertions(+), 10 deletions(-) diff --git a/.Jules/palette.md b/.Jules/palette.md index 2677c36..fcb1212 100644 --- a/.Jules/palette.md +++ b/.Jules/palette.md @@ -9,3 +9,7 @@ ## 2026-03-30 - [Demo Scale vs. Terminal Readability] **Learning:** For demo scripts, larger data sets can degrade the UX by flooding the terminal with logs, making it harder for users to see the structure of the output. **Action:** Limit the default number of items in demo loops (e.g., 5 items) to maintain a high signal-to-noise ratio while still demonstrating the functionality. + +## 2026-03-31 - [Visual Polish for CLI Summaries] +**Learning:** In CLI-based workflow scaffolds, replacing raw success messages with structured `rich.table.Table` summaries significantly improves the professional feel and readability of the output. Additionally, zero-padding generated IDs (e.g., 'customer-01') ensures natural sorting and vertical alignment, which reduces cognitive load when scanning lists. Finally, adding minimal artificial delays (e.g., `time.sleep(0.1)`) in demo scripts makes the "work" visible by giving terminal spinners and status indicators enough time to register with the user. +**Action:** Use structured tables for final execution summaries, ensure all generated IDs are zero-padded for alignment, and include brief pacing pauses in demo tasks to make the execution flow more perceptible. diff --git a/01_getting_started.py b/01_getting_started.py index 4669797..790b646 100644 --- a/01_getting_started.py +++ b/01_getting_started.py @@ -1,21 +1,27 @@ from prefect import flow, task import random +import time from rich.console import Console from rich.panel import Panel from rich.rule import Rule +from rich.table import Table console = Console() @task def get_customer_ids() -> list[str]: - # Fetch customer IDs from a database or API - return [f"customer{n}" for n in random.choices(range(100), k=5)] + """Fetch customer IDs from a database or API.""" + # Use sorted and zero-padded IDs for better terminal alignment + ids = [f"customer-{n:02d}" for n in random.choices(range(100), k=5)] + return sorted(ids) @task def process_customer(customer_id: str) -> str: - # Process a single customer + """Process a single customer.""" + # Add a brief pause to make the processing state visible in the UI + time.sleep(0.1) return f"Processed {customer_id}" @@ -23,19 +29,36 @@ def process_customer(customer_id: str) -> str: def main(): """ ### 🚀 Getting Started with Prefect + This flow demonstrates how to map a task over a list of inputs. It fetches a list of customer IDs and processes each one individually. """ with console.status("[bold green]Fetching customer data..."): customer_ids = get_customer_ids() - # Map the process_customer task across all customer IDs console.print(f"[bold blue]📦 Fetched {len(customer_ids)} customer IDs[/bold blue]") with console.status("[bold green]Processing customers..."): - results = process_customer.map(customer_ids) + futures = process_customer.map(customer_ids) + # Explicitly wait for results to avoid AttributeErrors on futures + results = [f.result() for f in futures] + + # Display results in a clean table for better readability + table = Table( + title="Processing Summary", show_header=True, header_style="bold blue" + ) + table.add_column("Customer ID", style="cyan") + table.add_column("Status", style="green") + for res in results: + # Extract the customer ID from the result string (e.g., "Processed customer-01") + customer_id = res.split()[-1] + table.add_row(customer_id, "✅ Success") + + console.print() + console.print(table) console.print() + console.print( Panel.fit( f"[bold green]✅ Successfully processed {len(results)} customers![/bold green]", diff --git a/02_logging.py b/02_logging.py index f225f64..5eaf0c0 100644 --- a/02_logging.py +++ b/02_logging.py @@ -1,24 +1,30 @@ from prefect import flow, task from prefect.logging import get_run_logger import random +import time from rich.console import Console from rich.panel import Panel from rich.rule import Rule +from rich.table import Table console = Console() @task def get_customer_ids() -> list[str]: - # Fetch customer IDs from a database or API - return [f"customer{n}" for n in random.choices(range(100), k=5)] + """Fetch customer IDs from a database or API.""" + # Use sorted and zero-padded IDs for better terminal alignment + ids = [f"customer-{n:02d}" for n in random.choices(range(100), k=5)] + return sorted(ids) @task def process_customer(customer_id: str) -> str: - # Process a single customer + """Process a single customer.""" logger = get_run_logger() for _ in range(3): + # Add a brief pause to make the logging visible and realistic + time.sleep(0.05) logger.info(f"Processing customer {customer_id}") return f"Processed {customer_id}" @@ -39,13 +45,29 @@ def main(): with console.status("[bold green]Fetching customer data..."): customer_ids = get_customer_ids() - # Map the process_customer task across all customer IDs console.print(f"[bold blue]📦 Fetched {len(customer_ids)} customer IDs[/bold blue]") with console.status("[bold green]Processing customers with logging..."): - results = process_customer.map(customer_ids) + futures = process_customer.map(customer_ids) + # Explicitly wait for results to avoid AttributeErrors on futures + results = [f.result() for f in futures] + + # Display results in a clean table for better readability + table = Table( + title="Processing Summary", show_header=True, header_style="bold blue" + ) + table.add_column("Customer ID", style="cyan") + table.add_column("Status", style="green") + + for res in results: + # Extract the customer ID from the result string (e.g., "Processed customer-01") + customer_id = res.split()[-1] + table.add_row(customer_id, "✅ Success") console.print() + console.print(table) + console.print() + console.print( Panel.fit( f"[bold green]✅ Successfully processed {len(results)} customers with detailed logging![/bold green]",