Spaces:
Sleeping
Sleeping
"""Module contains spinner related resources. | |
Note: | |
The spinner is not a standalone spinner to run in the terminal | |
but rather a `prompt_toolkit` :class:`~prompt_toolkit.layout.Window` that displays a spinner. | |
Use library such as `yaspin <https://github.com/pavdmyt/yaspin>`_ if you need a plain spinner. | |
""" | |
import asyncio | |
from typing import TYPE_CHECKING, Callable, List, NamedTuple, Optional, Tuple, Union | |
from prompt_toolkit.filters.utils import to_filter | |
from prompt_toolkit.layout.containers import ConditionalContainer, Window | |
from prompt_toolkit.layout.controls import FormattedTextControl | |
if TYPE_CHECKING: | |
from prompt_toolkit.filters.base import Filter | |
__all__ = ["SPINNERS", "SpinnerWindow"] | |
class SPINNERS(NamedTuple): | |
"""Presets of spinner patterns. | |
See Also: | |
https://github.com/pavdmyt/yaspin/blob/master/yaspin/data/spinners.json | |
This only contains some basic ones thats ready to use. For more patterns, checkout the | |
URL above. | |
Examples: | |
>>> from InquirerPy import inquirer | |
>>> from InquirerPy.spinner import SPINNERS | |
>>> inquirer.select(message="", choices=lambda _: [1, 2, 3], spinner_pattern=SPINNERS.dots) | |
""" | |
dots = ["β ", "β ", "β Ή", "β Έ", "β Ό", "β ΄", "β ¦", "β §", "β ", "β "] | |
dots2 = ["β£Ύ", "β£½", "β£»", "β’Ώ", "β‘Ώ", "β£", "β£―", "β£·"] | |
line = ["-", "\\", "|", "/"] | |
line2 = ["β ", "-", "β", "β", "β", "-"] | |
pipe = ["β€", "β", "β΄", "β", "β", "β", "β¬", "β"] | |
star = ["βΆ", "βΈ", "βΉ", "βΊ", "βΉ", "β·"] | |
star2 = ["+", "x", "*"] | |
flip = ["_", "_", "_", "-", "`", "`", "'", "Β΄", "-", "_", "_", "_"] | |
hamburger = ["β±", "β²", "β΄"] | |
grow_vertical = ["β", "β", "β", "β ", "β", "β", "β", "β ", "β", "β"] | |
grow_horizontal = ["β", "β", "β", "β", "β", "β", "β", "β", "β", "β", "β", "β"] | |
box_bounce = ["β", "β", "β", "β"] | |
triangle = ["β’", "β£", "β€", "β₯"] | |
arc = ["β", "β ", "β", "β", "β‘", "β"] | |
circle = ["β‘", "β", "β "] | |
class SpinnerWindow(ConditionalContainer): | |
"""Conditional `prompt_toolkit` :class:`~prompt_toolkit.layout.Window` that displays a spinner. | |
Args: | |
loading: A :class:`~prompt_toolkit.filters.Condition` to indicate if the spinner should be visible. | |
redraw: A redraw function (i.e. :meth:`~prompt_toolkit.application.Application.invalidate`) to refresh the UI. | |
pattern: List of pattern to display as the spinner. | |
delay: Spinner refresh frequency. | |
text: Loading text to display. | |
""" | |
def __init__( | |
self, | |
loading: "Filter", | |
redraw: Callable[[], None], | |
pattern: Optional[Union[List[str], SPINNERS]] = None, | |
delay: float = 0.1, | |
text: str = "", | |
) -> None: | |
self._loading = to_filter(loading) | |
self._spinning = False | |
self._redraw = redraw | |
self._pattern = pattern or SPINNERS.line | |
self._char = self._pattern[0] | |
self._delay = delay | |
self._text = text or "Loading ..." | |
super().__init__( | |
content=Window(content=FormattedTextControl(text=self._get_text)), | |
filter=self._loading, | |
) | |
def _get_text(self) -> List[Tuple[str, str]]: | |
"""Dynamically get the text for the :class:`~prompt_toolkit.layout.Window`. | |
Returns: | |
Formatted text. | |
""" | |
return [ | |
("class:spinner_pattern", self._char), | |
("", " "), | |
("class:spinner_text", self._text), | |
] | |
async def start(self) -> None: | |
"""Start the spinner.""" | |
if self._spinning: | |
return | |
self._spinning = True | |
while self._loading(): | |
for char in self._pattern: | |
await asyncio.sleep(self._delay) | |
self._char = char | |
self._redraw() | |
self._spinning = False | |