hammad-python 0.0.10__py3-none-any.whl → 0.0.11__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 (74) hide show
  1. hammad/__init__.py +64 -10
  2. hammad/based/__init__.py +52 -0
  3. hammad/based/fields.py +546 -0
  4. hammad/based/model.py +968 -0
  5. hammad/based/utils.py +455 -0
  6. hammad/cache/__init__.py +30 -0
  7. hammad/{cache.py → cache/_cache.py} +83 -12
  8. hammad/cli/__init__.py +25 -0
  9. hammad/cli/plugins/__init__.py +786 -0
  10. hammad/cli/styles/__init__.py +5 -0
  11. hammad/cli/styles/animations.py +548 -0
  12. hammad/cli/styles/settings.py +135 -0
  13. hammad/cli/styles/types.py +358 -0
  14. hammad/cli/styles/utils.py +480 -0
  15. hammad/data/__init__.py +51 -0
  16. hammad/data/collections/__init__.py +32 -0
  17. hammad/data/collections/base_collection.py +58 -0
  18. hammad/data/collections/collection.py +227 -0
  19. hammad/data/collections/searchable_collection.py +556 -0
  20. hammad/data/collections/vector_collection.py +497 -0
  21. hammad/data/databases/__init__.py +21 -0
  22. hammad/data/databases/database.py +551 -0
  23. hammad/data/types/__init__.py +33 -0
  24. hammad/data/types/files/__init__.py +1 -0
  25. hammad/data/types/files/audio.py +81 -0
  26. hammad/data/types/files/configuration.py +475 -0
  27. hammad/data/types/files/document.py +195 -0
  28. hammad/data/types/files/file.py +358 -0
  29. hammad/data/types/files/image.py +80 -0
  30. hammad/json/__init__.py +21 -0
  31. hammad/{utils/json → json}/converters.py +4 -1
  32. hammad/logging/__init__.py +27 -0
  33. hammad/logging/decorators.py +432 -0
  34. hammad/logging/logger.py +534 -0
  35. hammad/pydantic/__init__.py +43 -0
  36. hammad/{utils/pydantic → pydantic}/converters.py +2 -1
  37. hammad/pydantic/models/__init__.py +28 -0
  38. hammad/pydantic/models/arbitrary_model.py +46 -0
  39. hammad/pydantic/models/cacheable_model.py +79 -0
  40. hammad/pydantic/models/fast_model.py +318 -0
  41. hammad/pydantic/models/function_model.py +176 -0
  42. hammad/pydantic/models/subscriptable_model.py +63 -0
  43. hammad/text/__init__.py +37 -0
  44. hammad/text/text.py +1068 -0
  45. hammad/text/utils/__init__.py +1 -0
  46. hammad/{utils/text → text/utils}/converters.py +2 -2
  47. hammad/text/utils/markdown/__init__.py +1 -0
  48. hammad/{utils → text/utils}/markdown/converters.py +3 -3
  49. hammad/{utils → text/utils}/markdown/formatting.py +1 -1
  50. hammad/{utils/typing/utils.py → typing/__init__.py} +75 -2
  51. hammad/web/__init__.py +42 -0
  52. hammad/web/http/__init__.py +1 -0
  53. hammad/web/http/client.py +944 -0
  54. hammad/web/openapi/client.py +740 -0
  55. hammad/web/search/__init__.py +1 -0
  56. hammad/web/search/client.py +936 -0
  57. hammad/web/utils.py +463 -0
  58. hammad/yaml/__init__.py +30 -0
  59. hammad/yaml/converters.py +19 -0
  60. {hammad_python-0.0.10.dist-info → hammad_python-0.0.11.dist-info}/METADATA +14 -8
  61. hammad_python-0.0.11.dist-info/RECORD +65 -0
  62. hammad/database.py +0 -447
  63. hammad/logger.py +0 -273
  64. hammad/types/color.py +0 -951
  65. hammad/utils/json/__init__.py +0 -0
  66. hammad/utils/markdown/__init__.py +0 -0
  67. hammad/utils/pydantic/__init__.py +0 -0
  68. hammad/utils/text/__init__.py +0 -0
  69. hammad/utils/typing/__init__.py +0 -0
  70. hammad_python-0.0.10.dist-info/RECORD +0 -22
  71. /hammad/{types/__init__.py → py.typed} +0 -0
  72. /hammad/{utils → web/openapi}/__init__.py +0 -0
  73. {hammad_python-0.0.10.dist-info → hammad_python-0.0.11.dist-info}/WHEEL +0 -0
  74. {hammad_python-0.0.10.dist-info → hammad_python-0.0.11.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,5 @@
1
+ """hammad.cli.styles
2
+
3
+ Contains resources, types and other utilities in context of
4
+ styling rendered content in the CLI. Most resources within this
5
+ submodule are not meant for direct use."""
@@ -0,0 +1,548 @@
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 .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
+ ) -> None:
137
+ """Animate this effect for the specified duration using Live."""
138
+ animate_duration = duration or self.duration or 3.0
139
+ rich_classes = _get_rich_animation_classes()
140
+ Console = rich_classes["Console"]
141
+ Live = rich_classes["Live"]
142
+ console = Console()
143
+
144
+ with Live(
145
+ self, console=console, refresh_per_second=refresh_rate, transient=True
146
+ ) as live:
147
+ start = time.time()
148
+ while time.time() - start < animate_duration:
149
+ time.sleep(0.05)
150
+
151
+
152
+ class CLIFlashingAnimation(CLIAnimation):
153
+ """Makes any renderable flash/blink."""
154
+
155
+ def __init__(
156
+ self,
157
+ renderable,
158
+ speed: float = 0.5,
159
+ colors: Optional[List[CLIStyleColorName]] = None,
160
+ duration: Optional[float] = None,
161
+ ):
162
+ super().__init__(renderable, duration)
163
+ self.speed = speed
164
+ self.colors = colors or [
165
+ "bright_white",
166
+ "bright_yellow",
167
+ "bright_cyan",
168
+ "bright_magenta",
169
+ ]
170
+
171
+ def apply(self, console, options):
172
+ rich_classes = _get_rich_animation_classes()
173
+ Text = rich_classes["Text"]
174
+
175
+ # Calculate which color to use based on time
176
+ color_index = int(self.time_elapsed / self.speed) % len(self.colors)
177
+ color = self.colors[color_index]
178
+
179
+ # Apply color to the renderable
180
+ if isinstance(self.renderable, str):
181
+ yield Text(self.renderable, style=color)
182
+ else:
183
+ # Wrap any renderable in the flash color
184
+ yield Text.from_markup(f"[{color}]{self.renderable}[/{color}]")
185
+
186
+
187
+ class CLIPulsingAnimation(CLIAnimation):
188
+ """Makes any renderable pulse/breathe."""
189
+
190
+ def __init__(
191
+ self,
192
+ renderable: "RenderableType",
193
+ speed: float = 2.0,
194
+ min_opacity: float = 0.3,
195
+ max_opacity: float = 1.0,
196
+ color: "CLIStyleColorName" = "white",
197
+ duration: Optional[float] = None,
198
+ ):
199
+ super().__init__(renderable, duration)
200
+ self.speed = speed
201
+ self.min_opacity = min_opacity
202
+ self.max_opacity = max_opacity
203
+ self.color = color
204
+
205
+ def apply(self, console: "Console", options: "ConsoleOptions") -> "RenderResult":
206
+ # Calculate opacity using sine wave
207
+ opacity = self.min_opacity + (self.max_opacity - self.min_opacity) * (
208
+ 0.5 + 0.5 * math.sin(self.time_elapsed * self.speed)
209
+ )
210
+
211
+ # Convert opacity to RGB values for fading effect
212
+ rgb_value = int(opacity * 255)
213
+ fade_color = f"rgb({rgb_value},{rgb_value},{rgb_value})"
214
+
215
+ if isinstance(self.renderable, str):
216
+ yield Text(self.renderable, style=fade_color)
217
+ else:
218
+ # For Panel and other renderables, we need to use opacity styling
219
+ if isinstance(self.renderable, Panel):
220
+ # Create a new panel with modified style
221
+ new_panel = Panel(
222
+ self.renderable.renderable,
223
+ title=self.renderable.title,
224
+ title_align=self.renderable.title_align,
225
+ subtitle=self.renderable.subtitle,
226
+ subtitle_align=self.renderable.subtitle_align,
227
+ box=self.renderable.box,
228
+ style=fade_color,
229
+ border_style=fade_color,
230
+ expand=self.renderable.expand,
231
+ padding=self.renderable.padding,
232
+ width=self.renderable.width,
233
+ height=self.renderable.height,
234
+ )
235
+ yield new_panel
236
+ else:
237
+ # For other renderables, wrap in a panel with the fade effect
238
+ yield Panel(self.renderable, style=fade_color, border_style=fade_color)
239
+
240
+
241
+ class CLIShakingAnimation(CLIAnimation):
242
+ """Makes text shake/jitter."""
243
+
244
+ def __init__(
245
+ self,
246
+ renderable: "RenderableType",
247
+ intensity: int = 1,
248
+ speed: float = 0.1,
249
+ duration: Optional[float] = None,
250
+ ):
251
+ super().__init__(renderable, duration)
252
+ self.intensity = intensity
253
+ self.speed = speed
254
+ self.last_shake = 0
255
+
256
+ def apply(self, console: "Console", options: "ConsoleOptions") -> "RenderResult":
257
+ if self.time_elapsed - self.last_shake > self.speed:
258
+ self.last_shake = self.time_elapsed
259
+
260
+ # Add random spaces for shake effect
261
+ shake = " " * random.randint(0, self.intensity)
262
+
263
+ if isinstance(self.renderable, str):
264
+ yield Text(shake + self.renderable)
265
+ else:
266
+ yield Text(shake) + self.renderable
267
+ else:
268
+ # Keep previous position
269
+ yield self.renderable
270
+
271
+
272
+ class CLITypingAnimation(CLIAnimation):
273
+ """Typewriter effect."""
274
+
275
+ def __init__(
276
+ self, text: str, speed: float = 0.05, duration: Optional[float] = None
277
+ ):
278
+ super().__init__(text, duration)
279
+ self.text = text
280
+ self.speed = speed
281
+
282
+ def apply(self, console: "Console", options: "ConsoleOptions") -> "RenderResult":
283
+ # Calculate how many characters to show
284
+ chars_to_show = int(self.time_elapsed / self.speed)
285
+ chars_to_show = min(chars_to_show, len(self.text))
286
+
287
+ yield Text(
288
+ self.text[:chars_to_show] + "█"
289
+ if chars_to_show < len(self.text)
290
+ else self.text
291
+ )
292
+
293
+
294
+ class CLISpinningAnimation(CLIAnimation):
295
+ """Spinner effect for any renderable."""
296
+
297
+ def __init__(
298
+ self,
299
+ renderable: "RenderableType",
300
+ frames: Optional[List[str]] = None,
301
+ speed: float = 0.1,
302
+ prefix: bool = True,
303
+ duration: Optional[float] = None,
304
+ ):
305
+ super().__init__(renderable, duration)
306
+ self.frames = frames or ["⋅", "•", "●", "◉", "●", "•"]
307
+ self.speed = speed
308
+ self.prefix = prefix
309
+
310
+ def apply(self, console: "Console", options: "ConsoleOptions") -> "RenderResult":
311
+ frame_index = int(self.time_elapsed / self.speed) % len(self.frames)
312
+ spinner = self.frames[frame_index]
313
+
314
+ if isinstance(self.renderable, str):
315
+ if self.prefix:
316
+ yield Text(f"{spinner} {self.renderable}")
317
+ else:
318
+ yield Text(f"{self.renderable} {spinner}")
319
+ else:
320
+ if self.prefix:
321
+ yield Text(f"{spinner} ") + self.renderable
322
+ else:
323
+ yield self.renderable + Text(f" {spinner}")
324
+
325
+
326
+ RainbowPreset = Literal["classic", "bright", "pastel", "neon"]
327
+
328
+ RAINBOW_PRESETS = {
329
+ "classic": ["red", "yellow", "green", "cyan", "blue", "magenta"],
330
+ "bright": [
331
+ "bright_red",
332
+ "bright_yellow",
333
+ "bright_green",
334
+ "bright_cyan",
335
+ "bright_blue",
336
+ "bright_magenta",
337
+ ],
338
+ "pastel": [
339
+ "light_pink3",
340
+ "khaki1",
341
+ "light_green",
342
+ "light_cyan1",
343
+ "light_blue",
344
+ "plum2",
345
+ ],
346
+ "neon": ["hot_pink", "yellow1", "green1", "cyan1", "blue1", "magenta1"],
347
+ }
348
+
349
+
350
+ class CLIRainbowAnimation(CLIAnimation):
351
+ """Rainbow color cycling effect."""
352
+
353
+ def __init__(
354
+ self,
355
+ renderable: "RenderableType",
356
+ speed: float = 0.5,
357
+ colors: "RainbowPreset | List[CLIStyleColorName] | None" = None,
358
+ duration: Optional[float] = None,
359
+ ):
360
+ super().__init__(renderable, duration)
361
+ self.speed = speed
362
+
363
+ # Handle color selection
364
+ if colors is None:
365
+ colors = "classic"
366
+
367
+ if isinstance(colors, str) and colors in RAINBOW_PRESETS:
368
+ self.colors = RAINBOW_PRESETS[colors]
369
+ elif isinstance(colors, list):
370
+ self.colors = colors
371
+ else:
372
+ self.colors = RAINBOW_PRESETS["classic"]
373
+
374
+ def apply(self, console: "Console", options: "ConsoleOptions") -> "RenderResult":
375
+ if isinstance(self.renderable, str):
376
+ # Apply rainbow to each character
377
+ result = _get_rich_animation_classes()["Text"]()
378
+ for i, char in enumerate(self.renderable):
379
+ color_offset = int(
380
+ (self.time_elapsed / self.speed + i) % len(self.colors)
381
+ )
382
+ color = self.colors[color_offset]
383
+ result.append(char, style=color)
384
+ yield result
385
+ else:
386
+ # Cycle through colors for the whole renderable
387
+ color_index = int(self.time_elapsed / self.speed) % len(self.colors)
388
+ yield Text.from_markup(
389
+ f"[{self.colors[color_index]}]{self.renderable}[/{self.colors[color_index]}]"
390
+ )
391
+
392
+
393
+ def animate_flashing(
394
+ renderable: "RenderableType",
395
+ duration: Optional[float] = None,
396
+ speed: float = 0.5,
397
+ on_color: CLIStyleColorName = "white",
398
+ off_color: CLIStyleColorName = "dim white",
399
+ ) -> None:
400
+ """Create and run a flashing animation on any renderable.
401
+
402
+ Args:
403
+ renderable: The object to animate (text, panel, etc.)
404
+ duration: Duration of the animation in seconds (defaults to 2.0)
405
+ speed: Speed of the flashing effect (defaults to 0.5)
406
+ on_color: Color when flashing "on" (defaults to "white")
407
+ off_color: Color when flashing "off" (defaults to "dim white")
408
+
409
+ Examples:
410
+ >>> animate_flashing("Alert!", duration=3.0, speed=0.3)
411
+ >>> animate_flashing(Panel("Warning"), on_color="red", off_color="dark_red")
412
+ """
413
+ animation = CLIFlashingAnimation(
414
+ renderable,
415
+ duration=duration,
416
+ speed=speed,
417
+ on_color=on_color,
418
+ off_color=off_color,
419
+ )
420
+ animation.animate()
421
+
422
+
423
+ def animate_pulsing(
424
+ renderable: "RenderableType",
425
+ duration: Optional[float] = None,
426
+ speed: float = 1.0,
427
+ min_opacity: float = 0.3,
428
+ max_opacity: float = 1.0,
429
+ ) -> None:
430
+ """Create and run a pulsing animation on any renderable.
431
+
432
+ Args:
433
+ renderable: The object to animate (text, panel, etc.)
434
+ duration: Duration of the animation in seconds (defaults to 2.0)
435
+ speed: Speed of the pulsing effect (defaults to 1.0)
436
+ min_opacity: Minimum opacity during pulse (defaults to 0.3)
437
+ max_opacity: Maximum opacity during pulse (defaults to 1.0)
438
+
439
+ Examples:
440
+ >>> animate_pulsing("Loading...", duration=5.0, speed=2.0)
441
+ >>> animate_pulsing(Panel("Status"), min_opacity=0.1, max_opacity=0.9)
442
+ """
443
+ animation = CLIPulsingAnimation(
444
+ renderable,
445
+ duration=duration,
446
+ speed=speed,
447
+ min_opacity=min_opacity,
448
+ max_opacity=max_opacity,
449
+ )
450
+ animation.animate()
451
+
452
+
453
+ def animate_shaking(
454
+ renderable: "RenderableType",
455
+ duration: Optional[float] = None,
456
+ intensity: int = 2,
457
+ speed: float = 10.0,
458
+ ) -> None:
459
+ """Create and run a shaking animation on any renderable.
460
+
461
+ Args:
462
+ renderable: The object to animate (text, panel, etc.)
463
+ duration: Duration of the animation in seconds (defaults to 2.0)
464
+ intensity: Intensity of the shake effect (defaults to 2)
465
+ speed: Speed of the shaking motion (defaults to 10.0)
466
+
467
+ Examples:
468
+ >>> animate_shaking("Error!", duration=1.5, intensity=3)
469
+ >>> animate_shaking(Panel("Critical Alert"), speed=15.0)
470
+ """
471
+ animation = CLIShakingAnimation(
472
+ renderable, duration=duration, intensity=intensity, speed=speed
473
+ )
474
+ animation.animate()
475
+
476
+
477
+ def animate_spinning(
478
+ renderable: "RenderableType",
479
+ duration: Optional[float] = None,
480
+ frames: Optional[List[str]] = None,
481
+ speed: float = 0.1,
482
+ prefix: bool = True,
483
+ ) -> None:
484
+ """Create and run a spinning animation on any renderable.
485
+
486
+ Args:
487
+ renderable: The object to animate (text, panel, etc.)
488
+ duration: Duration of the animation in seconds (defaults to 2.0)
489
+ frames: List of spinner frames (defaults to ["⋅", "•", "●", "◉", "●", "•"])
490
+ speed: Speed between frame changes (defaults to 0.1)
491
+ prefix: Whether to show spinner before text (defaults to True)
492
+
493
+ Examples:
494
+ >>> animate_spinning("Processing...", duration=10.0, speed=0.2)
495
+ >>> animate_spinning("Done", frames=["◐", "◓", "◑", "◒"], prefix=False)
496
+ """
497
+ animation = CLISpinningAnimation(
498
+ renderable, duration=duration, frames=frames, speed=speed, prefix=prefix
499
+ )
500
+ animation.animate()
501
+
502
+
503
+ def animate_rainbow(
504
+ renderable: "RenderableType", duration: Optional[float] = None, speed: float = 0.5
505
+ ) -> None:
506
+ """Create and run a rainbow animation on any renderable.
507
+
508
+ Args:
509
+ renderable: The object to animate (text, panel, etc.)
510
+ duration: Duration of the animation in seconds (defaults to 2.0)
511
+ speed: Speed of the color cycling effect (defaults to 0.5)
512
+
513
+ Examples:
514
+ >>> animate_rainbow("Colorful Text!", duration=4.0, speed=1.0)
515
+ >>> animate_rainbow(Panel("Rainbow Panel"), speed=0.3)
516
+ """
517
+ animation = CLIRainbowAnimation(renderable, duration=duration, speed=speed)
518
+ animation.animate()
519
+
520
+
521
+ def animate_typing(
522
+ text: str,
523
+ duration: Optional[float] = None,
524
+ typing_speed: float = 0.05,
525
+ cursor: str = "▌",
526
+ show_cursor: bool = True,
527
+ ) -> None:
528
+ """Create and run a typewriter animation.
529
+
530
+ Args:
531
+ text: The text to type out
532
+ duration: Duration of the animation in seconds (defaults to 2.0)
533
+ typing_speed: Speed between character reveals (defaults to 0.05)
534
+ cursor: Cursor character to show (defaults to "▌")
535
+ show_cursor: Whether to show the typing cursor (defaults to True)
536
+
537
+ Examples:
538
+ >>> animate_typing("Hello, World!", typing_speed=0.1)
539
+ >>> animate_typing("Fast typing", duration=1.0, cursor="|", show_cursor=False)
540
+ """
541
+ animation = CLITypingAnimation(
542
+ text,
543
+ duration=duration,
544
+ typing_speed=typing_speed,
545
+ cursor=cursor,
546
+ show_cursor=show_cursor,
547
+ )
548
+ animation.animate()
@@ -0,0 +1,135 @@
1
+ """hammad.cli.styles.settings"""
2
+
3
+ from typing import Any
4
+ from typing_extensions import TypedDict, NotRequired
5
+
6
+ from .types import (
7
+ CLIStyleBoxName,
8
+ CLIStyleJustifyMethod,
9
+ CLIStyleOverflowMethod,
10
+ CLIStyleVerticalOverflowMethod,
11
+ )
12
+
13
+ __all__ = (
14
+ "CLIStyleRenderableSettings",
15
+ "CLIStyleBackgroundSettings",
16
+ "CLIStyleLiveSettings",
17
+ )
18
+
19
+
20
+ class CLIStyleRenderableSettings(TypedDict, total=False):
21
+ """Extended dictionary definition of settings that can be
22
+ applied to style various renderable content. These settings
23
+ extend the settings within `rich.text.Text` and
24
+ `rich.style.Style`.
25
+
26
+ When using various stylable modules in the `hammad` package,
27
+ you can either define the `style` parameter with a rich string
28
+ tag with a color / style name. or apply the `style_settings`
29
+ parameter with these settings."""
30
+
31
+ # rich.text
32
+
33
+ justify: NotRequired[CLIStyleJustifyMethod]
34
+ """The justification of the renderable output or content."""
35
+ overflow: NotRequired[CLIStyleOverflowMethod | int]
36
+ """The overflow method of the renderable output or content."""
37
+ no_wrap: NotRequired[bool]
38
+ """Whether the renderable output or content should be wrapped."""
39
+ end: NotRequired[str]
40
+ """The end character of the renderable output or content."""
41
+ tab_size: NotRequired[int]
42
+ """The tab size of the renderable output or content."""
43
+ spans: NotRequired[list[Any]]
44
+ """The spans of the renderable output or content."""
45
+
46
+ # rich.style
47
+
48
+ bold: NotRequired[bool]
49
+ """Whether the renderable output or content should be bold."""
50
+ dim: NotRequired[bool]
51
+ """Whether the renderable output or content should be dimmed."""
52
+ italic: NotRequired[bool]
53
+ """Whether the renderable output or content should be italicized."""
54
+ underline: NotRequired[bool]
55
+ """Whether the renderable output or content should be underlined."""
56
+ blink: NotRequired[bool]
57
+ """Whether the renderable output or content should blink."""
58
+ blink2: NotRequired[bool]
59
+ """Whether the renderable output or content should blink twice."""
60
+ reverse: NotRequired[bool]
61
+ """Whether the renderable output or content should be reversed."""
62
+ conceal: NotRequired[bool]
63
+ """Whether the renderable output or content should be concealed."""
64
+ strike: NotRequired[bool]
65
+ """Whether the renderable output or content should be struck through."""
66
+ underline2: NotRequired[bool]
67
+ """Whether the renderable output or content should be underlined twice."""
68
+ frame: NotRequired[bool]
69
+ """Whether the renderable output or content should be framed."""
70
+ encircle: NotRequired[bool]
71
+ """Whether the renderable output or content should be encircled."""
72
+ overline: NotRequired[bool]
73
+ """Whether the renderable output or content should be overlined."""
74
+ link: NotRequired[str]
75
+ """The link to be applied to the renderable output or content."""
76
+
77
+
78
+ class CLIStyleBackgroundSettings(TypedDict, total=False):
79
+ """Extended dictionary definition of settings that can be
80
+ applied to style various background content. These settings
81
+ extend the settings within `rich.box.Box` and `rich.panel.Panel`.
82
+
83
+ When using various stylable modules in the `hammad` package,
84
+ you can either define the `bg` parameter with a rich string
85
+ tag with a color / style name. or apply the `bg_settings`
86
+ parameter with these settings."""
87
+
88
+ box: NotRequired[CLIStyleBoxName]
89
+ """The box style to be applied to the background."""
90
+ title: NotRequired[str]
91
+ """The title of the background."""
92
+ subtitle: NotRequired[str]
93
+ """The subtitle of the background."""
94
+ title_align: NotRequired[CLIStyleJustifyMethod]
95
+ """The alignment of the title."""
96
+ subtitle_align: NotRequired[CLIStyleJustifyMethod]
97
+ """The alignment of the subtitle."""
98
+ safe_box: NotRequired[bool]
99
+ """Whether the box should be safe."""
100
+ expand: NotRequired[bool]
101
+ """Whether the box should be expanded."""
102
+ style: NotRequired[CLIStyleRenderableSettings]
103
+ """The style of the background."""
104
+ border_style: NotRequired[CLIStyleRenderableSettings]
105
+ """The style of the border."""
106
+ width: NotRequired[int]
107
+ """The width of the background."""
108
+ height: NotRequired[int]
109
+ """The height of the background."""
110
+ padding: NotRequired[int]
111
+ """The padding of the background."""
112
+ highlight: NotRequired[bool]
113
+ """Whether the background should be highlighted."""
114
+
115
+
116
+ class CLIStyleLiveSettings(TypedDict, total=False):
117
+ """Dictionary definition of settings for content rendered
118
+ with `rich.live.Live`."""
119
+
120
+ screen: NotRequired[bool]
121
+ """Whether the live renderable should be displayed in a screen."""
122
+ duration: NotRequired[float]
123
+ """The duration of the live renderable."""
124
+ refresh_rate: NotRequired[int]
125
+ """The refresh rate of the live renderable."""
126
+ auto_refresh: NotRequired[bool]
127
+ """Whether the live renderable should be automatically refreshed."""
128
+ transient: NotRequired[bool]
129
+ """Whether the live renderable should be transient."""
130
+ redirect_stdout: NotRequired[bool]
131
+ """Whether the live renderable should redirect stdout."""
132
+ redirect_stderr: NotRequired[bool]
133
+ """Whether the live renderable should redirect stderr."""
134
+ vertical_overflow: NotRequired[CLIStyleVerticalOverflowMethod]
135
+ """The vertical overflow method of the live renderable."""