Package: yaspin
yaspin:YetAnother TerminalSpinner for PythonYaspinprovides a full-featured terminal spinner to show the progress during long-hanging operations.It is easy to integrate into existing codebase by using it as acontext manageror as a functiondecorator:importtimefromyaspinimportyaspin# Context manager:withyaspin():time.sleep(3)# time consuming code# Function decorator:@yaspin(text="Loading...")defsome_operations():time.sleep(3)# time consuming codesome_operations()Yaspinalso provides an intuitive and powerful API. For example, you can easily summon a shark:importtimefromyaspinimportyaspinwithyaspin().white.bold.shark.on_blueassp:sp.text="White bold shark in a blue sea"time.sleep(5)FeaturesRuns at all majorCPythonversions (3.9,3.10,3.11,3.12),PyPySupports all (70+) spinners fromcli-spinnersSupports allcolors,highlights,attributesand their mixes fromtermcolorlibraryEasy to combine with other command-line libraries, e.g.prompt-toolkitFlexible API, easy to integrate with existing codeUser-friendly API for handling POSIXsignalsSafepipesandredirects:$pythonscript_that_uses_yaspin.py>script.log$pythonscript_that_uses_yaspin.py|grepERRORInstallationFromPyPIusingpippackage manager:pipinstall--upgradeyaspinOr install the latest sources from GitHub:pipinstallhttps://github.com/pavdmyt/yaspin/archive/master.zipUsageBasic Exampleimporttimefromrandomimportrandintfromyaspinimportyaspinwithyaspin(text="Loading",color="yellow")asspinner:time.sleep(2)# time consuming codesuccess=randint(0,1)ifsuccess:spinner.ok("✅ ")else:spinner.fail("💥 ")It is also possible to control spinner manually:importtimefromyaspinimportyaspinspinner=yaspin()spinner.start()time.sleep(3)# time consuming tasksspinner.stop()Run any spinner fromcli-spinnersimporttimefromyaspinimportyaspinfromyaspin.spinnersimportSpinnerswithyaspin(Spinners.earth,text="Earth")assp:time.sleep(2)# time consuming code# change spinnersp.spinner=Spinners.moonsp.text="Moon"time.sleep(2)# time consuming codeAny Colour You Like🌈importtimefromyaspinimportyaspinwithyaspin(text="Colors!")assp:# Support all basic termcolor text colorscolors=("red","green","yellow","blue","magenta","cyan","white")forcolorincolors:sp.color,sp.text=color,colortime.sleep(1)Advanced colors usageimporttimefromyaspinimportyaspinfromyaspin.spinnersimportSpinnerstext="Bold blink magenta spinner on cyan color"withyaspin().bold.blink.magenta.bouncingBall.on_cyanassp:sp.text=texttime.sleep(3)# The same result can be achieved by passing arguments directlywithyaspin(Spinners.bouncingBall,color="magenta",on_color="on_cyan",attrs=["bold","blink"],)assp:sp.text=texttime.sleep(3)Run any spinner you wantimporttimefromyaspinimportyaspin,Spinner# Compose new spinners with custom frame sequence and interval valuesp=Spinner(["😸","😹","😺","😻","😼","😽","😾","😿","🙀"],200)withyaspin(sp,text="Cat!"):time.sleep(3)# cat consuming code :)Change spinner properties on the flyimporttimefromyaspinimportyaspinfromyaspin.spinnersimportSpinnerswithyaspin(Spinners.noise,text="Noise spinner")assp:time.sleep(2)sp.spinner=Spinners.arc# spinner typesp.text="Arc spinner"# text along with spinnersp.color="green"# spinner colorsp.side="right"# put spinner to the rightsp.reversal=True# reverse spin directiontime.sleep(2)Spinner with timerimporttimefromyaspinimportyaspinwithyaspin(text="elapsed time",timer=True)assp:time.sleep(3.1415)sp.ok()Dynamic textimporttimefromdatetimeimportdatetimefromyaspinimportyaspinclassTimedText:def__init__(self,text):self.text=textself._start=datetime.now()def__str__(self):now=datetime.now()delta=now-self._startreturnf"{self.text}({round(delta.total_seconds(),1)}s)"withyaspin(text=TimedText("time passed:")):time.sleep(3)Writing messagesYou should not write any message in the terminal usingprintwhile spinner is open.
To write messages in the terminal without any collision withyaspinspinner, a.write()method is provided:importtimefromyaspinimportyaspinwithyaspin(text="Downloading images",color="cyan")assp:# task 1time.sleep(1)sp.write("> image 1 download complete")# task 2time.sleep(2)sp.write("> image 2 download complete")# finalizesp.ok("✔")Integration with other librariesUtilizinghiddencontext manager it is possible to toggle the display of
the spinner in order to call custom methods that write to the terminal. This is
helpful for allowing easy usage in other frameworks likeprompt-toolkit.
Using the powerfulprint_formatted_textfunction allows you even to apply
HTML formats and CSS styles to the output:importsysimporttimefromyaspinimportyaspinfromprompt_toolkitimportHTML,print_formatted_textfromprompt_toolkit.stylesimportStyle# override print with feature-rich ``print_formatted_text`` from prompt_toolkitprint=print_formatted_text# build a basic prompt_toolkit style for styling the HTML wrapped textstyle=Style.from_dict({'msg':'#4caf50 bold','sub-msg':'#616161 italic'})withyaspin(text='Downloading images')assp:# task 1time.sleep(1)withsp.hidden():print(HTML(u'<b>></b> <msg>image 1</msg> <sub-msg>download complete</sub-msg>'),style=style)# task 2time.sleep(2)withsp.hidden():print(HTML(u'<b>></b> <msg>image 2</msg> <sub-msg>download complete</sub-msg>'),style=style)# finalizesp.ok()Handling POSIXsignalsHandling keyboard interrupts (pressing Control-C):importtimefromyaspinimportkbi_safe_yaspinwithkbi_safe_yaspin(text="Press Control+C to send SIGINT (Keyboard Interrupt) signal"):time.sleep(5)# time consuming codeHandling other types of signals:importosimporttimefromsignalimportSIGTERM,SIGUSR1fromyaspinimportyaspinfromyaspin.signal_handlersimportdefault_handler,fancy_handlersigmap={SIGUSR1:default_handler,SIGTERM:fancy_handler}withyaspin(sigmap=sigmap,text="Handling SIGUSR1 and SIGTERM signals")assp:sp.write("Send signals using `kill` command")sp.write("E.g. $ kill -USR1{0}".format(os.getpid()))time.sleep(20)# time consuming codeMoreexamples.DevelopmentClone the repository:gitclonehttps://github.com/pavdmyt/yaspin.gitInstall dev dependencies:poetryinstall# if you don't have poetry installed:pipinstall-rrequirements.txtLint code:makelintFormat code:makeblack-fmtRun tests:maketestContributingFork it!Create your feature branch:git checkout-bmy-new-featureCommit your changes:git commit-m'Add some feature'Push to the branch:git push originmy-new-featureSubmit a pull requestMake sure tests are passingLicenseMIT - Pavlo Dmytrenko;https://twitter.com/pavdmytContains data fromcli-spinners: MIT License, Copyright (c) Sindre Sorhussindresorhus@gmail.com(sindresorhus.com)