A highly configurable progress indicator library for Python with Rich and Textual support
Project description
ThothSpinner
A highly configurable progress indicator library for Python, built on Rich. ThothSpinner provides beautiful, composable terminal UI components including spinners, progress bars, timers, and animated messages with shimmer effects.
Demo
โจ Features
- ๐จ Modular Components: Mix and match spinner, progress, timer, message, and hint components
- ๐ State Management: Built-in success/error states with automatic transitions
- โจ Shimmer Effects: Eye-catching animation effects for messages
- ๐ฏ Thread-Safe: Proper locking for concurrent operations
- ๐ Performance Optimized: Efficient rendering with minimal CPU usage
- ๐ญ Rich Integration: Seamless integration with Rich Console and Live displays
- ๐บ Textual Support: Native Textual widgets with reactive state management
๐ Documentation
- Rich API Reference - Complete API documentation for Rich components
- Textual API Reference - Textual widget documentation
- Examples Gallery - Runnable Rich examples
- Textual Examples - Textual application examples
- Rich to Textual Guide - Migration guide
- Troubleshooting Guide - Solutions to common issues
- Release Guide - Build, publish, and CI/CD architecture
- First-Time Publish Guide - Step-by-step v1.0.0 PyPI publish walkthrough
๐ Quick Start
Setup
# Install from PyPI
pip install thothspinner
# or with uv (recommended)
uv add thothspinner
Explore Spinner Styles
# Preview all 48 spinner styles in the terminal
thothspinner preview
# Preview a specific style
thothspinner preview npm_dots
# Open interactive TUI style browser
thothspinner browse
Basic Usage
from thothspinner import ThothSpinner
from rich.console import Console
from rich.live import Live
import time
console = Console()
# Simple usage with all components
with Live(ThothSpinner(), console=console) as live:
spinner = live.renderable
spinner.start()
# Simulate work with progress
for i in range(100):
spinner.update_progress(current=i, total=100)
time.sleep(0.05)
spinner.success("Task completed!")
Textual Quick Start
from textual.app import App, ComposeResult
from thothspinner.textual import TextualThothSpinner
import asyncio
class MyApp(App):
def compose(self) -> ComposeResult:
yield TextualThothSpinner(
spinner_style="npm_dots",
message_text="Processing data",
message_shimmer=True,
)
async def on_mount(self) -> None:
spinner = self.query_one(TextualThothSpinner)
spinner.start()
await asyncio.sleep(2)
spinner.success("Done!")
MyApp().run()
Run the Examples
# Run all examples (Rich + Textual)
just examples
# Or run by category
just examples-thothspinner # Rich ThothSpinner examples
just examples-textual # Textual widget examples
# Or run individual examples
just example-thothspinner-basic
just example-thothspinner-full
just example-progress
just example-timer
just example-message
just example-message-shimmer
๐ฆ Installation
Prerequisites
Install from Source
# Clone the repository
git clone https://github.com/smorin/thothspinner.git
cd thothspinner
# Install with uv (recommended)
uv sync
# Or with pip
pip install -e .
Install from PyPI
pip install thothspinner
# Or with uv (recommended)
uv add thothspinner
๐ฏ Available Components
Core Components
- SpinnerComponent: Animated spinners with multiple styles (npm_dots, claude_stars, etc.)
- ProgressComponent: Progress counters with various formats (percentage, fraction, etc.)
- TimerComponent: Elapsed time display with flexible formatting
- MessageComponent: Rotating action words with shimmer effects
- HintComponent: Static hint text for instructions
- ThothSpinner: Orchestrator that combines all components
Example Usage
from thothspinner import ThothSpinner
from thothspinner.rich.components import SpinnerComponent, ProgressComponent
# Individual components
spinner = SpinnerComponent(style="claude_stars", color="#FFA500")
progress = ProgressComponent(format={"style": "percentage"}, color="#00FF00")
# Or use the orchestrator for everything
spinner = ThothSpinner(
spinner_style="npm_dots",
message_text="Processing data", # initial rotating message text
message_shimmer=True,
progress_format="percentage",
timer_format="auto",
hint_text="(esc to cancel)"
)
set_message() updates the current rotating message text. Use
set_message_pinned() only when you explicitly want a non-rotating message.
Configuration
ThothSpinner supports both kwargs and dictionary configuration:
# Using kwargs
spinner = ThothSpinner(
spinner_style="claude_stars",
message_shimmer=True,
success_duration=2.0 # Auto-clear after 2 seconds
)
# Using configuration dictionary
config = {
"defaults": {"color": "#D97706"},
"elements": {
"spinner": {"style": "npm_dots"},
"message": {"shimmer": {"enabled": True, "width": 3}},
"progress": {"format": {"style": "percentage"}}
},
"states": {
"success": {
"spinner": {"icon": "โ", "color": "#00FF00"},
"message": {"text": "Complete!"}
}
}
}
spinner = ThothSpinner.from_dict(config)
๐ ๏ธ Development
Project Structure
thothspinner/
โโโ src/thothspinner/ # Source code
โ โโโ rich/ # Rich-based components
โ โ โโโ components/ # Individual components
โ โ โโโ thothspinner.py # Main orchestrator
โ โโโ textual/ # Textual widgets
โโโ tests/ # Test suite (97%+ coverage)
โโโ docs/ # Documentation
โ โโโ thothspinner_rich.md # Rich API reference
โ โโโ thothspinner_textual.md # Textual API reference
โ โโโ examples/ # Example scripts
โ โโโ troubleshooting.md # Troubleshooting guide
โโโ examples/ # Demo scripts
โโโ justfile # Task automation
โโโ pyproject.toml # Project configuration
Development Commands
# Format code
just format
# Lint code
just lint
# Type check
just typecheck
# Run tests with coverage
just test-cov
# Security scan (bandit)
just security
# Generate changelog (git-cliff)
just changelog
# Version management
just current-version
just bump-patch
just bump-minor
just bump-major
# Regenerate visual regression snapshots
just update-snapshots
# Run all checks (format, lint, typecheck, security, test)
just all
# Clean build artifacts
just clean
CLI Tools
# Preview all 48 spinner styles
uv run thothspinner preview
# Preview a specific style
uv run thothspinner preview npm_dots
# Open interactive TUI style browser
uv run thothspinner browse
Generating the Demo GIF
# Install GIF generation tools (macOS only, one-time)
just install-readme-animation
# Generate demo.gif
just demo-gif
# Verify it looks right
open docs/images/demo.gif
# Commit and push
git add docs/images/demo.gif
git commit -m "docs: add demo.gif for README"
git push origin main
Testing
The project maintains 97%+ test coverage, including visual regression tests via pytest-textual-snapshot:
# Run tests
just test
# Run tests with coverage report
just test-cov
# Coverage report generated at htmlcov/index.html
# Run specific test file
just test tests/rich/test_spinner.py
# Regenerate visual regression snapshots (Textual widgets)
just update-snapshots
๐ Examples
Basic Progress Bar
from thothspinner import ThothSpinner
from rich.live import Live
with Live(ThothSpinner()) as live:
spinner = live.renderable
spinner.start()
for i in range(100):
spinner.update_progress(current=i, total=100)
time.sleep(0.05)
spinner.success()
File Processing
from pathlib import Path
files = list(Path(".").glob("*.py"))
spinner = ThothSpinner(progress_format="fraction")
with Live(spinner) as live:
spinner.start()
for i, file in enumerate(files):
spinner.set_message(text=f"Processing {file.name}") # rotating message update
spinner.update_progress(current=i, total=len(files))
process_file(file)
spinner.success(f"Processed {len(files)} files")
Error Handling
with Live(ThothSpinner()) as live:
spinner = live.renderable
spinner.start()
try:
risky_operation()
spinner.success("Operation successful")
except Exception as e:
spinner.error(f"Operation failed: {e}")
More examples in the Examples Gallery.
๐บ๏ธ Roadmap
Completed Milestones
โ M01โM05: Core Rich Components (v0.1.0โv0.5.0)
- Hint, Spinner, Progress, Timer, and Message components
- ThothSpinner orchestrator with state management
- 97%+ test coverage, thread-safe operations with proper locking
โ M06: Rich Documentation (v0.6.0)
- Comprehensive API reference, examples gallery with 20+ examples, troubleshooting guide
โ M07โM13: Textual Components & Documentation (v0.7.0โv0.13.0)
- Full Textual widget set with reactive state management
- Feature parity with all Rich components
- Textual examples, integration guides, and API reference
โ M15: Progress Bar Format & Animation Smoothing (v1.1.0)
- Bar format style for Textual ProgressWidget with configurable fill characters
- Smooth animated transitions when progress values change
โ M14: Publishing to PyPI (v1.0.0)
- PyPI package publication with OIDC trusted publishing
- GitHub Actions CI/CD pipeline (test matrix, CodeQL, publish)
- Release automation with git-cliff changelog generation
Releasing
First time? Follow the First-Time Publish Guide for step-by-step OIDC setup and the v1.0.0 publish walkthrough.
For subsequent releases, see the Release Guide. Quick reference:
# 1. Bump version (pick one), then run checks and commit:
just bump-patch # or bump-minor / bump-major
just all # format, lint, typecheck, security, test โ must all pass
git add pyproject.toml
git commit -m "chore: release v1.2.3"
git push origin main
# 2. Tag and publish (auto-generates changelog, builds, tags, pushes โ triggers CI โ PyPI)
just release 1.2.3
Releases are published automatically via OIDC trusted publishing โ no API tokens required. See RELEASE.md for OIDC setup, CI/CD pipeline details, and troubleshooting.
๐ค Contributing
Contributions are welcome! See CONTRIBUTING.md for full details. Quick summary:
- Check the MILESTONES.md for current tasks
- Follow the established code patterns
- Maintain test coverage above 90%
- Use the development toolchain (just commands)
- Write tests for new features
- Update documentation as needed
For milestone-specific work, reference tasks in the milestone documents (M01.md, M02.md, etc.).
Zero-Setup with GitHub Codespaces
A .devcontainer config is included โ open in Codespaces or VS Code Dev Containers for an instant, pre-configured development environment.
๐ License
MIT License - See LICENSE file for details.
๐ Acknowledgments
- Built on the excellent Rich and Textual libraries by Will McGugan
- Inspired by various terminal UI libraries including ora, cli-spinners, and progress
- Name inspired by Thoth, ancient Egyptian deity of wisdom and writing
- Development patterns influenced by Rich's battle-tested implementation
๐ฌ Support
For issues, questions, or suggestions:
- ๐ Open an issue on GitHub
- ๐ Check the Documentation
- ๐ Review the Troubleshooting Guide
- ๐ง Contact the maintainers
Current Version: 1.0.0 | Python: 3.11+ | Coverage: 97%+ | Rich Docs | Textual Docs
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file thothspinner-1.2.5.tar.gz.
File metadata
- Download URL: thothspinner-1.2.5.tar.gz
- Upload date:
- Size: 48.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.6 {"installer":{"name":"uv","version":"0.11.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
caf05da508c366f49b00165006560a3d9276ad63d18944d8d7ae0857d543ce1a
|
|
| MD5 |
a888c2586c2b2a46354004b6af6310f6
|
|
| BLAKE2b-256 |
460b715d23e806dfa78fbe499d800c763458d0377993aaba0cd1046c4457ec4c
|
File details
Details for the file thothspinner-1.2.5-py3-none-any.whl.
File metadata
- Download URL: thothspinner-1.2.5-py3-none-any.whl
- Upload date:
- Size: 66.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.6 {"installer":{"name":"uv","version":"0.11.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
90bbbfcf003655c64bcb2573c364bd76da83d5e96f42fb7b19b5d36275ca739b
|
|
| MD5 |
958046bda249352105ccbaa56c0a75a9
|
|
| BLAKE2b-256 |
93314f26fc77295b289e52493892b0a93af214e261ae13f158bc21577b70a2fe
|