This example uses the rich.console.Console and rich.spinner.Spinner classes. The first context manager, get_console(), yields a rich.Console() object, which can be used with the rich.Spinner() class to display a spinner on the command line.
fromcontextlibimportcontextmanagerimporttypingastfromrich.consoleimportConsole@contextmanagerdefget_console()->t.Generator[Console,t.Any,None]:"""Yield a `rich.Console`. Usage: `with get_console() as console:` """try:console:Console=Console()yieldconsoleexceptExceptionasexc:msg=Exception(f"Unhandled exception getting rich Console. Details: {exc}")log.error(msg)raiseexc
The simple_spinner() context manager yields a rich.Spinner() instance. Wrap a function in with simple_spinner(msg="Some message") as spinner: to show a spinner while the function executes.
fromcontextlibimportcontextmanagerfromrich.spinnerimportSpinner@contextmanagerdefsimple_spinner(text:str="Processing... \n",animation:str="dots"):ifnottext:text:str="Processing... \n"assertisinstance(text,str),TypeError(f"Expected spinner text to be a string. Got type: ({type(text)})")ifnottext.endswith("\n"):text+=" \n"ifnotanimation:animation:str="dots"assertisinstance(animation,str),TypeError(f"Expected spinner animation to be a string. Got type: ({type(text)})")try:_spinner=Spinner(animation,text=text)exceptExceptionasexc:msg=Exception(f"Unhandled exception getting console spinner. Details: {exc}")log.error(msg)raiseexc## Display spinnertry:withget_console()asconsole:withconsole.status(text,spinner=animation):yieldconsoleexceptExceptionasexc:msg=Exception(f"Unhandled exception yielding spinner. Continuing without animation. Details: {exc}")log.error(msg)pass
Putting both of these functions in the same file allows you to import just the simple_spinner method, which calls get_console() for you. You can also get a console using with get_console() as console:, and write custom spinner/rich logic.