Beautiful terminal spinners in Python
—
Configure spinner appearance including colors, text formatting, placement options, and text animations. All properties can be modified dynamically while the spinner is running.
Control the text displayed alongside the spinner with dynamic updates and color formatting.
@property
def text(self):
"""
Get the current spinner text.
Returns:
- str: Current text value
"""
@text.setter
def text(self, text):
"""
Set spinner text with automatic animation handling for long strings.
Parameters:
- text (str): New text to display
"""
@property
def text_color(self):
"""
Get the current text color.
Returns:
- str: Current text color or None
"""
@text_color.setter
def text_color(self, text_color):
"""
Set the text color.
Parameters:
- text_color (str): Color name - "red", "green", "blue", "cyan", "magenta", "yellow", "white", "grey"
"""Usage Example:
from halo import Halo
import time
spinner = Halo(text='Starting process', text_color='blue')
spinner.start()
# Update text dynamically
spinner.text = 'Loading data'
time.sleep(1)
spinner.text = 'Processing results'
spinner.text_color = 'green'
time.sleep(1)
spinner.stop()Customize the spinner animation and color with support for built-in spinner types and custom definitions.
@property
def spinner(self):
"""
Get current spinner configuration.
Returns:
- dict: Spinner definition with 'frames' and 'interval' keys
"""
@spinner.setter
def spinner(self, spinner):
"""
Set spinner type or custom spinner definition.
Parameters:
- spinner (str|dict): Spinner name or custom definition
- str: Built-in spinner name (e.g., "dots", "line", "star", "arrow")
- dict: Custom spinner with 'frames' (list) and 'interval' (int) keys
"""
@property
def color(self):
"""
Get current spinner color.
Returns:
- str: Current spinner color
"""
@color.setter
def color(self, color):
"""
Set spinner color.
Parameters:
- color (str): Color name - "cyan", "red", "green", "yellow", "blue", "magenta", "white", "grey"
"""Usage Example:
from halo import Halo
import time
# Built-in spinner types
spinner = Halo(text='Loading', spinner='dots', color='cyan')
spinner.start()
time.sleep(1)
# Change to different built-in spinner
spinner.spinner = 'star'
spinner.color = 'green'
time.sleep(1)
# Custom spinner definition
custom_spinner = {
'frames': ['◐', '◓', '◑', '◒'],
'interval': 100
}
spinner.spinner = custom_spinner
spinner.color = 'red'
time.sleep(2)
spinner.stop()Control where the spinner appears relative to the text and how the overall layout is arranged.
@property
def placement(self):
"""
Get current spinner placement.
Returns:
- str: Current placement ("left" or "right")
"""
@placement.setter
def placement(self, placement):
"""
Set spinner placement relative to text.
Parameters:
- placement (str): Position - "left" or "right"
Raises:
- ValueError: If placement is not "left" or "right"
"""Usage Example:
from halo import Halo
import time
# Left placement (default)
spinner = Halo(text='Loading data', placement='left')
spinner.start()
time.sleep(1)
# Switch to right placement
spinner.placement = 'right'
time.sleep(1)
spinner.stop()Handle long text with scrolling animations when text exceeds terminal width.
@property
def animation(self):
"""
Get current text animation type.
Returns:
- str: Current animation type or None
"""
@animation.setter
def animation(self, animation):
"""
Set text animation for long strings.
Parameters:
- animation (str): Animation type - "bounce", "marquee", or None
- "bounce": Text bounces back and forth within terminal width
- "marquee": Text scrolls continuously like a marquee
- None: Long text truncated with ellipsis
"""Usage Example:
from halo import Halo
import time
# Long text with marquee animation
long_text = "This is a very long text that exceeds terminal width and will scroll"
spinner = Halo(text=long_text, animation='marquee', spinner='dots')
spinner.start()
time.sleep(3)
# Switch to bounce animation
spinner.animation = 'bounce'
time.sleep(3)
# Disable animation (truncate with ellipsis)
spinner.animation = None
time.sleep(1)
spinner.stop()Common spinner types available (from the spinners package):
# Fast spinners
"dots" # ⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏
"line" # |/-\
"arrow" # ←↖↑↗→↘↓↙
# Animated spinners
"star" # ✶✸✹✺✹✷
"bouncingBar" # [ ] [= ] [== ] [=== ] [====]
"bouncingBall" # ( ● ) ( ● ) ( ● ) ( ● )
# Decorative spinners
"hearts" # 💛💙💜💚❤️
"moon" # 🌑🌒🌓🌔🌕🌖🌗🌘
"earth" # 🌍🌎🌏# Define custom spinner
custom_spinner = {
'frames': ['⚫', '⚪', '⚫', '⚪'], # Animation frames
'interval': 200 # Milliseconds between frames
}
spinner = Halo(
text='Custom animation',
spinner=custom_spinner,
color='magenta'
)
with spinner:
time.sleep(3)from halo import Halo
import time
import random
spinner = Halo(text='Dynamic demo', spinner='dots')
spinner.start()
colors = ['red', 'green', 'blue', 'cyan', 'magenta', 'yellow']
spinners = ['dots', 'line', 'star', 'arrow']
for i in range(10):
# Randomly change appearance
spinner.color = random.choice(colors)
spinner.spinner = random.choice(spinners)
spinner.text = f'Random style {i+1}'
time.sleep(0.5)
spinner.stop()Install with Tessl CLI
npx tessl i tessl/pypi-halo