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