Skip to content

Instantly share code, notes, and snippets.

@paulgessinger
Created February 5, 2025 12:34
Show Gist options
  • Save paulgessinger/b56ad2d87efad42bdfef99a5d6045952 to your computer and use it in GitHub Desktop.
Save paulgessinger/b56ad2d87efad42bdfef99a5d6045952 to your computer and use it in GitHub Desktop.
Python script to run a process a number of times and report status
#!/usr/bin/env python3
# /// script
# dependencies = [
# "rich",
# "typer",
# ]
# ///
import rich
import typer
from rich.progress import Progress, SpinnerColumn, ProgressColumn,Task
from rich.panel import Panel
from rich.console import Group
from rich.rule import Rule
import subprocess
app = typer.Typer()
class ProgressWithRule(Progress):
def get_renderables(self):
yield Group(
Rule(title="Status"),
self.make_tasks_table(self.tasks)
)
class ProcessColumn(ProgressColumn):
successes: int
failed: int
@property
def percent(self):
total = self.successes + self.failed
if total == 0:
return "---%"
return f"{self.failed / total * 100:>3.0f}%"
def __init__(self, *args, **kwargs):
self.successes = 0
self.failed = 0
super().__init__(*args, **kwargs)
def render(self, task: Task) -> str:
return f"successes: {self.successes}, failures: {self.failed} -> {self.percent}"
@app.command()
def run(cmd: str, num_runs: int = 10):
column = ProcessColumn()
with ProgressWithRule(SpinnerColumn(), *Progress.get_default_columns(), column, transient=True) as progress:
task = progress.add_task("Running...", total=num_runs)
for i in range(num_runs):
proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
assert proc.stdout is not None
while line := proc.stdout.readline() or proc.poll() is None:
if isinstance(line, bytes):
line = line.decode("utf-8")
progress.console.print(line, end="", highlight=False, markup=False, emoji=False)
progress.advance(task)
if proc.returncode != 0:
column.failed += 1
else:
column.successes += 1
rich.print(
Panel(
f"""
Success: {num_runs - column.failed}
Failure: {column.failed}
""".strip()
, title="Summary"
)
)
raise typer.Exit(code=1 if column.failed > 0 else 0)
app()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment