Beautiful terminal spinners in Python
—
Specialized spinner implementation for Jupyter notebooks and IPython environments using widgets. HaloNotebook provides the same API as the standard Halo class but renders using IPython display widgets instead of terminal output.
Jupyter-optimized spinner that inherits from Halo with widget-based rendering for notebook environments.
class HaloNotebook(Halo):
def __init__(
self,
text="",
color="cyan",
text_color=None,
spinner=None,
placement="left",
animation=None,
interval=-1,
enabled=True,
stream=sys.stdout
):
"""
Initialize a Jupyter notebook-compatible spinner.
Parameters: Same as Halo.__init__
- text (str): Text to display alongside spinner (default: "")
- color (str): Spinner color (default: "cyan")
- text_color (str): Text color (default: None)
- spinner (str|dict): Spinner type or custom definition (default: "dots")
- placement (str): Spinner position - "left" or "right" (default: "left")
- animation (str): Text animation - "bounce", "marquee" (default: None)
- interval (int): Frame interval in milliseconds (default: -1)
- enabled (bool): Whether spinner is active (default: True)
- stream (io.TextIOWrapper): Output stream (default: sys.stdout)
"""HaloNotebook uses IPython widgets for rendering, providing clean output management in notebook cells.
@property
def output(self):
"""
Get the IPython Output widget instance.
Returns:
- ipywidgets.Output: The widget used for spinner display
"""Usage Example:
# In Jupyter notebook cell
from halo import HaloNotebook
import time
# Basic usage - identical to Halo
spinner = HaloNotebook(text='Processing data', spinner='dots', color='blue')
spinner.start()
time.sleep(3)
spinner.succeed('✓ Processing complete')Halo automatically detects the execution environment and uses appropriate spinner class.
from halo import Halo
import time
# Automatically uses HaloNotebook in Jupyter, regular Halo in terminal
with Halo(text='Loading', spinner='dots'):
time.sleep(2)For full Jupyter notebook support, install with notebook dependencies:
pip install halo[ipython]This installs the required IPython and ipywidgets dependencies:
IPython==5.7.0ipywidgets==7.1.0# In Jupyter notebook cell
from halo import HaloNotebook
import time
# Context manager usage
with HaloNotebook(text='Training model', spinner='dots', color='green'):
# Simulate long-running operation
for epoch in range(5):
time.sleep(1)
print(f"Epoch {epoch + 1} completed") # This won't interfere with spinner
print("Training completed!")# In Jupyter notebook cell
from halo import HaloNotebook
import time
spinner = HaloNotebook(text='Starting analysis', spinner='star')
spinner.start()
# Update text during execution
for i in range(1, 6):
spinner.text = f'Processing batch {i}/5'
time.sleep(1)
spinner.succeed('✓ Analysis completed successfully')# In Jupyter notebook cell
from halo import HaloNotebook
import time
@HaloNotebook(text='Running computation', spinner='dots', color='cyan')
def heavy_computation():
time.sleep(3)
return "computation_result"
result = heavy_computation()
print(f"Result: {result}")# In Jupyter notebook cell
from halo import HaloNotebook
import time
def analyze_data():
spinner = HaloNotebook(text='Analyzing dataset', spinner='arrow')
spinner.start()
time.sleep(2)
# Different completion methods work the same
try:
# Simulate analysis
success = True
if success:
spinner.succeed('✓ Analysis completed - 1000 records processed')
else:
spinner.fail('✗ Analysis failed')
except Exception as e:
spinner.fail(f'✗ Error during analysis: {e}')
analyze_data()# In Jupyter notebook cell
from halo import HaloNotebook
import time
def data_pipeline():
# Step 1: Data loading
loader = HaloNotebook(text='Loading data', spinner='dots', color='blue')
loader.start()
time.sleep(1)
loader.succeed('✓ Data loaded - 10,000 records')
# Step 2: Data processing
processor = HaloNotebook(text='Processing data', spinner='star', color='green')
processor.start()
time.sleep(2)
processor.succeed('✓ Data processed - features extracted')
# Step 3: Model training
trainer = HaloNotebook(text='Training model', spinner='arrow', color='red')
trainer.start()
time.sleep(3)
trainer.succeed('✓ Model trained - accuracy: 95.2%')
data_pipeline()# In Jupyter notebook cell
from halo import HaloNotebook
import time
def process_files():
files = ['data1.csv', 'data2.csv', 'data3.csv', 'data4.csv', 'data5.csv']
spinner = HaloNotebook(text='Starting file processing', spinner='dots')
spinner.start()
for i, file in enumerate(files, 1):
spinner.text = f'Processing {file} ({i}/{len(files)})'
time.sleep(1) # Simulate processing time
spinner.succeed(f'✓ Processed {len(files)} files successfully')
process_files()# In Jupyter notebook cell
from halo import HaloNotebook
import pandas as pd
import numpy as np
import time
def data_analysis():
spinner = HaloNotebook(text='Loading dataset', spinner='dots', color='blue')
spinner.start()
# Simulate data loading
time.sleep(1)
data = pd.DataFrame(np.random.randn(10000, 5))
spinner.text = 'Computing statistics'
time.sleep(1)
stats = data.describe()
spinner.text = 'Performing correlation analysis'
time.sleep(1)
corr = data.corr()
spinner.succeed('✓ Analysis complete - results ready')
return stats, corr
stats, correlations = data_analysis()Halo automatically detects the execution environment:
from halo._utils import get_environment
env = get_environment()
print(f"Current environment: {env}")
# Possible values: "terminal", "ipython", "jupyter"# Force use of HaloNotebook even in terminal (not recommended)
from halo import HaloNotebook
# Force use of regular Halo in notebook (will not display properly)
from halo.halo import HaloFor HaloNotebook to work properly:
If these requirements aren't met, HaloNotebook will fall back to standard Halo behavior.
Spinner not displaying in notebook:
ipywidgets is installed: pip install ipywidgetsjupyter nbextension enable --py widgetsnbextensionMultiple outputs in cell:
HaloNotebook instead of Halo in notebook environmentsWidget state errors:
Install with Tessl CLI
npx tessl i tessl/pypi-halo