Skip to content

Instantly share code, notes, and snippets.

@marcio0
Created April 5, 2022 14:50
Show Gist options
  • Save marcio0/ead7bd19b897fc6261e50e0d9fe17184 to your computer and use it in GitHub Desktop.
Save marcio0/ead7bd19b897fc6261e50e0d9fe17184 to your computer and use it in GitHub Desktop.
import sys
import threading
import itertools
import time
# https://stackoverflow.com/questions/4995733/how-to-create-a-spinning-command-line-cursor
class Spinner:
def __init__(self, message="", delay=0.1):
self.spinner = itertools.cycle(["-", "/", "|", "\\"])
self.delay = delay
self.busy = False
self.spinner_visible = False
sys.stdout.write(message)
def write_next(self):
with self._screen_lock:
if not self.spinner_visible:
sys.stdout.write(next(self.spinner))
self.spinner_visible = True
sys.stdout.flush()
def remove_spinner(self, cleanup=False):
with self._screen_lock:
if self.spinner_visible:
sys.stdout.write("\b")
self.spinner_visible = False
if cleanup:
sys.stdout.write(" ") # overwrite spinner with blank
sys.stdout.write("\r") # move to next line
sys.stdout.flush()
def spinner_task(self):
while self.busy:
self.write_next()
time.sleep(self.delay)
self.remove_spinner()
def __enter__(self):
if sys.stdout.isatty():
self._screen_lock = threading.Lock()
self.busy = True
self.thread = threading.Thread(target=self.spinner_task)
self.thread.start()
def __exit__(self, exception, value, tb):
if sys.stdout.isatty():
self.busy = False
self.remove_spinner(cleanup=True)
else:
sys.stdout.write("\r")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment