Skip to content

Instantly share code, notes, and snippets.

@thewh1teagle
Created November 10, 2024 17:48
Show Gist options
  • Save thewh1teagle/7f2eec5fc30f54966ab1e524decc0d38 to your computer and use it in GitHub Desktop.
Save thewh1teagle/7f2eec5fc30f54966ab1e524decc0d38 to your computer and use it in GitHub Desktop.
Beautiful spinner in python
"""
pip install colorama
"""
import sys
import threading
import time
from colorama import init, Fore, Style
class Spinner:
def __init__(self, initial_message=""):
self.message = initial_message
self.spinning = False
self.spinner_frames = ["⣾", "⣽", "⣻", "⢿", "⡿", "⣟", "⣯", "⣷"]
self.frame_index = 0
self.max_message_length = len(self.message)
def hide_cursor(self):
sys.stdout.write("\033[?25l")
sys.stdout.flush()
def show_cursor(self):
sys.stdout.write("\033[?25h")
sys.stdout.flush()
def start(self):
self.hide_cursor()
if self.spinning:
return # Don't start if already spinning
self.spinning = True
self.spinner_thread = threading.Thread(target=self.spin)
self.spinner_thread.start()
def spin(self):
while self.spinning:
# Update the max message length
self.max_message_length = max(self.max_message_length, len(self.message))
# Move cursor to start of the line and overwrite it
sys.stdout.write("\r" + Fore.GREEN + self.spinner_frames[self.frame_index] +
Style.RESET_ALL + " " + self.message)
sys.stdout.flush()
# Update spinner frame
self.frame_index = (self.frame_index + 1) % len(self.spinner_frames)
time.sleep(0.1) # Adjust speed here
# Clear line when done
sys.stdout.write("\r" + " " * (self.max_message_length + 3) + "\r")
sys.stdout.flush()
self.show_cursor()
def update_message(self, new_message):
self.message = new_message
def stop(self):
self.spinning = False
if self.spinner_thread.is_alive():
self.spinner_thread.join()
self.show_cursor()
if __name__ == "__main__":
total_steps = 100
spinner = Spinner("Fetching")
try:
spinner.start()
for i in range(total_steps + 1): # Simulate a task with 100 steps
time.sleep(0.05) # Simulate some work
percentage = int((i / total_steps) * 100)
spinner.update_message(f"Fetching {percentage}%")
spinner.update_message("Almost done...")
time.sleep(1)
finally:
spinner.stop()
print(Fore.GREEN + '✔' + Style.RESET_ALL + " Fetch complete!")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment