hammad-python 0.0.13__py3-none-any.whl → 0.0.15__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. hammad_python-0.0.15.dist-info/METADATA +184 -0
  2. hammad_python-0.0.15.dist-info/RECORD +4 -0
  3. hammad/__init__.py +0 -180
  4. hammad/_core/__init__.py +0 -1
  5. hammad/_core/_utils/__init__.py +0 -4
  6. hammad/_core/_utils/_import_utils.py +0 -182
  7. hammad/ai/__init__.py +0 -59
  8. hammad/ai/_utils.py +0 -142
  9. hammad/ai/completions/__init__.py +0 -44
  10. hammad/ai/completions/client.py +0 -729
  11. hammad/ai/completions/create.py +0 -686
  12. hammad/ai/completions/types.py +0 -711
  13. hammad/ai/completions/utils.py +0 -374
  14. hammad/ai/embeddings/__init__.py +0 -35
  15. hammad/ai/embeddings/client/__init__.py +0 -1
  16. hammad/ai/embeddings/client/base_embeddings_client.py +0 -26
  17. hammad/ai/embeddings/client/fastembed_text_embeddings_client.py +0 -200
  18. hammad/ai/embeddings/client/litellm_embeddings_client.py +0 -288
  19. hammad/ai/embeddings/create.py +0 -159
  20. hammad/ai/embeddings/types.py +0 -69
  21. hammad/base/__init__.py +0 -35
  22. hammad/base/fields.py +0 -546
  23. hammad/base/model.py +0 -1078
  24. hammad/base/utils.py +0 -280
  25. hammad/cache/__init__.py +0 -48
  26. hammad/cache/base_cache.py +0 -181
  27. hammad/cache/cache.py +0 -169
  28. hammad/cache/decorators.py +0 -261
  29. hammad/cache/file_cache.py +0 -80
  30. hammad/cache/ttl_cache.py +0 -74
  31. hammad/cli/__init__.py +0 -33
  32. hammad/cli/animations.py +0 -604
  33. hammad/cli/plugins.py +0 -781
  34. hammad/cli/styles/__init__.py +0 -55
  35. hammad/cli/styles/settings.py +0 -139
  36. hammad/cli/styles/types.py +0 -358
  37. hammad/cli/styles/utils.py +0 -480
  38. hammad/configuration/__init__.py +0 -35
  39. hammad/configuration/configuration.py +0 -564
  40. hammad/data/__init__.py +0 -39
  41. hammad/data/collections/__init__.py +0 -34
  42. hammad/data/collections/base_collection.py +0 -58
  43. hammad/data/collections/collection.py +0 -452
  44. hammad/data/collections/searchable_collection.py +0 -556
  45. hammad/data/collections/vector_collection.py +0 -603
  46. hammad/data/databases/__init__.py +0 -21
  47. hammad/data/databases/database.py +0 -902
  48. hammad/json/__init__.py +0 -21
  49. hammad/json/converters.py +0 -152
  50. hammad/logging/__init__.py +0 -35
  51. hammad/logging/decorators.py +0 -834
  52. hammad/logging/logger.py +0 -954
  53. hammad/multimodal/__init__.py +0 -24
  54. hammad/multimodal/audio.py +0 -96
  55. hammad/multimodal/image.py +0 -80
  56. hammad/multithreading/__init__.py +0 -304
  57. hammad/py.typed +0 -0
  58. hammad/pydantic/__init__.py +0 -43
  59. hammad/pydantic/converters.py +0 -623
  60. hammad/pydantic/models/__init__.py +0 -28
  61. hammad/pydantic/models/arbitrary_model.py +0 -46
  62. hammad/pydantic/models/cacheable_model.py +0 -79
  63. hammad/pydantic/models/fast_model.py +0 -318
  64. hammad/pydantic/models/function_model.py +0 -176
  65. hammad/pydantic/models/subscriptable_model.py +0 -63
  66. hammad/text/__init__.py +0 -82
  67. hammad/text/converters.py +0 -723
  68. hammad/text/markdown.py +0 -131
  69. hammad/text/text.py +0 -1066
  70. hammad/types/__init__.py +0 -11
  71. hammad/types/file.py +0 -358
  72. hammad/typing/__init__.py +0 -407
  73. hammad/web/__init__.py +0 -43
  74. hammad/web/http/__init__.py +0 -1
  75. hammad/web/http/client.py +0 -944
  76. hammad/web/models.py +0 -245
  77. hammad/web/openapi/__init__.py +0 -0
  78. hammad/web/openapi/client.py +0 -740
  79. hammad/web/search/__init__.py +0 -1
  80. hammad/web/search/client.py +0 -988
  81. hammad/web/utils.py +0 -472
  82. hammad/yaml/__init__.py +0 -30
  83. hammad/yaml/converters.py +0 -19
  84. hammad_python-0.0.13.dist-info/METADATA +0 -38
  85. hammad_python-0.0.13.dist-info/RECORD +0 -85
  86. {hammad_python-0.0.13.dist-info → hammad_python-0.0.15.dist-info}/WHEEL +0 -0
  87. {hammad_python-0.0.13.dist-info → hammad_python-0.0.15.dist-info}/licenses/LICENSE +0 -0
hammad/cli/animations.py DELETED
@@ -1,604 +0,0 @@
1
- """hammad.cli.styles.animations"""
2
-
3
- import time
4
- import math
5
- import random
6
- import threading
7
- from dataclasses import dataclass, field
8
- from typing import Literal, Optional, List, overload, TYPE_CHECKING
9
-
10
- if TYPE_CHECKING:
11
- from rich import get_console
12
- from rich.console import Console, ConsoleOptions, RenderResult, RenderableType
13
- from rich.live import Live
14
- from rich.text import Text
15
- from rich.panel import Panel
16
-
17
- from .styles.types import (
18
- CLIStyleColorName,
19
- )
20
-
21
-
22
- def _get_rich_animation_classes():
23
- """Lazy import for rich classes used in animations"""
24
- from rich import get_console
25
- from rich.console import Console, ConsoleOptions, RenderResult, RenderableType
26
- from rich.live import Live
27
- from rich.text import Text
28
- from rich.panel import Panel
29
-
30
- return {
31
- "get_console": get_console,
32
- "Console": Console,
33
- "ConsoleOptions": ConsoleOptions,
34
- "RenderResult": RenderResult,
35
- "RenderableType": RenderableType,
36
- "Live": Live,
37
- "Text": Text,
38
- "Panel": Panel,
39
- }
40
-
41
-
42
- __all__ = (
43
- "CLIAnimation",
44
- "CLIAnimationState",
45
- "CLIFlashingAnimation",
46
- "CLIPulsingAnimation",
47
- "CLIShakingAnimation",
48
- "CLITypingAnimation",
49
- "CLISpinningAnimation",
50
- "CLIRainbowAnimation",
51
- "animate_flashing",
52
- "animate_pulsing",
53
- "animate_shaking",
54
- "animate_spinning",
55
- "animate_rainbow",
56
- "animate_typing",
57
- )
58
-
59
-
60
- @dataclass
61
- class CLIAnimationState:
62
- """Internal class used to track the current state of an
63
- animation."""
64
-
65
- start_time: float = field(default_factory=time.time)
66
- frame: int = 0
67
- last_update: float | None = field(default_factory=time.time)
68
-
69
-
70
- @dataclass
71
- class CLIAnimation:
72
- """Base class for all animations within the `hammad` package,
73
- this is used to integrate with rich's `__rich_console__` protocol."""
74
-
75
- def __init__(
76
- self,
77
- # The object that this animation is being applied to.
78
- renderable,
79
- duration: Optional[float] = None,
80
- ) -> None:
81
- self.renderable = renderable
82
- """The object that this animation is being applied to."""
83
- self.duration = duration or 2.0
84
- """The duration of the animation in seconds (defaults to 2.0 seconds)."""
85
- # Set last_update to None to ensure the animation is classified as
86
- # the first update on init.
87
- self.state = CLIAnimationState(last_update=None)
88
- """The current state of the animation."""
89
-
90
- rich_classes = _get_rich_animation_classes()
91
- self.rich_console = rich_classes["get_console"]()
92
- """The rich console responsible for rendering the animation."""
93
- self._animation_thread: threading.Thread | None = None
94
- """The thread responsible for running the animation."""
95
- self._stop_animation = False
96
- """Flag used to stop the animation."""
97
-
98
- def __rich_console__(
99
- self,
100
- console,
101
- options,
102
- ):
103
- """Rich will call this automatically when rendering."""
104
- if not self.is_complete:
105
- console.force_terminal = True
106
- if console.is_terminal:
107
- # force referesh
108
- console._is_alt_screen = False
109
-
110
- current_time = time.time()
111
- self.state.frame += 1
112
- self.state.last_update = current_time
113
-
114
- yield from self.apply(console, options)
115
-
116
- def apply(self, console, options):
117
- """Used by subclasses to apply the animation."""
118
- yield self.renderable
119
-
120
- @property
121
- def time_elapsed(self) -> float:
122
- """Time elapsed since the animation started."""
123
- return time.time() - self.state.start_time
124
-
125
- @property
126
- def is_complete(self) -> bool:
127
- """Check if the animation is complete."""
128
- if self.duration is None:
129
- return False
130
- return self.time_elapsed >= self.duration
131
-
132
- def animate(
133
- self,
134
- duration: Optional[float] = None,
135
- refresh_rate: int = 20,
136
- transient: bool = True,
137
- auto_refresh: bool = True,
138
- console: Optional["Console"] = None,
139
- screen: bool = False,
140
- vertical_overflow: str = "ellipsis",
141
- ) -> None:
142
- """Animate this effect for the specified duration using Live."""
143
- animate_duration = duration or self.duration or 3.0
144
- rich_classes = _get_rich_animation_classes()
145
- Console = rich_classes["Console"]
146
- Live = rich_classes["Live"]
147
-
148
- # Use provided console or create new one
149
- live_console = console or Console()
150
-
151
- with Live(
152
- self,
153
- console=live_console,
154
- refresh_per_second=refresh_rate,
155
- transient=transient,
156
- auto_refresh=auto_refresh,
157
- screen=screen,
158
- vertical_overflow=vertical_overflow,
159
- ) as live:
160
- start = time.time()
161
- while time.time() - start < animate_duration:
162
- time.sleep(0.05)
163
-
164
-
165
- class CLIFlashingAnimation(CLIAnimation):
166
- """Makes any renderable flash/blink."""
167
-
168
- def __init__(
169
- self,
170
- renderable,
171
- speed: float = 0.5,
172
- colors: Optional[List[CLIStyleColorName]] = None,
173
- on_color: CLIStyleColorName = "white",
174
- off_color: CLIStyleColorName = "dim white",
175
- duration: Optional[float] = None,
176
- ):
177
- super().__init__(renderable, duration)
178
- self.speed = speed
179
- # If colors is provided, use it; otherwise use on_color/off_color
180
- if colors is not None:
181
- self.colors = colors
182
- else:
183
- self.colors = [on_color, off_color]
184
-
185
- def apply(self, console, options):
186
- rich_classes = _get_rich_animation_classes()
187
- Text = rich_classes["Text"]
188
-
189
- # Calculate which color to use based on time
190
- color_index = int(self.time_elapsed / self.speed) % len(self.colors)
191
- color = self.colors[color_index]
192
-
193
- # Apply color to the renderable
194
- if isinstance(self.renderable, str):
195
- yield Text(self.renderable, style=color)
196
- else:
197
- # Wrap any renderable in the flash color
198
- yield Text.from_markup(f"[{color}]{self.renderable}[/{color}]")
199
-
200
-
201
- class CLIPulsingAnimation(CLIAnimation):
202
- """Makes any renderable pulse/breathe."""
203
-
204
- def __init__(
205
- self,
206
- renderable: "RenderableType",
207
- speed: float = 2.0,
208
- min_opacity: float = 0.3,
209
- max_opacity: float = 1.0,
210
- color: "CLIStyleColorName" = "white",
211
- duration: Optional[float] = None,
212
- ):
213
- super().__init__(renderable, duration)
214
- self.speed = speed
215
- self.min_opacity = min_opacity
216
- self.max_opacity = max_opacity
217
- self.color = color
218
-
219
- def apply(self, console: "Console", options: "ConsoleOptions") -> "RenderResult":
220
- # Calculate opacity using sine wave
221
- opacity = self.min_opacity + (self.max_opacity - self.min_opacity) * (
222
- 0.5 + 0.5 * math.sin(self.time_elapsed * self.speed)
223
- )
224
-
225
- # Convert opacity to RGB values for fading effect
226
- rgb_value = int(opacity * 255)
227
- fade_color = f"rgb({rgb_value},{rgb_value},{rgb_value})"
228
-
229
- if isinstance(self.renderable, str):
230
- yield Text(self.renderable, style=fade_color)
231
- else:
232
- # For Panel and other renderables, we need to use opacity styling
233
- if isinstance(self.renderable, Panel):
234
- # Create a new panel with modified style
235
- new_panel = Panel(
236
- self.renderable.renderable,
237
- title=self.renderable.title,
238
- title_align=self.renderable.title_align,
239
- subtitle=self.renderable.subtitle,
240
- subtitle_align=self.renderable.subtitle_align,
241
- box=self.renderable.box,
242
- style=fade_color,
243
- border_style=fade_color,
244
- expand=self.renderable.expand,
245
- padding=self.renderable.padding,
246
- width=self.renderable.width,
247
- height=self.renderable.height,
248
- )
249
- yield new_panel
250
- else:
251
- # For other renderables, wrap in a panel with the fade effect
252
- yield Panel(self.renderable, style=fade_color, border_style=fade_color)
253
-
254
-
255
- class CLIShakingAnimation(CLIAnimation):
256
- """Makes text shake/jitter."""
257
-
258
- def __init__(
259
- self,
260
- renderable: "RenderableType",
261
- intensity: int = 1,
262
- speed: float = 0.1,
263
- duration: Optional[float] = None,
264
- ):
265
- super().__init__(renderable, duration)
266
- self.intensity = intensity
267
- self.speed = speed
268
- self.last_shake = 0
269
-
270
- def apply(self, console: "Console", options: "ConsoleOptions") -> "RenderResult":
271
- if self.time_elapsed - self.last_shake > self.speed:
272
- self.last_shake = self.time_elapsed
273
-
274
- # Add random spaces for shake effect
275
- shake = " " * random.randint(0, self.intensity)
276
-
277
- if isinstance(self.renderable, str):
278
- yield Text(shake + self.renderable)
279
- else:
280
- yield Text(shake) + self.renderable
281
- else:
282
- # Keep previous position
283
- yield self.renderable
284
-
285
-
286
- class CLITypingAnimation(CLIAnimation):
287
- """Typewriter effect."""
288
-
289
- def __init__(
290
- self,
291
- text: str,
292
- speed: float = 0.05,
293
- typing_speed: Optional[float] = None,
294
- cursor: str = "█",
295
- show_cursor: bool = True,
296
- duration: Optional[float] = None,
297
- ):
298
- super().__init__(text, duration)
299
- self.text = text
300
- # Use typing_speed if provided, otherwise use speed
301
- self.speed = typing_speed if typing_speed is not None else speed
302
- self.cursor = cursor
303
- self.show_cursor = show_cursor
304
-
305
- def apply(self, console: "Console", options: "ConsoleOptions") -> "RenderResult":
306
- rich_classes = _get_rich_animation_classes()
307
- Text = rich_classes["Text"]
308
-
309
- # Calculate how many characters to show
310
- chars_to_show = int(self.time_elapsed / self.speed)
311
- chars_to_show = min(chars_to_show, len(self.text))
312
-
313
- if chars_to_show < len(self.text):
314
- # Still typing - show cursor if enabled
315
- text_content = self.text[:chars_to_show]
316
- if self.show_cursor:
317
- text_content += self.cursor
318
- yield Text(text_content)
319
- else:
320
- # Finished typing - show complete text without cursor
321
- yield Text(self.text)
322
-
323
-
324
- class CLISpinningAnimation(CLIAnimation):
325
- """Spinner effect for any renderable."""
326
-
327
- def __init__(
328
- self,
329
- renderable: "RenderableType",
330
- frames: Optional[List[str]] = None,
331
- speed: float = 0.1,
332
- prefix: bool = True,
333
- duration: Optional[float] = None,
334
- ):
335
- super().__init__(renderable, duration)
336
- self.frames = frames or ["⋅", "•", "●", "◉", "●", "•"]
337
- self.speed = speed
338
- self.prefix = prefix
339
-
340
- def apply(self, console: "Console", options: "ConsoleOptions") -> "RenderResult":
341
- frame_index = int(self.time_elapsed / self.speed) % len(self.frames)
342
- spinner = self.frames[frame_index]
343
-
344
- if isinstance(self.renderable, str):
345
- if self.prefix:
346
- yield Text(f"{spinner} {self.renderable}")
347
- else:
348
- yield Text(f"{self.renderable} {spinner}")
349
- else:
350
- if self.prefix:
351
- yield Text(f"{spinner} ") + self.renderable
352
- else:
353
- yield self.renderable + Text(f" {spinner}")
354
-
355
-
356
- RainbowPreset = Literal["classic", "bright", "pastel", "neon"]
357
-
358
- RAINBOW_PRESETS = {
359
- "classic": ["red", "yellow", "green", "cyan", "blue", "magenta"],
360
- "bright": [
361
- "bright_red",
362
- "bright_yellow",
363
- "bright_green",
364
- "bright_cyan",
365
- "bright_blue",
366
- "bright_magenta",
367
- ],
368
- "pastel": [
369
- "light_pink3",
370
- "khaki1",
371
- "light_green",
372
- "light_cyan1",
373
- "light_blue",
374
- "plum2",
375
- ],
376
- "neon": ["hot_pink", "yellow1", "green1", "cyan1", "blue1", "magenta1"],
377
- }
378
-
379
-
380
- class CLIRainbowAnimation(CLIAnimation):
381
- """Rainbow color cycling effect."""
382
-
383
- def __init__(
384
- self,
385
- renderable: "RenderableType",
386
- speed: float = 0.5,
387
- colors: "RainbowPreset | List[CLIStyleColorName] | None" = None,
388
- duration: Optional[float] = None,
389
- ):
390
- super().__init__(renderable, duration)
391
- self.speed = speed
392
-
393
- # Handle color selection
394
- if colors is None:
395
- colors = "classic"
396
-
397
- if isinstance(colors, str) and colors in RAINBOW_PRESETS:
398
- self.colors = RAINBOW_PRESETS[colors]
399
- elif isinstance(colors, list):
400
- self.colors = colors
401
- else:
402
- self.colors = RAINBOW_PRESETS["classic"]
403
-
404
- def apply(self, console: "Console", options: "ConsoleOptions") -> "RenderResult":
405
- if isinstance(self.renderable, str):
406
- # Apply rainbow to each character
407
- result = _get_rich_animation_classes()["Text"]()
408
- for i, char in enumerate(self.renderable):
409
- color_offset = int(
410
- (self.time_elapsed / self.speed + i) % len(self.colors)
411
- )
412
- color = self.colors[color_offset]
413
- result.append(char, style=color)
414
- yield result
415
- else:
416
- # Cycle through colors for the whole renderable
417
- color_index = int(self.time_elapsed / self.speed) % len(self.colors)
418
- yield Text.from_markup(
419
- f"[{self.colors[color_index]}]{self.renderable}[/{self.colors[color_index]}]"
420
- )
421
-
422
-
423
- def animate_flashing(
424
- renderable: "RenderableType",
425
- duration: Optional[float] = None,
426
- speed: float = 0.5,
427
- on_color: CLIStyleColorName = "white",
428
- off_color: CLIStyleColorName = "dim white",
429
- refresh_rate: int = 20,
430
- transient: bool = True,
431
- ) -> None:
432
- """Create and run a flashing animation on any renderable.
433
-
434
- Args:
435
- renderable: The object to animate (text, panel, etc.)
436
- duration: Duration of the animation in seconds (defaults to 2.0)
437
- speed: Speed of the flashing effect (defaults to 0.5)
438
- on_color: Color when flashing "on" (defaults to "white")
439
- off_color: Color when flashing "off" (defaults to "dim white")
440
- refresh_rate: Refresh rate per second (defaults to 20)
441
- transient: Whether to clear animation after completion (defaults to True)
442
-
443
- Examples:
444
- >>> animate_flashing("Alert!", duration=3.0, speed=0.3)
445
- >>> animate_flashing(Panel("Warning"), on_color="red", off_color="dark_red")
446
- """
447
- animation = CLIFlashingAnimation(
448
- renderable,
449
- duration=duration,
450
- speed=speed,
451
- on_color=on_color,
452
- off_color=off_color,
453
- )
454
- animation.animate(duration=duration, refresh_rate=refresh_rate)
455
-
456
-
457
- def animate_pulsing(
458
- renderable: "RenderableType",
459
- duration: Optional[float] = None,
460
- speed: float = 1.0,
461
- min_opacity: float = 0.3,
462
- max_opacity: float = 1.0,
463
- refresh_rate: int = 20,
464
- transient: bool = True,
465
- ) -> None:
466
- """Create and run a pulsing animation on any renderable.
467
-
468
- Args:
469
- renderable: The object to animate (text, panel, etc.)
470
- duration: Duration of the animation in seconds (defaults to 2.0)
471
- speed: Speed of the pulsing effect (defaults to 1.0)
472
- min_opacity: Minimum opacity during pulse (defaults to 0.3)
473
- max_opacity: Maximum opacity during pulse (defaults to 1.0)
474
- refresh_rate: Refresh rate per second (defaults to 20)
475
- transient: Whether to clear animation after completion (defaults to True)
476
-
477
- Examples:
478
- >>> animate_pulsing("Loading...", duration=5.0, speed=2.0)
479
- >>> animate_pulsing(Panel("Status"), min_opacity=0.1, max_opacity=0.9)
480
- """
481
- animation = CLIPulsingAnimation(
482
- renderable,
483
- duration=duration,
484
- speed=speed,
485
- min_opacity=min_opacity,
486
- max_opacity=max_opacity,
487
- )
488
- animation.animate(duration=duration, refresh_rate=refresh_rate)
489
-
490
-
491
- def animate_shaking(
492
- renderable: "RenderableType",
493
- duration: Optional[float] = None,
494
- intensity: int = 2,
495
- speed: float = 10.0,
496
- refresh_rate: int = 20,
497
- transient: bool = True,
498
- ) -> None:
499
- """Create and run a shaking animation on any renderable.
500
-
501
- Args:
502
- renderable: The object to animate (text, panel, etc.)
503
- duration: Duration of the animation in seconds (defaults to 2.0)
504
- intensity: Intensity of the shake effect (defaults to 2)
505
- speed: Speed of the shaking motion (defaults to 10.0)
506
- refresh_rate: Refresh rate per second (defaults to 20)
507
- transient: Whether to clear animation after completion (defaults to True)
508
-
509
- Examples:
510
- >>> animate_shaking("Error!", duration=1.5, intensity=3)
511
- >>> animate_shaking(Panel("Critical Alert"), speed=15.0)
512
- """
513
- animation = CLIShakingAnimation(
514
- renderable, duration=duration, intensity=intensity, speed=speed
515
- )
516
- animation.animate(duration=duration, refresh_rate=refresh_rate)
517
-
518
-
519
- def animate_spinning(
520
- renderable: "RenderableType",
521
- duration: Optional[float] = None,
522
- frames: Optional[List[str]] = None,
523
- speed: float = 0.1,
524
- prefix: bool = True,
525
- refresh_rate: int = 20,
526
- transient: bool = True,
527
- ) -> None:
528
- """Create and run a spinning animation on any renderable.
529
-
530
- Args:
531
- renderable: The object to animate (text, panel, etc.)
532
- duration: Duration of the animation in seconds (defaults to 2.0)
533
- frames: List of spinner frames (defaults to ["⋅", "•", "●", "◉", "●", "•"])
534
- speed: Speed between frame changes (defaults to 0.1)
535
- prefix: Whether to show spinner before text (defaults to True)
536
- refresh_rate: Refresh rate per second (defaults to 20)
537
- transient: Whether to clear animation after completion (defaults to True)
538
-
539
- Examples:
540
- >>> animate_spinning("Processing...", duration=10.0, speed=0.2)
541
- >>> animate_spinning("Done", frames=["◐", "◓", "◑", "◒"], prefix=False)
542
- """
543
- animation = CLISpinningAnimation(
544
- renderable, duration=duration, frames=frames, speed=speed, prefix=prefix
545
- )
546
- animation.animate(duration=duration, refresh_rate=refresh_rate)
547
-
548
-
549
- def animate_rainbow(
550
- renderable: "RenderableType",
551
- duration: Optional[float] = None,
552
- speed: float = 0.5,
553
- refresh_rate: int = 20,
554
- transient: bool = True,
555
- ) -> None:
556
- """Create and run a rainbow animation on any renderable.
557
-
558
- Args:
559
- renderable: The object to animate (text, panel, etc.)
560
- duration: Duration of the animation in seconds (defaults to 2.0)
561
- speed: Speed of the color cycling effect (defaults to 0.5)
562
- refresh_rate: Refresh rate per second (defaults to 20)
563
- transient: Whether to clear animation after completion (defaults to True)
564
-
565
- Examples:
566
- >>> animate_rainbow("Colorful Text!", duration=4.0, speed=1.0)
567
- >>> animate_rainbow(Panel("Rainbow Panel"), speed=0.3)
568
- """
569
- animation = CLIRainbowAnimation(renderable, duration=duration, speed=speed)
570
- animation.animate(duration=duration, refresh_rate=refresh_rate)
571
-
572
-
573
- def animate_typing(
574
- text: str,
575
- duration: Optional[float] = None,
576
- typing_speed: float = 0.05,
577
- cursor: str = "▌",
578
- show_cursor: bool = True,
579
- refresh_rate: int = 20,
580
- transient: bool = True,
581
- ) -> None:
582
- """Create and run a typewriter animation.
583
-
584
- Args:
585
- text: The text to type out
586
- duration: Duration of the animation in seconds (defaults to 2.0)
587
- typing_speed: Speed between character reveals (defaults to 0.05)
588
- cursor: Cursor character to show (defaults to "▌")
589
- show_cursor: Whether to show the typing cursor (defaults to True)
590
- refresh_rate: Refresh rate per second (defaults to 20)
591
- transient: Whether to clear animation after completion (defaults to True)
592
-
593
- Examples:
594
- >>> animate_typing("Hello, World!", typing_speed=0.1)
595
- >>> animate_typing("Fast typing", duration=1.0, cursor="|", show_cursor=False)
596
- """
597
- animation = CLITypingAnimation(
598
- text,
599
- duration=duration,
600
- typing_speed=typing_speed,
601
- cursor=cursor,
602
- show_cursor=show_cursor,
603
- )
604
- animation.animate(duration=duration, refresh_rate=refresh_rate)