Skip to main content

Beautiful multi-step terminal progress widget for Rich. Connected indicators, per-step logging, elapsed timers, and optional progress bars.

Project description

rich-stepper

PyPI version Python versions License: MIT

Beautiful multi-step terminal progress widget for Rich. Connected indicators, per-step logging, elapsed timers, and optional progress bars — all rendered live in your terminal.

Installation

pip install rich-stepper

Requires Python 3.10+ and Rich 13+.

Quick Start

from rich.console import Console
from stepper import StepDefinition, StepStatus, Stepper

steps = [
    StepDefinition("Clone repository", StepStatus.COMPLETED),
    StepDefinition("Install dependencies", StepStatus.ACTIVE),
    StepDefinition("Run tests", StepStatus.PENDING),
    StepDefinition("Deploy", StepStatus.PENDING),
]

stepper = Stepper(steps=steps)
Console().print(stepper)

Renders a connected vertical stepper with status indicators:

● Clone repository
│
◉ Install dependencies
│
○ Run tests
│
○ Deploy

Live Updates

Use the context manager for animated step progression:

import time
from stepper import StepDefinition, StepStatus, Stepper

steps = [
    StepDefinition("Connecting", StepStatus.ACTIVE),
    StepDefinition("Downloading", StepStatus.PENDING),
    StepDefinition("Installing", StepStatus.PENDING),
    StepDefinition("Done", StepStatus.PENDING),
]

stepper = Stepper(steps=steps)
with stepper:
    for i in range(len(steps)):
        time.sleep(0.5)
        if i > 0:
            stepper.set_step_status(i, StepStatus.ACTIVE)
        time.sleep(0.5)
        stepper.set_step_status(i, StepStatus.COMPLETED)

Per-Step Logging

Append log messages to any step with stepper.log():

from rich.console import Console
from stepper import StepDefinition, StepStatus, Stepper, StepperTheme

theme = StepperTheme(max_log_rows=3, log_style="dim italic", log_prefix="›")

stepper = Stepper(
    steps=[
        StepDefinition("Fetch schema", StepStatus.COMPLETED, step_description="200 OK"),
        StepDefinition("Migrate database", StepStatus.ACTIVE, step_description="Applying patches…"),
        StepDefinition("Seed data", StepStatus.PENDING),
    ],
    theme=theme,
    console=Console(),
    auto_refresh=False,
)

stepper.log(0, "Connected to postgres://db:5432")
stepper.log(0, "Fetched 42 table definitions")
stepper.log(1, "Applying 001_create_users.sql")
stepper.log(1, "Applying 002_add_indexes.sql")
stepper.log(1, "Applying 003_seed_config.sql")
stepper.log(1, "Applying 004_migrate_orders.sql")  # oldest dropped (max_log_rows=3)

Console().print(stepper)

Logs render inline below (or above) each step label. Set max_log_rows to cap visible lines, or leave it None for terminal-height-aware truncation.

Log position

Control where logs appear relative to the step label:

from stepper import LogPosition, StepperTheme

theme = StepperTheme(log_position=LogPosition.ABOVE)  # logs above the label

Progress Bars

Enable per-step progress bars with show_bar=True:

theme = StepperTheme(show_bar=True, bar_width=20)
stepper = Stepper(steps=steps, theme=theme, console=Console(), auto_refresh=False)
stepper.set_step_progress(1, 0.6)  # 60% complete
Console().print(stepper)

The percent argument is clamped to [0.0, 1.0].

Elapsed Time

Show elapsed time per step:

theme = StepperTheme(show_elapsed_time=True)

Completed and active steps show elapsed time. Pending steps display -:--:--. Time freezes when a step is marked completed.

Dynamic Steps

Add steps at runtime inside a context manager:

with Stepper(theme=theme, console=console) as stepper:
    for url, label in sites:
        idx = stepper.add_step(label, status=StepStatus.ACTIVE, step_description=url)
        stepper.log(idx, f"Fetching {url}")
        # ... do work ...
        stepper.set_step_status(idx, StepStatus.COMPLETED)

Theming

StepperTheme is a frozen dataclass — set any combination of fields at construction:

Symbols and styles

theme = StepperTheme(
    completed_symbol="✓",
    active_symbol="◎",
    pending_symbol="○",
    completed_style="green bold",
    active_style="magenta bold",
    pending_style="bright_black",
)

Connectors

theme = StepperTheme(
    connector_symbol="│",
    connector_style="bright_black",
    line_thickness=2,    # repeat connector symbol N times
    step_gap=1,          # blank lines between steps
)

Label formatting

theme = StepperTheme(
    label_style="",
    step_description_style="dim",
    label_padding=2,     # spaces before label text
)

Progress bar styling

theme = StepperTheme(
    show_bar=True,
    bar_width=20,
    bar_complete_style="bar.complete",
    bar_finished_style="bar.finished",
    bar_pulse_style="bar.pulse",
)

Log styling

from stepper import LogPosition

theme = StepperTheme(
    log_position=LogPosition.BELOW,  # or LogPosition.ABOVE
    max_log_rows=5,                  # None for terminal-aware
    log_style="dim italic",
    log_prefix="›",
)

Time column

theme = StepperTheme(
    show_elapsed_time=True,
    time_style="progress.elapsed",
)

API Reference

Stepper

Extends rich.progress.Progress. All Progress constructor args are forwarded.

Method Description
Stepper(steps, theme, console, ...) Create stepper with optional initial steps and theme
add_step(label, status, step_description) Add a step, returns TaskID
add_steps(steps) Add multiple steps from StepDefinition list
set_step_status(index, status) Update step status
set_step_progress(index, percent) Set progress bar (0.0–1.0)
log(index, message) Append a log message to a step

StepStatus

Value Description
StepStatus.PENDING Not yet started
StepStatus.ACTIVE Currently running
StepStatus.COMPLETED Finished

LogPosition

Value Description
LogPosition.BELOW Logs render below the step label (default)
LogPosition.ABOVE Logs render above the step label

StepDefinition

StepDefinition(label, status=StepStatus.PENDING, step_description=None)

StepperTheme

All fields have sensible defaults. Override any combination:

Field Type Default
completed_symbol str "●"
active_symbol str "◉"
pending_symbol str "○"
completed_style str "green"
active_style str "cyan bold"
pending_style str "bright_black"
connector_symbol str "│"
connector_style str "bright_black"
line_thickness int 1
step_gap int 0
label_style str ""
step_description_style str "dim"
label_padding int 1
show_elapsed_time bool False
time_style str "progress.elapsed"
show_bar bool False
bar_width int | None 20
bar_complete_style str "bar.complete"
bar_finished_style str "bar.finished"
bar_pulse_style str "bar.pulse"
log_position LogPosition LogPosition.BELOW
max_log_rows int | None None
log_style str "dim italic"
log_prefix str "›"

Examples

The examples/ directory contains 17 runnable scripts covering every feature:

Example Description
01_basic Default theme with mixed statuses
02_custom_colors Custom symbol and style colors
03_emoji_symbols Emoji-based step indicators
04_thick_connectors Multi-line connector glyphs
05_step_gap Blank lines between steps
06_all_completed All steps in completed state
07_in_progress Partially completed workflow
08_minimal_theme Stripped-down minimal appearance
09_dense_layout Compact layout with descriptions
10_many_steps Handling 10+ steps
11_single_step Single-step edge case
12_live_update Animated context manager usage
13_elapsed_time Elapsed time column
14_progress_bar Per-step progress bars
15_step_logging Inline log messages
16_full_featured Everything combined
17_web_scraper Real-world web scraper demo

Run any example directly:

python examples/16_full_featured.py

How It Works

Stepper extends Rich's Progress class with custom columns:

  • StepIndicatorColumn — renders status symbols and vertical connectors
  • StepLabelColumn — renders labels, descriptions, and inline logs
  • StepperTimeColumn — renders elapsed/frozen time per step

Status mapping and log rendering are handled by shared StatusMapper and LogRenderer helpers for consistency across columns.

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

rich_stepper-0.1.2.tar.gz (32.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

rich_stepper-0.1.2-py3-none-any.whl (9.8 kB view details)

Uploaded Python 3

File details

Details for the file rich_stepper-0.1.2.tar.gz.

File metadata

  • Download URL: rich_stepper-0.1.2.tar.gz
  • Upload date:
  • Size: 32.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for rich_stepper-0.1.2.tar.gz
Algorithm Hash digest
SHA256 c3b0ef56f0debdbbc53688a53e86434b47434d6624594024af5f7f891e6e8597
MD5 9677ca8192072269c5fce5fcd36b60f5
BLAKE2b-256 4e4a9cb3b8829927da4f49120858974932c6e9f2f2cf8bac30e79043ef407901

See more details on using hashes here.

Provenance

The following attestation bundles were made for rich_stepper-0.1.2.tar.gz:

Publisher: publish.yml on abbazs/rich-stepper

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rich_stepper-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: rich_stepper-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 9.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for rich_stepper-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 980c4038a7c93053a57a720477996a93f991ef2fa03fccd5687f7cd7c39bf541
MD5 377b58e3a8e2527aad620fd75576b6ec
BLAKE2b-256 23e3ea3cc044b86b0aad429220dc47952a5a4ad314497b91817455e2be4956fe

See more details on using hashes here.

Provenance

The following attestation bundles were made for rich_stepper-0.1.2-py3-none-any.whl:

Publisher: publish.yml on abbazs/rich-stepper

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page