console.py 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. """Functions to communicate to the user via console."""
  2. from __future__ import annotations
  3. from rich.console import Console
  4. from rich.progress import MofNCompleteColumn, Progress, TimeElapsedColumn
  5. from rich.prompt import Prompt
  6. from reflex.constants import LogLevel
  7. # Console for pretty printing.
  8. _console = Console()
  9. # The current log level.
  10. _LOG_LEVEL = LogLevel.INFO
  11. # Deprecated features who's warning has been printed.
  12. _EMITTED_DEPRECATION_WARNINGS = set()
  13. def set_log_level(log_level: LogLevel):
  14. """Set the log level.
  15. Args:
  16. log_level: The log level to set.
  17. """
  18. global _LOG_LEVEL
  19. _LOG_LEVEL = log_level
  20. def print(msg: str, **kwargs):
  21. """Print a message.
  22. Args:
  23. msg: The message to print.
  24. kwargs: Keyword arguments to pass to the print function.
  25. """
  26. _console.print(msg, **kwargs)
  27. def debug(msg: str, **kwargs):
  28. """Print a debug message.
  29. Args:
  30. msg: The debug message.
  31. kwargs: Keyword arguments to pass to the print function.
  32. """
  33. if _LOG_LEVEL <= LogLevel.DEBUG:
  34. msg_ = f"[blue]Debug: {msg}[/blue]"
  35. if progress := kwargs.pop("progress", None):
  36. progress.console.print(msg_, **kwargs)
  37. else:
  38. print(msg_, **kwargs)
  39. def info(msg: str, **kwargs):
  40. """Print an info message.
  41. Args:
  42. msg: The info message.
  43. kwargs: Keyword arguments to pass to the print function.
  44. """
  45. if _LOG_LEVEL <= LogLevel.INFO:
  46. print(f"[cyan]Info: {msg}[/cyan]", **kwargs)
  47. def success(msg: str, **kwargs):
  48. """Print a success message.
  49. Args:
  50. msg: The success message.
  51. kwargs: Keyword arguments to pass to the print function.
  52. """
  53. if _LOG_LEVEL <= LogLevel.INFO:
  54. print(f"[green]Success: {msg}[/green]", **kwargs)
  55. def log(msg: str, **kwargs):
  56. """Takes a string and logs it to the console.
  57. Args:
  58. msg: The message to log.
  59. kwargs: Keyword arguments to pass to the print function.
  60. """
  61. if _LOG_LEVEL <= LogLevel.INFO:
  62. _console.log(msg, **kwargs)
  63. def rule(title: str, **kwargs):
  64. """Prints a horizontal rule with a title.
  65. Args:
  66. title: The title of the rule.
  67. kwargs: Keyword arguments to pass to the print function.
  68. """
  69. _console.rule(title, **kwargs)
  70. def warn(msg: str, **kwargs):
  71. """Print a warning message.
  72. Args:
  73. msg: The warning message.
  74. kwargs: Keyword arguments to pass to the print function.
  75. """
  76. if _LOG_LEVEL <= LogLevel.WARNING:
  77. print(f"[orange1]Warning: {msg}[/orange1]", **kwargs)
  78. def deprecate(
  79. feature_name: str,
  80. reason: str,
  81. deprecation_version: str,
  82. removal_version: str,
  83. dedupe: bool = True,
  84. **kwargs,
  85. ):
  86. """Print a deprecation warning.
  87. Args:
  88. feature_name: The feature to deprecate.
  89. reason: The reason for deprecation.
  90. deprecation_version: The version the feature was deprecated
  91. removal_version: The version the deprecated feature will be removed
  92. dedupe: If True, suppress multiple console logs of deprecation message.
  93. kwargs: Keyword arguments to pass to the print function.
  94. """
  95. if feature_name not in _EMITTED_DEPRECATION_WARNINGS:
  96. msg = (
  97. f"{feature_name} has been deprecated in version {deprecation_version} {reason.rstrip('.')}. It will be completely "
  98. f"removed in {removal_version}"
  99. )
  100. if _LOG_LEVEL <= LogLevel.WARNING:
  101. print(f"[yellow]DeprecationWarning: {msg}[/yellow]", **kwargs)
  102. if dedupe:
  103. _EMITTED_DEPRECATION_WARNINGS.add(feature_name)
  104. def error(msg: str, **kwargs):
  105. """Print an error message.
  106. Args:
  107. msg: The error message.
  108. kwargs: Keyword arguments to pass to the print function.
  109. """
  110. if _LOG_LEVEL <= LogLevel.ERROR:
  111. print(f"[red]{msg}[/red]", **kwargs)
  112. def ask(
  113. question: str,
  114. choices: list[str] | None = None,
  115. default: str | None = None,
  116. show_choices: bool = True,
  117. ) -> str:
  118. """Takes a prompt question and optionally a list of choices
  119. and returns the user input.
  120. Args:
  121. question: The question to ask the user.
  122. choices: A list of choices to select from.
  123. default: The default option selected.
  124. show_choices: Whether to show the choices.
  125. Returns:
  126. A string with the user input.
  127. """
  128. return Prompt.ask(question, choices=choices, default=default, show_choices=show_choices) # type: ignore
  129. def progress():
  130. """Create a new progress bar.
  131. Returns:
  132. A new progress bar.
  133. """
  134. return Progress(
  135. *Progress.get_default_columns()[:-1],
  136. MofNCompleteColumn(),
  137. TimeElapsedColumn(),
  138. )
  139. def status(*args, **kwargs):
  140. """Create a status with a spinner.
  141. Args:
  142. *args: Args to pass to the status.
  143. **kwargs: Kwargs to pass to the status.
  144. Returns:
  145. A new status.
  146. """
  147. return _console.status(*args, **kwargs)