Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 
 

149 linhas
4.1 KiB

  1. from __future__ import annotations
  2. from typing import Any, Dict, List, Optional, Union
  3. from rich.console import Console, RenderableType
  4. from rich.theme import Theme
  5. from .input import Input
  6. from .menu import Menu, Option, ReturnValue
  7. from .progress import Progress
  8. from .styles.base import BaseStyle
  9. class RichToolkitTheme:
  10. def __init__(self, style: BaseStyle, theme: Dict[str, str]) -> None:
  11. self.style = style
  12. self.rich_theme = Theme(theme)
  13. class RichToolkit:
  14. def __init__(
  15. self,
  16. style: Optional[BaseStyle] = None,
  17. theme: Optional[RichToolkitTheme] = None,
  18. handle_keyboard_interrupts: bool = True,
  19. ) -> None:
  20. # TODO: deprecate this
  21. self.theme = theme
  22. if theme is not None:
  23. self.style = theme.style
  24. self.style.theme = theme.rich_theme
  25. self.style.console = Console(theme=theme.rich_theme)
  26. else:
  27. assert style is not None
  28. self.style = style
  29. self.console = self.style.console
  30. self.handle_keyboard_interrupts = handle_keyboard_interrupts
  31. def __enter__(self):
  32. self.console.print()
  33. return self
  34. def __exit__(
  35. self, exc_type: Any, exc_value: Any, traceback: Any
  36. ) -> Union[bool, None]:
  37. if self.handle_keyboard_interrupts and exc_type is KeyboardInterrupt:
  38. # we want to handle keyboard interrupts gracefully, instead of showing a traceback
  39. # or any other error message
  40. return True
  41. self.console.print()
  42. return None
  43. def print_title(self, title: str, **metadata: Any) -> None:
  44. self.console.print(self.style.render_element(title, title=True, **metadata))
  45. def print(self, *renderables: RenderableType, **metadata: Any) -> None:
  46. self.console.print(
  47. *[
  48. self.style.render_element(renderable, **metadata)
  49. for renderable in renderables
  50. ]
  51. )
  52. def print_as_string(self, *renderables: RenderableType, **metadata: Any) -> str:
  53. with self.console.capture() as capture:
  54. self.print(*renderables, **metadata)
  55. return capture.get().rstrip()
  56. def print_line(self) -> None:
  57. self.console.print(self.style.empty_line())
  58. def confirm(self, label: str, **metadata: Any) -> bool:
  59. return self.ask(
  60. label=label,
  61. options=[
  62. Option({"value": True, "name": "Yes"}),
  63. Option({"value": False, "name": "No"}),
  64. ],
  65. inline=True,
  66. **metadata,
  67. )
  68. def ask(
  69. self,
  70. label: str,
  71. options: List[Option[ReturnValue]],
  72. inline: bool = False,
  73. allow_filtering: bool = False,
  74. **metadata: Any,
  75. ) -> ReturnValue:
  76. return Menu(
  77. label=label,
  78. options=options,
  79. console=self.console,
  80. style=self.style,
  81. inline=inline,
  82. allow_filtering=allow_filtering,
  83. **metadata,
  84. ).ask()
  85. def input(
  86. self,
  87. title: str,
  88. default: str = "",
  89. placeholder: str = "",
  90. password: bool = False,
  91. required: bool = False,
  92. required_message: str = "",
  93. inline: bool = False,
  94. **metadata: Any,
  95. ) -> str:
  96. return Input(
  97. name=title,
  98. label=title,
  99. default=default,
  100. placeholder=placeholder,
  101. password=password,
  102. required=required,
  103. required_message=required_message,
  104. inline=inline,
  105. style=self.style,
  106. **metadata,
  107. ).ask()
  108. def progress(
  109. self,
  110. title: str,
  111. transient: bool = False,
  112. transient_on_error: bool = False,
  113. inline_logs: bool = False,
  114. lines_to_show: int = -1,
  115. ) -> Progress:
  116. return Progress(
  117. title=title,
  118. console=self.console,
  119. style=self.style,
  120. transient=transient,
  121. transient_on_error=transient_on_error,
  122. inline_logs=inline_logs,
  123. lines_to_show=lines_to_show,
  124. )