pycaps-ai 0.2.1__tar.gz

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 (194) hide show
  1. pycaps_ai-0.2.1/LICENSE +21 -0
  2. pycaps_ai-0.2.1/MANIFEST.in +4 -0
  3. pycaps_ai-0.2.1/PKG-INFO +225 -0
  4. pycaps_ai-0.2.1/README.md +175 -0
  5. pycaps_ai-0.2.1/pyproject.toml +76 -0
  6. pycaps_ai-0.2.1/setup.cfg +4 -0
  7. pycaps_ai-0.2.1/src/pycaps/__init__.py +13 -0
  8. pycaps_ai-0.2.1/src/pycaps/ai/__init__.py +5 -0
  9. pycaps_ai-0.2.1/src/pycaps/ai/gpt.py +35 -0
  10. pycaps_ai-0.2.1/src/pycaps/ai/llm.py +11 -0
  11. pycaps_ai-0.2.1/src/pycaps/ai/llm_provider.py +16 -0
  12. pycaps_ai-0.2.1/src/pycaps/animation/__init__.py +31 -0
  13. pycaps_ai-0.2.1/src/pycaps/animation/animation.py +11 -0
  14. pycaps_ai-0.2.1/src/pycaps/animation/builtin/__init__.py +18 -0
  15. pycaps_ai-0.2.1/src/pycaps/animation/builtin/preset/__init__.py +21 -0
  16. pycaps_ai-0.2.1/src/pycaps/animation/builtin/preset/fade_in.py +17 -0
  17. pycaps_ai-0.2.1/src/pycaps/animation/builtin/preset/fade_out.py +19 -0
  18. pycaps_ai-0.2.1/src/pycaps/animation/builtin/preset/pop_in.py +22 -0
  19. pycaps_ai-0.2.1/src/pycaps/animation/builtin/preset/pop_in_bounce.py +20 -0
  20. pycaps_ai-0.2.1/src/pycaps/animation/builtin/preset/pop_out.py +22 -0
  21. pycaps_ai-0.2.1/src/pycaps/animation/builtin/preset/slide_in.py +25 -0
  22. pycaps_ai-0.2.1/src/pycaps/animation/builtin/preset/slide_out.py +26 -0
  23. pycaps_ai-0.2.1/src/pycaps/animation/builtin/preset/zoom_in.py +24 -0
  24. pycaps_ai-0.2.1/src/pycaps/animation/builtin/preset/zoom_out.py +25 -0
  25. pycaps_ai-0.2.1/src/pycaps/animation/builtin/primitive/__init__.py +11 -0
  26. pycaps_ai-0.2.1/src/pycaps/animation/builtin/primitive/fade_in_primitive.py +6 -0
  27. pycaps_ai-0.2.1/src/pycaps/animation/builtin/primitive/pop_in_primitive.py +64 -0
  28. pycaps_ai-0.2.1/src/pycaps/animation/builtin/primitive/slide_in_primitive.py +54 -0
  29. pycaps_ai-0.2.1/src/pycaps/animation/builtin/primitive/zoom_in_primitive.py +64 -0
  30. pycaps_ai-0.2.1/src/pycaps/animation/definitions.py +22 -0
  31. pycaps_ai-0.2.1/src/pycaps/animation/element_animator.py +52 -0
  32. pycaps_ai-0.2.1/src/pycaps/animation/preset_animation.py +16 -0
  33. pycaps_ai-0.2.1/src/pycaps/animation/primitive_animation.py +89 -0
  34. pycaps_ai-0.2.1/src/pycaps/api/__init__.py +3 -0
  35. pycaps_ai-0.2.1/src/pycaps/api/api_key_service.py +21 -0
  36. pycaps_ai-0.2.1/src/pycaps/api/api_sender.py +53 -0
  37. pycaps_ai-0.2.1/src/pycaps/api/emoji_in_segments_api.py +42 -0
  38. pycaps_ai-0.2.1/src/pycaps/api/pycaps_tagger_api.py +24 -0
  39. pycaps_ai-0.2.1/src/pycaps/bootstrap.py +35 -0
  40. pycaps_ai-0.2.1/src/pycaps/cli/__init__.py +1 -0
  41. pycaps_ai-0.2.1/src/pycaps/cli/cli.py +23 -0
  42. pycaps_ai-0.2.1/src/pycaps/cli/config_cli.py +25 -0
  43. pycaps_ai-0.2.1/src/pycaps/cli/preview_styles_cli.py +30 -0
  44. pycaps_ai-0.2.1/src/pycaps/cli/render_cli.py +103 -0
  45. pycaps_ai-0.2.1/src/pycaps/cli/template_cli.py +39 -0
  46. pycaps_ai-0.2.1/src/pycaps/common/__init__.py +43 -0
  47. pycaps_ai-0.2.1/src/pycaps/common/config_service.py +50 -0
  48. pycaps_ai-0.2.1/src/pycaps/common/element_container.py +48 -0
  49. pycaps_ai-0.2.1/src/pycaps/common/models.py +298 -0
  50. pycaps_ai-0.2.1/src/pycaps/common/types.py +63 -0
  51. pycaps_ai-0.2.1/src/pycaps/effect/__init__.py +22 -0
  52. pycaps_ai-0.2.1/src/pycaps/effect/clip/__init__.py +9 -0
  53. pycaps_ai-0.2.1/src/pycaps/effect/clip/animate_segment_emojis_effect.py +105 -0
  54. pycaps_ai-0.2.1/src/pycaps/effect/clip/clip_effect.py +6 -0
  55. pycaps_ai-0.2.1/src/pycaps/effect/clip/typewriting_effect.py +54 -0
  56. pycaps_ai-0.2.1/src/pycaps/effect/effect.py +5 -0
  57. pycaps_ai-0.2.1/src/pycaps/effect/sound/__init__.py +5 -0
  58. pycaps_ai-0.2.1/src/pycaps/effect/sound/builtin_sound.py +42 -0
  59. pycaps_ai-0.2.1/src/pycaps/effect/sound/presets/click-light.mp3 +0 -0
  60. pycaps_ai-0.2.1/src/pycaps/effect/sound/presets/click.mp3 +0 -0
  61. pycaps_ai-0.2.1/src/pycaps/effect/sound/presets/ding-long.mp3 +0 -0
  62. pycaps_ai-0.2.1/src/pycaps/effect/sound/presets/ding-short.mp3 +0 -0
  63. pycaps_ai-0.2.1/src/pycaps/effect/sound/presets/ding.mp3 +0 -0
  64. pycaps_ai-0.2.1/src/pycaps/effect/sound/presets/glitch-static.mp3 +0 -0
  65. pycaps_ai-0.2.1/src/pycaps/effect/sound/presets/glitch.mp3 +0 -0
  66. pycaps_ai-0.2.1/src/pycaps/effect/sound/presets/heart-beat.mp3 +0 -0
  67. pycaps_ai-0.2.1/src/pycaps/effect/sound/presets/hit-intense.mp3 +0 -0
  68. pycaps_ai-0.2.1/src/pycaps/effect/sound/presets/hit-strong.mp3 +0 -0
  69. pycaps_ai-0.2.1/src/pycaps/effect/sound/presets/pop-2.mp3 +0 -0
  70. pycaps_ai-0.2.1/src/pycaps/effect/sound/presets/pop.mp3 +0 -0
  71. pycaps_ai-0.2.1/src/pycaps/effect/sound/presets/slide-paper.mp3 +0 -0
  72. pycaps_ai-0.2.1/src/pycaps/effect/sound/presets/swoosh.mp3 +0 -0
  73. pycaps_ai-0.2.1/src/pycaps/effect/sound/presets/whoosh-2.mp3 +0 -0
  74. pycaps_ai-0.2.1/src/pycaps/effect/sound/presets/whoosh-deep.mp3 +0 -0
  75. pycaps_ai-0.2.1/src/pycaps/effect/sound/presets/whoosh.mp3 +0 -0
  76. pycaps_ai-0.2.1/src/pycaps/effect/sound/sound.py +15 -0
  77. pycaps_ai-0.2.1/src/pycaps/effect/sound/sound_effect.py +74 -0
  78. pycaps_ai-0.2.1/src/pycaps/effect/text/__init__.py +14 -0
  79. pycaps_ai-0.2.1/src/pycaps/effect/text/emoji_in_segment_effect.py +88 -0
  80. pycaps_ai-0.2.1/src/pycaps/effect/text/emoji_in_segment_getter.py +34 -0
  81. pycaps_ai-0.2.1/src/pycaps/effect/text/emoji_in_segment_llm_getter.py +38 -0
  82. pycaps_ai-0.2.1/src/pycaps/effect/text/emoji_in_word_effect.py +43 -0
  83. pycaps_ai-0.2.1/src/pycaps/effect/text/modify_words_effect.py +26 -0
  84. pycaps_ai-0.2.1/src/pycaps/effect/text/remove_punctuation_marks_effect.py +41 -0
  85. pycaps_ai-0.2.1/src/pycaps/effect/text/text_effect.py +4 -0
  86. pycaps_ai-0.2.1/src/pycaps/layout/__init__.py +19 -0
  87. pycaps_ai-0.2.1/src/pycaps/layout/definitions.py +61 -0
  88. pycaps_ai-0.2.1/src/pycaps/layout/layout_updater.py +55 -0
  89. pycaps_ai-0.2.1/src/pycaps/layout/layout_utils.py +38 -0
  90. pycaps_ai-0.2.1/src/pycaps/layout/line_splitter.py +75 -0
  91. pycaps_ai-0.2.1/src/pycaps/layout/positions_calculator.py +105 -0
  92. pycaps_ai-0.2.1/src/pycaps/layout/word_size_calculator.py +19 -0
  93. pycaps_ai-0.2.1/src/pycaps/logger.py +50 -0
  94. pycaps_ai-0.2.1/src/pycaps/pipeline/__init__.py +9 -0
  95. pycaps_ai-0.2.1/src/pycaps/pipeline/caps_pipeline.py +290 -0
  96. pycaps_ai-0.2.1/src/pycaps/pipeline/caps_pipeline_builder.py +137 -0
  97. pycaps_ai-0.2.1/src/pycaps/pipeline/json_config_loader.py +231 -0
  98. pycaps_ai-0.2.1/src/pycaps/pipeline/json_schema.py +181 -0
  99. pycaps_ai-0.2.1/src/pycaps/pipeline/subtitle_data_service.py +14 -0
  100. pycaps_ai-0.2.1/src/pycaps/renderer/__init__.py +13 -0
  101. pycaps_ai-0.2.1/src/pycaps/renderer/css_subtitle_renderer.py +296 -0
  102. pycaps_ai-0.2.1/src/pycaps/renderer/letter_size_cache.py +26 -0
  103. pycaps_ai-0.2.1/src/pycaps/renderer/pictex_subtitle_renderer.py +147 -0
  104. pycaps_ai-0.2.1/src/pycaps/renderer/playwright_screenshot_capturer.py +38 -0
  105. pycaps_ai-0.2.1/src/pycaps/renderer/previewer/__init__.py +3 -0
  106. pycaps_ai-0.2.1/src/pycaps/renderer/previewer/css_subtitle_previewer.py +52 -0
  107. pycaps_ai-0.2.1/src/pycaps/renderer/previewer/previewer.html +340 -0
  108. pycaps_ai-0.2.1/src/pycaps/renderer/rendered_image_cache.py +35 -0
  109. pycaps_ai-0.2.1/src/pycaps/renderer/renderer_page.py +80 -0
  110. pycaps_ai-0.2.1/src/pycaps/renderer/subtitle_renderer.py +36 -0
  111. pycaps_ai-0.2.1/src/pycaps/selector/__init__.py +11 -0
  112. pycaps_ai-0.2.1/src/pycaps/selector/tag_based_selector.py +17 -0
  113. pycaps_ai-0.2.1/src/pycaps/selector/time_event_selector.py +72 -0
  114. pycaps_ai-0.2.1/src/pycaps/selector/word_clip_selector.py +31 -0
  115. pycaps_ai-0.2.1/src/pycaps/tag/__init__.py +11 -0
  116. pycaps_ai-0.2.1/src/pycaps/tag/definitions.py +19 -0
  117. pycaps_ai-0.2.1/src/pycaps/tag/tag_condition.py +113 -0
  118. pycaps_ai-0.2.1/src/pycaps/tag/tagger/__init__.py +7 -0
  119. pycaps_ai-0.2.1/src/pycaps/tag/tagger/ai_tagger.py +28 -0
  120. pycaps_ai-0.2.1/src/pycaps/tag/tagger/external_llm_tagger.py +76 -0
  121. pycaps_ai-0.2.1/src/pycaps/tag/tagger/semantic_tagger.py +114 -0
  122. pycaps_ai-0.2.1/src/pycaps/tag/tagger/structure_tagger.py +51 -0
  123. pycaps_ai-0.2.1/src/pycaps/template/__init__.py +17 -0
  124. pycaps_ai-0.2.1/src/pycaps/template/builtin_template.py +10 -0
  125. pycaps_ai-0.2.1/src/pycaps/template/constants.py +3 -0
  126. pycaps_ai-0.2.1/src/pycaps/template/local_template.py +8 -0
  127. pycaps_ai-0.2.1/src/pycaps/template/preset/classic/pycaps.template.json +3 -0
  128. pycaps_ai-0.2.1/src/pycaps/template/preset/classic/styles.css +10 -0
  129. pycaps_ai-0.2.1/src/pycaps/template/preset/default/pycaps.template.json +16 -0
  130. pycaps_ai-0.2.1/src/pycaps/template/preset/default/resources/black.ttf +0 -0
  131. pycaps_ai-0.2.1/src/pycaps/template/preset/default/styles.css +16 -0
  132. pycaps_ai-0.2.1/src/pycaps/template/preset/explosive/pycaps.template.json +66 -0
  133. pycaps_ai-0.2.1/src/pycaps/template/preset/explosive/resources/black.ttf +0 -0
  134. pycaps_ai-0.2.1/src/pycaps/template/preset/explosive/styles.css +44 -0
  135. pycaps_ai-0.2.1/src/pycaps/template/preset/fast/pycaps.template.json +21 -0
  136. pycaps_ai-0.2.1/src/pycaps/template/preset/fast/styles.css +15 -0
  137. pycaps_ai-0.2.1/src/pycaps/template/preset/hype/pycaps.template.json +65 -0
  138. pycaps_ai-0.2.1/src/pycaps/template/preset/hype/resources/komika.ttf +0 -0
  139. pycaps_ai-0.2.1/src/pycaps/template/preset/hype/styles.css +26 -0
  140. pycaps_ai-0.2.1/src/pycaps/template/preset/line-focus/pycaps.template.json +29 -0
  141. pycaps_ai-0.2.1/src/pycaps/template/preset/line-focus/resources/black.ttf +0 -0
  142. pycaps_ai-0.2.1/src/pycaps/template/preset/line-focus/styles.css +32 -0
  143. pycaps_ai-0.2.1/src/pycaps/template/preset/minimalist/pycaps.template.json +33 -0
  144. pycaps_ai-0.2.1/src/pycaps/template/preset/minimalist/styles.css +26 -0
  145. pycaps_ai-0.2.1/src/pycaps/template/preset/model/main.py +0 -0
  146. pycaps_ai-0.2.1/src/pycaps/template/preset/model/preview.hash +4 -0
  147. pycaps_ai-0.2.1/src/pycaps/template/preset/model/pycaps.template.json +0 -0
  148. pycaps_ai-0.2.1/src/pycaps/template/preset/model/styles.css +0 -0
  149. pycaps_ai-0.2.1/src/pycaps/template/preset/neo-minimal/pycaps.template.json +44 -0
  150. pycaps_ai-0.2.1/src/pycaps/template/preset/neo-minimal/styles.css +46 -0
  151. pycaps_ai-0.2.1/src/pycaps/template/preset/retro-gaming/pycaps.template.json +48 -0
  152. pycaps_ai-0.2.1/src/pycaps/template/preset/retro-gaming/resources/PressStart2P.ttf +0 -0
  153. pycaps_ai-0.2.1/src/pycaps/template/preset/retro-gaming/styles.css +29 -0
  154. pycaps_ai-0.2.1/src/pycaps/template/preset/vibrant/pycaps.template.json +57 -0
  155. pycaps_ai-0.2.1/src/pycaps/template/preset/vibrant/resources/black.ttf +0 -0
  156. pycaps_ai-0.2.1/src/pycaps/template/preset/vibrant/styles.css +34 -0
  157. pycaps_ai-0.2.1/src/pycaps/template/preset/word-focus/pycaps.template.json +29 -0
  158. pycaps_ai-0.2.1/src/pycaps/template/preset/word-focus/resources/black.ttf +0 -0
  159. pycaps_ai-0.2.1/src/pycaps/template/preset/word-focus/styles.css +22 -0
  160. pycaps_ai-0.2.1/src/pycaps/template/template.py +14 -0
  161. pycaps_ai-0.2.1/src/pycaps/template/template_factory.py +17 -0
  162. pycaps_ai-0.2.1/src/pycaps/template/template_loader.py +31 -0
  163. pycaps_ai-0.2.1/src/pycaps/template/template_service.py +21 -0
  164. pycaps_ai-0.2.1/src/pycaps/transcriber/__init__.py +23 -0
  165. pycaps_ai-0.2.1/src/pycaps/transcriber/base_transcriber.py +18 -0
  166. pycaps_ai-0.2.1/src/pycaps/transcriber/editor/__init__.py +3 -0
  167. pycaps_ai-0.2.1/src/pycaps/transcriber/editor/editor.html +731 -0
  168. pycaps_ai-0.2.1/src/pycaps/transcriber/editor/transcription_editor.py +54 -0
  169. pycaps_ai-0.2.1/src/pycaps/transcriber/google_audio_transcriber.py +103 -0
  170. pycaps_ai-0.2.1/src/pycaps/transcriber/preview_transcriber.py +29 -0
  171. pycaps_ai-0.2.1/src/pycaps/transcriber/splitter/__init__.py +12 -0
  172. pycaps_ai-0.2.1/src/pycaps/transcriber/splitter/base_segment_splitter.py +12 -0
  173. pycaps_ai-0.2.1/src/pycaps/transcriber/splitter/limit_by_chars_splitter.py +87 -0
  174. pycaps_ai-0.2.1/src/pycaps/transcriber/splitter/limit_by_words_splitter.py +45 -0
  175. pycaps_ai-0.2.1/src/pycaps/transcriber/splitter/split_into_sentences_splitter.py +33 -0
  176. pycaps_ai-0.2.1/src/pycaps/transcriber/transcript_format.py +9 -0
  177. pycaps_ai-0.2.1/src/pycaps/transcriber/transcript_loader.py +383 -0
  178. pycaps_ai-0.2.1/src/pycaps/transcriber/whisper_audio_transcriber.py +88 -0
  179. pycaps_ai-0.2.1/src/pycaps/utils/__init__.py +7 -0
  180. pycaps_ai-0.2.1/src/pycaps/utils/script_utils.py +30 -0
  181. pycaps_ai-0.2.1/src/pycaps/utils/time_utils.py +3 -0
  182. pycaps_ai-0.2.1/src/pycaps/video/__init__.py +7 -0
  183. pycaps_ai-0.2.1/src/pycaps/video/audio_utils.py +29 -0
  184. pycaps_ai-0.2.1/src/pycaps/video/subtitle_clips_generator.py +103 -0
  185. pycaps_ai-0.2.1/src/pycaps/video/video_generator.py +128 -0
  186. pycaps_ai-0.2.1/src/pycaps_ai.egg-info/PKG-INFO +225 -0
  187. pycaps_ai-0.2.1/src/pycaps_ai.egg-info/SOURCES.txt +192 -0
  188. pycaps_ai-0.2.1/src/pycaps_ai.egg-info/dependency_links.txt +1 -0
  189. pycaps_ai-0.2.1/src/pycaps_ai.egg-info/entry_points.txt +2 -0
  190. pycaps_ai-0.2.1/src/pycaps_ai.egg-info/requires.txt +25 -0
  191. pycaps_ai-0.2.1/src/pycaps_ai.egg-info/top_level.txt +1 -0
  192. pycaps_ai-0.2.1/tests/test_pipeline_transcription_path.py +77 -0
  193. pycaps_ai-0.2.1/tests/test_render_cli_transcript_flags.py +119 -0
  194. pycaps_ai-0.2.1/tests/test_transcript_loader.py +133 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Franco Zanardi
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,4 @@
1
+ graft src/pycaps/effect/sound/presets
2
+ graft src/pycaps/template/preset
3
+ include src/pycaps/renderer/previewer/previewer.html
4
+ include src/pycaps/transcriber/editor/editor.html
@@ -0,0 +1,225 @@
1
+ Metadata-Version: 2.4
2
+ Name: pycaps-ai
3
+ Version: 0.2.1
4
+ Summary: A Python tool to edit videos and automatically add CSS-styled subtitles to videos.
5
+ Author-email: Aleef Bilal <aleefbilal@gmail.com>
6
+ Maintainer-email: Aleef Bilal <aleefbilal@gmail.com>
7
+ License: MIT License
8
+ Project-URL: Homepage, https://github.com/AleefBilal/pycaps
9
+ Project-URL: Repository, https://github.com/AleefBilal/pycaps
10
+ Project-URL: Bug Tracker, https://github.com/AleefBilal/pycaps/issues
11
+ Keywords: video,subtitles,video editing,whisper,captions
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Operating System :: OS Independent
20
+ Classifier: Topic :: Multimedia :: Video
21
+ Classifier: Topic :: Multimedia :: Sound/Audio :: Speech
22
+ Classifier: Topic :: Text Processing :: Linguistic
23
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
24
+ Requires-Python: >=3.10
25
+ Description-Content-Type: text/markdown
26
+ License-File: LICENSE
27
+ Requires-Dist: Pillow
28
+ Requires-Dist: numpy
29
+ Requires-Dist: pydantic
30
+ Requires-Dist: typer
31
+ Requires-Dist: requests
32
+ Requires-Dist: multiprocess
33
+ Requires-Dist: tqdm
34
+ Requires-Dist: movielite
35
+ Requires-Dist: platformdirs
36
+ Provides-Extra: fast
37
+ Requires-Dist: html2pic; extra == "fast"
38
+ Requires-Dist: google-cloud-speech; extra == "fast"
39
+ Provides-Extra: base
40
+ Requires-Dist: openai-whisper; extra == "base"
41
+ Requires-Dist: playwright; extra == "base"
42
+ Requires-Dist: pywebview; extra == "base"
43
+ Provides-Extra: all
44
+ Requires-Dist: openai-whisper; extra == "all"
45
+ Requires-Dist: google-cloud-speech; extra == "all"
46
+ Requires-Dist: playwright; extra == "all"
47
+ Requires-Dist: pywebview; extra == "all"
48
+ Requires-Dist: html2pic; extra == "all"
49
+ Dynamic: license-file
50
+
51
+ # pycaps
52
+
53
+ [![Status](https://img.shields.io/badge/status-alpha-orange.svg)](https://github.com/AleefBilal/pycaps)
54
+ [![PyPI](https://img.shields.io/pypi/v/pycaps-ai.svg)](https://pypi.org/project/pycaps-ai/)
55
+ [![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://opensource.org/licenses/MIT)
56
+ [![Python Version](https://img.shields.io/badge/python-3.10%20%7C%203.11%20%7C%203.12-blue)](https://www.python.org/downloads/)
57
+ [![Hugging Face Spaces](https://img.shields.io/badge/Try%20it%20online-Hugging%20Face-blue?logo=huggingface)](https://huggingface.co/spaces/francozanardi/pycaps-new)
58
+
59
+
60
+ **pycaps** is a Python tool for adding CSS styled subtitles to videos. It's designed as both a programmable library and a command-line interface (CLI), making it perfect for automating the creation of dynamic content for platforms like TikTok, YouTube Shorts, and Instagram Reels.
61
+
62
+ > **Note:** This is a community fork published on PyPI as [`pycaps-ai`](https://pypi.org/project/pycaps-ai/). The original project is [francozanardi/pycaps](https://github.com/francozanardi/pycaps).
63
+
64
+ ![demo-1](https://github.com/user-attachments/assets/fd2d3325-c986-4b6a-81ba-09c428577e61)
65
+ ![demo-2](https://github.com/user-attachments/assets/9a789244-0387-4ac8-ab51-b3601447953e)
66
+
67
+ <sub>See more examples on <a href="https://www.pycaps.com/">pycaps.com</a></sub>
68
+
69
+ ## Try It Online (no installation needed!)
70
+
71
+ You have two options to test `pycaps` directly in your browser (hosted by the [original project](https://github.com/francozanardi/pycaps)). Choose the one that best fits your needs.
72
+
73
+ ### 1. Interactive Web Demo (on Hugging Face)
74
+
75
+ Ideal for a **quick preview**, testing built-in templates, and **editing captions** with a user-friendly interface.
76
+
77
+ [![Hugging Face Spaces](https://img.shields.io/badge/Launch%20Web%20Demo-Hugging%20Face-blue?logo=huggingface)](https://huggingface.co/spaces/francozanardi/pycaps-new)
78
+
79
+ > **Keep in mind:**
80
+ > * This demo runs on a shared, CPU-only environment, so it's best for **short videos (< 60 seconds)**.
81
+ > * For a private, faster experience, you can **[duplicate the Space](https://huggingface.co/spaces/francozanardi/pycaps-new?duplicate=true)** for free.
82
+
83
+ ### 2. Full-Power Notebook (on Google Colab)
84
+
85
+ The best choice for **processing longer videos** with **maximum transcription quality**, using a free GPU provided by Google.
86
+
87
+ [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/drive/117g6xujecjLyXHBwhwyzx0innCMLh_nj?usp=sharing)
88
+
89
+ > **Keep in mind:**
90
+ > * The interface is a step-by-step code notebook, not a graphical UI.
91
+ > * You will be guided to enable the GPU for the best performance.
92
+
93
+ ## Key Features
94
+
95
+ * **Template System**: Get started quickly with predefined templates. Create and share your own templates, packaging styles, animations, and configurations.
96
+ * **CSS Styling**: Style subtitles using standard CSS. Target specific states like `.word-being-narrated` for dynamic effects, cleanly separating style from logic.
97
+ * **Word Tagging**: Tag words or phrases using regular expressions, word lists, or AI. These tags act as powerful selectors for applying custom CSS, effects, or animations.
98
+ * **Advanced Animations & Effects**: Bring words to life with a library of built-in animations (fades, pops, slides) and effects (typewriting, emoji insertion, sound effects).
99
+ * **Whisper-based Transcription**: Automatically generate accurate, word-level timestamps for your videos using OpenAI's Whisper.
100
+ * **Dual Interface**: Use it as a simple CLI for quick renders or as a comprehensive Python library for programmatic video creation.
101
+ * **Offline-First**: The core transcription, styling, and rendering engine runs entirely on your local machine. An internet connection is only needed for optional AI-powered features that require contextual understanding of your script.
102
+
103
+ ## Prerequisites
104
+
105
+ Before installing, please ensure your environment meets the following requirements:
106
+
107
+ * **Python Version**: `pycaps` was tested on **Python 3.10, 3.11, and 3.12**. Other versions may present issues.
108
+
109
+ * **FFmpeg**: You need to have FFmpeg installed on your system and accessible from your command line's `PATH`. This is essential for all audio and video processing tasks.
110
+ * You can download it from [ffmpeg.org](https://ffmpeg.org/download.html) and follow a guide to add it to your system's `PATH`.
111
+
112
+ ## Installation
113
+
114
+ 1. **Install FFmpeg**: Ensure you have completed the prerequisite step above.
115
+
116
+ 2. **Install from PyPI:**
117
+
118
+ **Full installation (recommended):**
119
+ ```bash
120
+ pip install "pycaps-ai[all]"
121
+ ```
122
+
123
+ **Custom installation with specific features:**
124
+ ```bash
125
+ # Whisper + Playwright + transcription editor (default setup)
126
+ pip install "pycaps-ai[base]"
127
+
128
+ # Lighter rendering: Google Speech + html2pic (no browser)
129
+ pip install "pycaps-ai[fast]"
130
+ ```
131
+
132
+ **Install from GitHub (latest dev):**
133
+ ```bash
134
+ pip install "git+https://github.com/AleefBilal/pycaps.git#egg=pycaps-ai[all]"
135
+ ```
136
+
137
+ 3. **Install Browser Dependencies for Rendering:**
138
+ `pycaps` currently has two different options to render the subtitle images:
139
+ - `CssSubtitleRenderer`, which is the original and default one. It uses Playwright to render CSS styles. So, you need to install its browser dependency to use it:
140
+ ```bash
141
+ playwright install chromium
142
+ ```
143
+ - `PictexSubtitleRenderer`, which is a light-weight option. It doesn't use a browser, but it only support a subset of CSS, and it may present some visual differences in the result (specially in the shadows, you should modify the CSS from the templates to get the same results). To use it, you must call `with_custom_subtitle_renderer(PictexSubtitleRenderer())` when `CapsPipelineBuilder()` is created.
144
+
145
+ > ⚠️ **Note**: The first time you use `pycaps`, it will also download a Whisper AI model for transcription. This may take a few minutes and only happens once.
146
+
147
+ ## Quick Start
148
+
149
+ There are two primary ways to use pycaps: via the command line with a template or programmatically in a Python script.
150
+
151
+ ### 1. Using the Command-Line (CLI)
152
+
153
+ The fastest way to get started is to use a built-in template.
154
+
155
+ ```bash
156
+ pycaps render --input my_video.mp4 --template minimalist
157
+ ```
158
+
159
+ This command will:
160
+ 1. Load the `minimalist` template.
161
+ 2. Transcribe the audio from `my_video.mp4`.
162
+ 3. Apply the template's styles and animations.
163
+ 4. Save the result in a new file.
164
+
165
+ If you already have a transcript from another tool, you can skip built-in transcription:
166
+
167
+ ```bash
168
+ pycaps render --input my_video.mp4 --template minimalist --transcript transcript.json
169
+ ```
170
+
171
+ Supported transcript formats: `whisper_json`, `pycaps_json`, `srt`, `vtt` (`--transcript-format` is optional and defaults to `auto`).
172
+
173
+ ### 2. Using the Python Library
174
+
175
+ For full control, use the `CapsPipelineBuilder` in your Python code.
176
+
177
+ ```python
178
+ from pycaps import CapsPipelineBuilder
179
+
180
+ # The pipeline contains multiples stages to render the final video
181
+ pipeline = (
182
+ CapsPipelineBuilder()
183
+ .with_input_video("input.mp4")
184
+ .add_css("css_file.css")
185
+ .build()
186
+ )
187
+ pipeline.run() # When this is executed, it starts to render the video
188
+ ```
189
+
190
+ You can also preload the builder using a Template.
191
+ ```python
192
+ from pycaps import *
193
+
194
+ # Load a template and configure it
195
+ builder = TemplateLoader("default").with_input_video("my_video.mp4").load(False)
196
+
197
+ # Programmatically add an animation
198
+ builder.add_animation(
199
+ animation=FadeIn(),
200
+ when=EventType.ON_NARRATION_STARTS,
201
+ what=ElementType.SEGMENT
202
+ )
203
+
204
+ # Build and run the pipeline
205
+ pipeline = builder.build()
206
+ pipeline.run()
207
+ ```
208
+
209
+ ## What's Next?
210
+
211
+ * 🚀 **For Command-Line Users**: Check the **[CLI Usage Guide](./docs/CLI.md)** for a quick and easy start.
212
+ * 🧠 **For Developers**: Understand the core concepts in the **[Structure Guide](./docs/CORE_STRUCTURE.md)**.
213
+ * 🏷️ **Styling & Logic**: Learn about the powerful **[Tagging System](./docs/TAGS.md)**.
214
+ * 🎨 **Reusable Styles**: See how **[Templates](./docs/TEMPLATES.md)** work and how to create your own.
215
+ * 💡 **Inspiration**: Dive into **[Code & JSON Examples](./docs/EXAMPLES.md)**.
216
+ * 🔧 **Advanced Config**: See all options in the **[JSON Configuration Reference](./docs/CONFIG_REFERENCE.md)**.
217
+ * 🤖 **AI Features**: Learn about AI-powered features in the **[API Usage Guide](./docs/API_USAGE.md)**.
218
+
219
+ ## Contributing
220
+
221
+ This project is in active development. Contributions, bug reports, and feature requests are welcome! Please open an issue or pull request on our [GitHub repository](https://github.com/AleefBilal/pycaps).
222
+
223
+ ## License
224
+
225
+ pycaps is licensed under the [MIT License](https://opensource.org/licenses/MIT). Originally created by [Franco Zanardi](https://github.com/francozanardi/pycaps).
@@ -0,0 +1,175 @@
1
+ # pycaps
2
+
3
+ [![Status](https://img.shields.io/badge/status-alpha-orange.svg)](https://github.com/AleefBilal/pycaps)
4
+ [![PyPI](https://img.shields.io/pypi/v/pycaps-ai.svg)](https://pypi.org/project/pycaps-ai/)
5
+ [![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://opensource.org/licenses/MIT)
6
+ [![Python Version](https://img.shields.io/badge/python-3.10%20%7C%203.11%20%7C%203.12-blue)](https://www.python.org/downloads/)
7
+ [![Hugging Face Spaces](https://img.shields.io/badge/Try%20it%20online-Hugging%20Face-blue?logo=huggingface)](https://huggingface.co/spaces/francozanardi/pycaps-new)
8
+
9
+
10
+ **pycaps** is a Python tool for adding CSS styled subtitles to videos. It's designed as both a programmable library and a command-line interface (CLI), making it perfect for automating the creation of dynamic content for platforms like TikTok, YouTube Shorts, and Instagram Reels.
11
+
12
+ > **Note:** This is a community fork published on PyPI as [`pycaps-ai`](https://pypi.org/project/pycaps-ai/). The original project is [francozanardi/pycaps](https://github.com/francozanardi/pycaps).
13
+
14
+ ![demo-1](https://github.com/user-attachments/assets/fd2d3325-c986-4b6a-81ba-09c428577e61)
15
+ ![demo-2](https://github.com/user-attachments/assets/9a789244-0387-4ac8-ab51-b3601447953e)
16
+
17
+ <sub>See more examples on <a href="https://www.pycaps.com/">pycaps.com</a></sub>
18
+
19
+ ## Try It Online (no installation needed!)
20
+
21
+ You have two options to test `pycaps` directly in your browser (hosted by the [original project](https://github.com/francozanardi/pycaps)). Choose the one that best fits your needs.
22
+
23
+ ### 1. Interactive Web Demo (on Hugging Face)
24
+
25
+ Ideal for a **quick preview**, testing built-in templates, and **editing captions** with a user-friendly interface.
26
+
27
+ [![Hugging Face Spaces](https://img.shields.io/badge/Launch%20Web%20Demo-Hugging%20Face-blue?logo=huggingface)](https://huggingface.co/spaces/francozanardi/pycaps-new)
28
+
29
+ > **Keep in mind:**
30
+ > * This demo runs on a shared, CPU-only environment, so it's best for **short videos (< 60 seconds)**.
31
+ > * For a private, faster experience, you can **[duplicate the Space](https://huggingface.co/spaces/francozanardi/pycaps-new?duplicate=true)** for free.
32
+
33
+ ### 2. Full-Power Notebook (on Google Colab)
34
+
35
+ The best choice for **processing longer videos** with **maximum transcription quality**, using a free GPU provided by Google.
36
+
37
+ [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/drive/117g6xujecjLyXHBwhwyzx0innCMLh_nj?usp=sharing)
38
+
39
+ > **Keep in mind:**
40
+ > * The interface is a step-by-step code notebook, not a graphical UI.
41
+ > * You will be guided to enable the GPU for the best performance.
42
+
43
+ ## Key Features
44
+
45
+ * **Template System**: Get started quickly with predefined templates. Create and share your own templates, packaging styles, animations, and configurations.
46
+ * **CSS Styling**: Style subtitles using standard CSS. Target specific states like `.word-being-narrated` for dynamic effects, cleanly separating style from logic.
47
+ * **Word Tagging**: Tag words or phrases using regular expressions, word lists, or AI. These tags act as powerful selectors for applying custom CSS, effects, or animations.
48
+ * **Advanced Animations & Effects**: Bring words to life with a library of built-in animations (fades, pops, slides) and effects (typewriting, emoji insertion, sound effects).
49
+ * **Whisper-based Transcription**: Automatically generate accurate, word-level timestamps for your videos using OpenAI's Whisper.
50
+ * **Dual Interface**: Use it as a simple CLI for quick renders or as a comprehensive Python library for programmatic video creation.
51
+ * **Offline-First**: The core transcription, styling, and rendering engine runs entirely on your local machine. An internet connection is only needed for optional AI-powered features that require contextual understanding of your script.
52
+
53
+ ## Prerequisites
54
+
55
+ Before installing, please ensure your environment meets the following requirements:
56
+
57
+ * **Python Version**: `pycaps` was tested on **Python 3.10, 3.11, and 3.12**. Other versions may present issues.
58
+
59
+ * **FFmpeg**: You need to have FFmpeg installed on your system and accessible from your command line's `PATH`. This is essential for all audio and video processing tasks.
60
+ * You can download it from [ffmpeg.org](https://ffmpeg.org/download.html) and follow a guide to add it to your system's `PATH`.
61
+
62
+ ## Installation
63
+
64
+ 1. **Install FFmpeg**: Ensure you have completed the prerequisite step above.
65
+
66
+ 2. **Install from PyPI:**
67
+
68
+ **Full installation (recommended):**
69
+ ```bash
70
+ pip install "pycaps-ai[all]"
71
+ ```
72
+
73
+ **Custom installation with specific features:**
74
+ ```bash
75
+ # Whisper + Playwright + transcription editor (default setup)
76
+ pip install "pycaps-ai[base]"
77
+
78
+ # Lighter rendering: Google Speech + html2pic (no browser)
79
+ pip install "pycaps-ai[fast]"
80
+ ```
81
+
82
+ **Install from GitHub (latest dev):**
83
+ ```bash
84
+ pip install "git+https://github.com/AleefBilal/pycaps.git#egg=pycaps-ai[all]"
85
+ ```
86
+
87
+ 3. **Install Browser Dependencies for Rendering:**
88
+ `pycaps` currently has two different options to render the subtitle images:
89
+ - `CssSubtitleRenderer`, which is the original and default one. It uses Playwright to render CSS styles. So, you need to install its browser dependency to use it:
90
+ ```bash
91
+ playwright install chromium
92
+ ```
93
+ - `PictexSubtitleRenderer`, which is a light-weight option. It doesn't use a browser, but it only support a subset of CSS, and it may present some visual differences in the result (specially in the shadows, you should modify the CSS from the templates to get the same results). To use it, you must call `with_custom_subtitle_renderer(PictexSubtitleRenderer())` when `CapsPipelineBuilder()` is created.
94
+
95
+ > ⚠️ **Note**: The first time you use `pycaps`, it will also download a Whisper AI model for transcription. This may take a few minutes and only happens once.
96
+
97
+ ## Quick Start
98
+
99
+ There are two primary ways to use pycaps: via the command line with a template or programmatically in a Python script.
100
+
101
+ ### 1. Using the Command-Line (CLI)
102
+
103
+ The fastest way to get started is to use a built-in template.
104
+
105
+ ```bash
106
+ pycaps render --input my_video.mp4 --template minimalist
107
+ ```
108
+
109
+ This command will:
110
+ 1. Load the `minimalist` template.
111
+ 2. Transcribe the audio from `my_video.mp4`.
112
+ 3. Apply the template's styles and animations.
113
+ 4. Save the result in a new file.
114
+
115
+ If you already have a transcript from another tool, you can skip built-in transcription:
116
+
117
+ ```bash
118
+ pycaps render --input my_video.mp4 --template minimalist --transcript transcript.json
119
+ ```
120
+
121
+ Supported transcript formats: `whisper_json`, `pycaps_json`, `srt`, `vtt` (`--transcript-format` is optional and defaults to `auto`).
122
+
123
+ ### 2. Using the Python Library
124
+
125
+ For full control, use the `CapsPipelineBuilder` in your Python code.
126
+
127
+ ```python
128
+ from pycaps import CapsPipelineBuilder
129
+
130
+ # The pipeline contains multiples stages to render the final video
131
+ pipeline = (
132
+ CapsPipelineBuilder()
133
+ .with_input_video("input.mp4")
134
+ .add_css("css_file.css")
135
+ .build()
136
+ )
137
+ pipeline.run() # When this is executed, it starts to render the video
138
+ ```
139
+
140
+ You can also preload the builder using a Template.
141
+ ```python
142
+ from pycaps import *
143
+
144
+ # Load a template and configure it
145
+ builder = TemplateLoader("default").with_input_video("my_video.mp4").load(False)
146
+
147
+ # Programmatically add an animation
148
+ builder.add_animation(
149
+ animation=FadeIn(),
150
+ when=EventType.ON_NARRATION_STARTS,
151
+ what=ElementType.SEGMENT
152
+ )
153
+
154
+ # Build and run the pipeline
155
+ pipeline = builder.build()
156
+ pipeline.run()
157
+ ```
158
+
159
+ ## What's Next?
160
+
161
+ * 🚀 **For Command-Line Users**: Check the **[CLI Usage Guide](./docs/CLI.md)** for a quick and easy start.
162
+ * 🧠 **For Developers**: Understand the core concepts in the **[Structure Guide](./docs/CORE_STRUCTURE.md)**.
163
+ * 🏷️ **Styling & Logic**: Learn about the powerful **[Tagging System](./docs/TAGS.md)**.
164
+ * 🎨 **Reusable Styles**: See how **[Templates](./docs/TEMPLATES.md)** work and how to create your own.
165
+ * 💡 **Inspiration**: Dive into **[Code & JSON Examples](./docs/EXAMPLES.md)**.
166
+ * 🔧 **Advanced Config**: See all options in the **[JSON Configuration Reference](./docs/CONFIG_REFERENCE.md)**.
167
+ * 🤖 **AI Features**: Learn about AI-powered features in the **[API Usage Guide](./docs/API_USAGE.md)**.
168
+
169
+ ## Contributing
170
+
171
+ This project is in active development. Contributions, bug reports, and feature requests are welcome! Please open an issue or pull request on our [GitHub repository](https://github.com/AleefBilal/pycaps).
172
+
173
+ ## License
174
+
175
+ pycaps is licensed under the [MIT License](https://opensource.org/licenses/MIT). Originally created by [Franco Zanardi](https://github.com/francozanardi/pycaps).
@@ -0,0 +1,76 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "pycaps-ai"
7
+ version = "0.2.1"
8
+ authors = [
9
+ { name = "Aleef Bilal", email = "aleefbilal@gmail.com" },
10
+ ]
11
+ maintainers = [
12
+ { name = "Aleef Bilal", email = "aleefbilal@gmail.com" },
13
+ ]
14
+ description = "A Python tool to edit videos and automatically add CSS-styled subtitles to videos."
15
+ readme = "README.md"
16
+ requires-python = ">=3.10"
17
+ license = {text = "MIT License"}
18
+ keywords = ["video", "subtitles", "video editing", "whisper", "captions"]
19
+ classifiers = [
20
+ "Development Status :: 3 - Alpha",
21
+ "Intended Audience :: Developers",
22
+ "License :: OSI Approved :: MIT License",
23
+ "Programming Language :: Python :: 3",
24
+ "Programming Language :: Python :: 3.10",
25
+ "Programming Language :: Python :: 3.11",
26
+ "Programming Language :: Python :: 3.12",
27
+ "Operating System :: OS Independent",
28
+ "Topic :: Multimedia :: Video",
29
+ "Topic :: Multimedia :: Sound/Audio :: Speech",
30
+ "Topic :: Text Processing :: Linguistic",
31
+ "Topic :: Software Development :: Libraries :: Python Modules",
32
+ ]
33
+
34
+ dependencies = [
35
+ "Pillow",
36
+ "numpy",
37
+ "pydantic",
38
+ "typer",
39
+ "requests",
40
+ "multiprocess",
41
+ "tqdm",
42
+ "movielite",
43
+ "platformdirs"
44
+ ]
45
+
46
+ [project.optional-dependencies]
47
+ fast = [
48
+ "html2pic",
49
+ "google-cloud-speech"
50
+ ]
51
+ base = [
52
+ "openai-whisper",
53
+ "playwright",
54
+ "pywebview",
55
+ ]
56
+ all = [
57
+ "openai-whisper",
58
+ "google-cloud-speech",
59
+ "playwright",
60
+ "pywebview",
61
+ "html2pic"
62
+ ]
63
+
64
+ [project.scripts]
65
+ pycaps = "pycaps.cli:app"
66
+
67
+ [project.urls]
68
+ "Homepage" = "https://github.com/AleefBilal/pycaps"
69
+ "Repository" = "https://github.com/AleefBilal/pycaps"
70
+ "Bug Tracker" = "https://github.com/AleefBilal/pycaps/issues"
71
+
72
+ [tool.setuptools]
73
+ include-package-data = true
74
+
75
+ [tool.setuptools.packages.find]
76
+ where = ["src"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,13 @@
1
+ from .pipeline import CapsPipeline, CapsPipelineBuilder, JsonConfigLoader
2
+ from .renderer import CssSubtitleRenderer, PictexSubtitleRenderer
3
+ from .transcriber import WhisperAudioTranscriber, GoogleAudioTranscriber, AudioTranscriber, LimitByWordsSplitter, LimitByCharsSplitter, SplitIntoSentencesSplitter, TranscriptFormat, load_transcription
4
+ from .effect import *
5
+ from .animation import *
6
+ from .selector import WordClipSelector
7
+ from .tag import TagCondition, BuiltinTag, TagConditionFactory, SemanticTagger
8
+ from .common import *
9
+ from .layout.definitions import *
10
+ from .ai import LlmProvider
11
+ from .template import TemplateLoader, TemplateFactory, DEFAULT_TEMPLATE_NAME
12
+
13
+ __version__ = "0.2.1"
@@ -0,0 +1,5 @@
1
+ from .gpt import Gpt
2
+ from .llm import Llm
3
+ from .llm_provider import LlmProvider
4
+
5
+ __all__ = ["Gpt", "Llm", "LlmProvider"]
@@ -0,0 +1,35 @@
1
+ from pycaps.ai.llm import Llm
2
+ import os
3
+
4
+ class Gpt(Llm):
5
+
6
+ OPENAI_API_KEY_NAME = "PYCAPS_OPENAI_API_KEY"
7
+
8
+ def __init__(self):
9
+ self._client = None
10
+
11
+ def send_message(self, prompt: str, model: str = "gpt-4.1-mini") -> str:
12
+ return self._get_client().responses.create(model=model, input=prompt).output_text
13
+
14
+ def is_enabled(self) -> bool:
15
+ return os.getenv(self.OPENAI_API_KEY_NAME) is not None
16
+
17
+ def _get_client(self):
18
+ try:
19
+ from openai import OpenAI
20
+
21
+ if self._client:
22
+ return self._client
23
+
24
+ self._client = OpenAI(api_key=os.getenv(self.OPENAI_API_KEY_NAME))
25
+ return self._client
26
+ except ImportError:
27
+ raise ImportError(
28
+ "OpenAI API not found. "
29
+ "Please install it with: pip install openai"
30
+ )
31
+ except Exception as e:
32
+ raise RuntimeError(
33
+ f"Error initializing OpenAI client: {e}\n\n"
34
+ "Please ensure you have authenticated correctly via PYCAPS_OPENAI_API_KEY."
35
+ )
@@ -0,0 +1,11 @@
1
+ from abc import ABC, abstractmethod
2
+
3
+ class Llm(ABC):
4
+
5
+ @abstractmethod
6
+ def send_message(self, message: str, model: str) -> str:
7
+ pass
8
+
9
+ @abstractmethod
10
+ def is_enabled(self) -> bool:
11
+ pass
@@ -0,0 +1,16 @@
1
+ from typing import Optional
2
+ from .llm import Llm
3
+ from .gpt import Gpt
4
+
5
+ class LlmProvider:
6
+ _llm: Optional[Llm] = None
7
+
8
+ @staticmethod
9
+ def get() -> Llm:
10
+ if LlmProvider._llm is None:
11
+ LlmProvider._llm = Gpt()
12
+ return LlmProvider._llm
13
+
14
+ @staticmethod
15
+ def set(llm: Llm):
16
+ LlmProvider._llm = llm
@@ -0,0 +1,31 @@
1
+ # src/pycaps/animator/__init__.py
2
+
3
+ from .builtin import *
4
+ from .definitions import Transformer, OvershootConfig, Direction
5
+ from .primitive_animation import PrimitiveAnimation
6
+ from .preset_animation import PresetAnimation
7
+ from .animation import Animation
8
+ from .element_animator import ElementAnimator
9
+
10
+ __all__ = [
11
+ "Animation",
12
+ "PrimitiveAnimation",
13
+ "PresetAnimation",
14
+ "ElementAnimator",
15
+ "Transformer",
16
+ "OvershootConfig",
17
+ "Direction",
18
+ "SlideInPrimitive",
19
+ "ZoomInPrimitive",
20
+ "PopInPrimitive",
21
+ "FadeInPrimitive",
22
+ "FadeIn",
23
+ "FadeOut",
24
+ "PopIn",
25
+ "PopOut",
26
+ "PopInBounce",
27
+ "SlideIn",
28
+ "SlideOut",
29
+ "ZoomIn",
30
+ "ZoomOut",
31
+ ]
@@ -0,0 +1,11 @@
1
+ from pycaps.common import WordClip, ElementType
2
+ from abc import ABC, abstractmethod
3
+
4
+ class Animation(ABC):
5
+ def __init__(self, duration: float, delay: float = 0.0) -> None:
6
+ self._duration: float = duration
7
+ self._delay: float = delay
8
+
9
+ @abstractmethod
10
+ def run(self, clip: WordClip, offset: float, what: ElementType) -> None:
11
+ pass
@@ -0,0 +1,18 @@
1
+ from .primitive import *
2
+ from .preset import *
3
+
4
+ __all__ = [
5
+ "FadeIn",
6
+ "FadeOut",
7
+ "SlideIn",
8
+ "SlideOut",
9
+ "ZoomIn",
10
+ "ZoomOut",
11
+ "PopIn",
12
+ "PopOut",
13
+ "PopInBounce",
14
+ "FadeInPrimitive",
15
+ "PopInPrimitive",
16
+ "ZoomInPrimitive",
17
+ "SlideInPrimitive",
18
+ ]