magic_hour 0.9.5__py3-none-any.whl → 0.44.0__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 (264) hide show
  1. magic_hour/README.md +34 -0
  2. magic_hour/__init__.py +1 -1
  3. magic_hour/client.py +8 -17
  4. magic_hour/environment.py +13 -1
  5. magic_hour/helpers/__init__.py +4 -0
  6. magic_hour/helpers/download.py +77 -0
  7. magic_hour/helpers/logger.py +8 -0
  8. magic_hour/resources/v1/README.md +32 -0
  9. magic_hour/resources/v1/ai_clothes_changer/README.md +94 -5
  10. magic_hour/resources/v1/ai_clothes_changer/client.py +161 -16
  11. magic_hour/resources/v1/ai_face_editor/README.md +195 -0
  12. magic_hour/resources/v1/ai_face_editor/__init__.py +4 -0
  13. magic_hour/resources/v1/ai_face_editor/client.py +324 -0
  14. magic_hour/resources/v1/ai_gif_generator/README.md +116 -0
  15. magic_hour/resources/v1/ai_gif_generator/__init__.py +4 -0
  16. magic_hour/resources/v1/ai_gif_generator/client.py +257 -0
  17. magic_hour/resources/v1/ai_headshot_generator/README.md +81 -3
  18. magic_hour/resources/v1/ai_headshot_generator/client.py +167 -18
  19. magic_hour/resources/v1/ai_image_editor/README.md +125 -0
  20. magic_hour/resources/v1/ai_image_editor/__init__.py +4 -0
  21. magic_hour/resources/v1/ai_image_editor/client.py +290 -0
  22. magic_hour/resources/v1/ai_image_generator/README.md +99 -5
  23. magic_hour/resources/v1/ai_image_generator/client.py +170 -24
  24. magic_hour/resources/v1/ai_image_upscaler/README.md +89 -3
  25. magic_hour/resources/v1/ai_image_upscaler/client.py +173 -20
  26. magic_hour/resources/v1/ai_meme_generator/README.md +129 -0
  27. magic_hour/resources/v1/ai_meme_generator/__init__.py +4 -0
  28. magic_hour/resources/v1/ai_meme_generator/client.py +253 -0
  29. magic_hour/resources/v1/ai_photo_editor/README.md +119 -4
  30. magic_hour/resources/v1/ai_photo_editor/client.py +199 -18
  31. magic_hour/resources/v1/ai_qr_code_generator/README.md +84 -3
  32. magic_hour/resources/v1/ai_qr_code_generator/client.py +140 -18
  33. magic_hour/resources/v1/ai_talking_photo/README.md +137 -0
  34. magic_hour/resources/v1/ai_talking_photo/__init__.py +4 -0
  35. magic_hour/resources/v1/ai_talking_photo/client.py +326 -0
  36. magic_hour/resources/v1/ai_voice_cloner/README.md +62 -0
  37. magic_hour/resources/v1/ai_voice_cloner/__init__.py +4 -0
  38. magic_hour/resources/v1/ai_voice_cloner/client.py +272 -0
  39. magic_hour/resources/v1/ai_voice_generator/README.md +112 -0
  40. magic_hour/resources/v1/ai_voice_generator/__init__.py +4 -0
  41. magic_hour/resources/v1/ai_voice_generator/client.py +241 -0
  42. magic_hour/resources/v1/animation/README.md +128 -6
  43. magic_hour/resources/v1/animation/client.py +247 -22
  44. magic_hour/resources/v1/audio_projects/README.md +135 -0
  45. magic_hour/resources/v1/audio_projects/__init__.py +12 -0
  46. magic_hour/resources/v1/audio_projects/client.py +310 -0
  47. magic_hour/resources/v1/audio_projects/client_test.py +520 -0
  48. magic_hour/resources/v1/auto_subtitle_generator/README.md +128 -0
  49. magic_hour/resources/v1/auto_subtitle_generator/__init__.py +4 -0
  50. magic_hour/resources/v1/auto_subtitle_generator/client.py +346 -0
  51. magic_hour/resources/v1/client.py +75 -1
  52. magic_hour/resources/v1/face_detection/README.md +157 -0
  53. magic_hour/resources/v1/face_detection/__init__.py +12 -0
  54. magic_hour/resources/v1/face_detection/client.py +380 -0
  55. magic_hour/resources/v1/face_swap/README.md +137 -9
  56. magic_hour/resources/v1/face_swap/client.py +329 -38
  57. magic_hour/resources/v1/face_swap_photo/README.md +118 -3
  58. magic_hour/resources/v1/face_swap_photo/client.py +199 -14
  59. magic_hour/resources/v1/files/README.md +39 -0
  60. magic_hour/resources/v1/files/client.py +351 -1
  61. magic_hour/resources/v1/files/client_test.py +414 -0
  62. magic_hour/resources/v1/files/upload_urls/README.md +38 -17
  63. magic_hour/resources/v1/files/upload_urls/client.py +38 -34
  64. magic_hour/resources/v1/image_background_remover/README.md +96 -5
  65. magic_hour/resources/v1/image_background_remover/client.py +151 -16
  66. magic_hour/resources/v1/image_projects/README.md +82 -10
  67. magic_hour/resources/v1/image_projects/__init__.py +10 -2
  68. magic_hour/resources/v1/image_projects/client.py +154 -16
  69. magic_hour/resources/v1/image_projects/client_test.py +527 -0
  70. magic_hour/resources/v1/image_to_video/README.md +96 -11
  71. magic_hour/resources/v1/image_to_video/client.py +282 -38
  72. magic_hour/resources/v1/lip_sync/README.md +112 -9
  73. magic_hour/resources/v1/lip_sync/client.py +288 -34
  74. magic_hour/resources/v1/photo_colorizer/README.md +107 -0
  75. magic_hour/resources/v1/photo_colorizer/__init__.py +4 -0
  76. magic_hour/resources/v1/photo_colorizer/client.py +248 -0
  77. magic_hour/resources/v1/text_to_video/README.md +96 -7
  78. magic_hour/resources/v1/text_to_video/client.py +204 -18
  79. magic_hour/resources/v1/video_projects/README.md +81 -9
  80. magic_hour/resources/v1/video_projects/__init__.py +10 -2
  81. magic_hour/resources/v1/video_projects/client.py +151 -14
  82. magic_hour/resources/v1/video_projects/client_test.py +527 -0
  83. magic_hour/resources/v1/video_to_video/README.md +119 -15
  84. magic_hour/resources/v1/video_to_video/client.py +299 -46
  85. magic_hour/types/models/__init__.py +92 -56
  86. magic_hour/types/models/v1_ai_clothes_changer_create_response.py +33 -0
  87. magic_hour/types/models/v1_ai_face_editor_create_response.py +33 -0
  88. magic_hour/types/models/v1_ai_gif_generator_create_response.py +33 -0
  89. magic_hour/types/models/v1_ai_headshot_generator_create_response.py +33 -0
  90. magic_hour/types/models/v1_ai_image_editor_create_response.py +33 -0
  91. magic_hour/types/models/v1_ai_image_generator_create_response.py +33 -0
  92. magic_hour/types/models/v1_ai_image_upscaler_create_response.py +33 -0
  93. magic_hour/types/models/v1_ai_meme_generator_create_response.py +33 -0
  94. magic_hour/types/models/v1_ai_photo_editor_create_response.py +33 -0
  95. magic_hour/types/models/v1_ai_qr_code_generator_create_response.py +33 -0
  96. magic_hour/types/models/v1_ai_talking_photo_create_response.py +35 -0
  97. magic_hour/types/models/v1_ai_voice_cloner_create_response.py +27 -0
  98. magic_hour/types/models/v1_ai_voice_generator_create_response.py +27 -0
  99. magic_hour/types/models/v1_animation_create_response.py +35 -0
  100. magic_hour/types/models/v1_audio_projects_get_response.py +72 -0
  101. magic_hour/types/models/v1_audio_projects_get_response_downloads_item.py +19 -0
  102. magic_hour/types/models/{get_v1_image_projects_id_response_error.py → v1_audio_projects_get_response_error.py} +2 -2
  103. magic_hour/types/models/v1_auto_subtitle_generator_create_response.py +35 -0
  104. magic_hour/types/models/v1_face_detection_create_response.py +25 -0
  105. magic_hour/types/models/v1_face_detection_get_response.py +45 -0
  106. magic_hour/types/models/v1_face_detection_get_response_faces_item.py +25 -0
  107. magic_hour/types/models/v1_face_swap_create_response.py +35 -0
  108. magic_hour/types/models/v1_face_swap_photo_create_response.py +33 -0
  109. magic_hour/types/models/v1_files_upload_urls_create_response.py +24 -0
  110. magic_hour/types/models/{post_v1_files_upload_urls_response_items_item.py → v1_files_upload_urls_create_response_items_item.py} +2 -2
  111. magic_hour/types/models/v1_image_background_remover_create_response.py +33 -0
  112. magic_hour/types/models/{get_v1_image_projects_id_response.py → v1_image_projects_get_response.py} +20 -18
  113. magic_hour/types/models/{get_v1_video_projects_id_response_downloads_item.py → v1_image_projects_get_response_downloads_item.py} +1 -1
  114. magic_hour/types/models/{get_v1_video_projects_id_response_error.py → v1_image_projects_get_response_error.py} +2 -2
  115. magic_hour/types/models/v1_image_to_video_create_response.py +35 -0
  116. magic_hour/types/models/v1_lip_sync_create_response.py +35 -0
  117. magic_hour/types/models/v1_photo_colorizer_create_response.py +33 -0
  118. magic_hour/types/models/v1_text_to_video_create_response.py +35 -0
  119. magic_hour/types/models/{get_v1_video_projects_id_response.py → v1_video_projects_get_response.py} +26 -23
  120. magic_hour/types/models/{get_v1_video_projects_id_response_download.py → v1_video_projects_get_response_download.py} +1 -1
  121. magic_hour/types/models/{get_v1_image_projects_id_response_downloads_item.py → v1_video_projects_get_response_downloads_item.py} +1 -1
  122. magic_hour/types/models/v1_video_projects_get_response_error.py +25 -0
  123. magic_hour/types/models/v1_video_to_video_create_response.py +35 -0
  124. magic_hour/types/params/__init__.py +422 -176
  125. magic_hour/types/params/v1_ai_clothes_changer_create_body.py +40 -0
  126. magic_hour/types/params/v1_ai_clothes_changer_create_body_assets.py +58 -0
  127. magic_hour/types/params/v1_ai_clothes_changer_generate_body_assets.py +33 -0
  128. magic_hour/types/params/v1_ai_face_editor_create_body.py +52 -0
  129. magic_hour/types/params/v1_ai_face_editor_create_body_assets.py +33 -0
  130. magic_hour/types/params/v1_ai_face_editor_create_body_style.py +137 -0
  131. magic_hour/types/params/v1_ai_face_editor_generate_body_assets.py +17 -0
  132. magic_hour/types/params/v1_ai_gif_generator_create_body.py +47 -0
  133. magic_hour/types/params/{post_v1_ai_image_generator_body_style.py → v1_ai_gif_generator_create_body_style.py} +5 -5
  134. magic_hour/types/params/v1_ai_headshot_generator_create_body.py +49 -0
  135. magic_hour/types/params/v1_ai_headshot_generator_create_body_assets.py +33 -0
  136. magic_hour/types/params/v1_ai_headshot_generator_create_body_style.py +27 -0
  137. magic_hour/types/params/v1_ai_headshot_generator_generate_body_assets.py +17 -0
  138. magic_hour/types/params/v1_ai_image_editor_create_body.py +49 -0
  139. magic_hour/types/params/v1_ai_image_editor_create_body_assets.py +47 -0
  140. magic_hour/types/params/v1_ai_image_editor_create_body_style.py +41 -0
  141. magic_hour/types/params/v1_ai_image_editor_generate_body_assets.py +28 -0
  142. magic_hour/types/params/{post_v1_ai_image_generator_body.py → v1_ai_image_generator_create_body.py} +17 -11
  143. magic_hour/types/params/v1_ai_image_generator_create_body_style.py +127 -0
  144. magic_hour/types/params/v1_ai_image_upscaler_create_body.py +59 -0
  145. magic_hour/types/params/v1_ai_image_upscaler_create_body_assets.py +33 -0
  146. magic_hour/types/params/{post_v1_ai_image_upscaler_body_style.py → v1_ai_image_upscaler_create_body_style.py} +4 -4
  147. magic_hour/types/params/v1_ai_image_upscaler_generate_body_assets.py +17 -0
  148. magic_hour/types/params/v1_ai_meme_generator_create_body.py +37 -0
  149. magic_hour/types/params/v1_ai_meme_generator_create_body_style.py +73 -0
  150. magic_hour/types/params/{post_v1_ai_photo_editor_body.py → v1_ai_photo_editor_create_body.py} +15 -15
  151. magic_hour/types/params/v1_ai_photo_editor_create_body_assets.py +33 -0
  152. magic_hour/types/params/{post_v1_ai_photo_editor_body_style.py → v1_ai_photo_editor_create_body_style.py} +20 -4
  153. magic_hour/types/params/v1_ai_photo_editor_generate_body_assets.py +17 -0
  154. magic_hour/types/params/v1_ai_qr_code_generator_create_body.py +45 -0
  155. magic_hour/types/params/{post_v1_ai_qr_code_generator_body_style.py → v1_ai_qr_code_generator_create_body_style.py} +4 -4
  156. magic_hour/types/params/v1_ai_talking_photo_create_body.py +68 -0
  157. magic_hour/types/params/v1_ai_talking_photo_create_body_assets.py +46 -0
  158. magic_hour/types/params/v1_ai_talking_photo_create_body_style.py +44 -0
  159. magic_hour/types/params/v1_ai_talking_photo_generate_body_assets.py +26 -0
  160. magic_hour/types/params/v1_ai_voice_cloner_create_body.py +49 -0
  161. magic_hour/types/params/v1_ai_voice_cloner_create_body_assets.py +33 -0
  162. magic_hour/types/params/v1_ai_voice_cloner_create_body_style.py +28 -0
  163. magic_hour/types/params/v1_ai_voice_cloner_generate_body_assets.py +28 -0
  164. magic_hour/types/params/v1_ai_voice_generator_create_body.py +40 -0
  165. magic_hour/types/params/v1_ai_voice_generator_create_body_style.py +440 -0
  166. magic_hour/types/params/{post_v1_animation_body.py → v1_animation_create_body.py} +16 -16
  167. magic_hour/types/params/{post_v1_animation_body_assets.py → v1_animation_create_body_assets.py} +15 -5
  168. magic_hour/types/params/{post_v1_animation_body_style.py → v1_animation_create_body_style.py} +13 -10
  169. magic_hour/types/params/v1_animation_generate_body_assets.py +39 -0
  170. magic_hour/types/params/v1_auto_subtitle_generator_create_body.py +78 -0
  171. magic_hour/types/params/v1_auto_subtitle_generator_create_body_assets.py +33 -0
  172. magic_hour/types/params/v1_auto_subtitle_generator_create_body_style.py +56 -0
  173. magic_hour/types/params/v1_auto_subtitle_generator_create_body_style_custom_config.py +86 -0
  174. magic_hour/types/params/v1_auto_subtitle_generator_generate_body_assets.py +17 -0
  175. magic_hour/types/params/v1_face_detection_create_body.py +44 -0
  176. magic_hour/types/params/v1_face_detection_create_body_assets.py +33 -0
  177. magic_hour/types/params/v1_face_detection_generate_body_assets.py +17 -0
  178. magic_hour/types/params/v1_face_swap_create_body.py +92 -0
  179. magic_hour/types/params/v1_face_swap_create_body_assets.py +91 -0
  180. magic_hour/types/params/v1_face_swap_create_body_assets_face_mappings_item.py +44 -0
  181. magic_hour/types/params/v1_face_swap_create_body_style.py +33 -0
  182. magic_hour/types/params/v1_face_swap_generate_body_assets.py +56 -0
  183. magic_hour/types/params/v1_face_swap_generate_body_assets_face_mappings_item.py +25 -0
  184. magic_hour/types/params/v1_face_swap_photo_create_body.py +40 -0
  185. magic_hour/types/params/v1_face_swap_photo_create_body_assets.py +76 -0
  186. magic_hour/types/params/v1_face_swap_photo_create_body_assets_face_mappings_item.py +44 -0
  187. magic_hour/types/params/v1_face_swap_photo_generate_body_assets.py +47 -0
  188. magic_hour/types/params/v1_face_swap_photo_generate_body_assets_face_mappings_item.py +25 -0
  189. magic_hour/types/params/v1_files_upload_urls_create_body.py +36 -0
  190. magic_hour/types/params/v1_files_upload_urls_create_body_items_item.py +38 -0
  191. magic_hour/types/params/v1_image_background_remover_create_body.py +40 -0
  192. magic_hour/types/params/v1_image_background_remover_create_body_assets.py +49 -0
  193. magic_hour/types/params/v1_image_background_remover_generate_body_assets.py +27 -0
  194. magic_hour/types/params/v1_image_to_video_create_body.py +101 -0
  195. magic_hour/types/params/v1_image_to_video_create_body_assets.py +33 -0
  196. magic_hour/types/params/v1_image_to_video_create_body_style.py +53 -0
  197. magic_hour/types/params/v1_image_to_video_generate_body_assets.py +17 -0
  198. magic_hour/types/params/v1_lip_sync_create_body.py +100 -0
  199. magic_hour/types/params/{post_v1_lip_sync_body_assets.py → v1_lip_sync_create_body_assets.py} +15 -5
  200. magic_hour/types/params/v1_lip_sync_create_body_style.py +37 -0
  201. magic_hour/types/params/v1_lip_sync_generate_body_assets.py +36 -0
  202. magic_hour/types/params/v1_photo_colorizer_create_body.py +40 -0
  203. magic_hour/types/params/v1_photo_colorizer_create_body_assets.py +33 -0
  204. magic_hour/types/params/v1_photo_colorizer_generate_body_assets.py +17 -0
  205. magic_hour/types/params/v1_text_to_video_create_body.py +78 -0
  206. magic_hour/types/params/v1_text_to_video_create_body_style.py +43 -0
  207. magic_hour/types/params/v1_video_to_video_create_body.py +101 -0
  208. magic_hour/types/params/{post_v1_video_to_video_body_assets.py → v1_video_to_video_create_body_assets.py} +9 -4
  209. magic_hour/types/params/{post_v1_video_to_video_body_style.py → v1_video_to_video_create_body_style.py} +68 -26
  210. magic_hour/types/params/v1_video_to_video_generate_body_assets.py +27 -0
  211. magic_hour-0.44.0.dist-info/METADATA +328 -0
  212. magic_hour-0.44.0.dist-info/RECORD +231 -0
  213. magic_hour/core/__init__.py +0 -52
  214. magic_hour/core/api_error.py +0 -56
  215. magic_hour/core/auth.py +0 -314
  216. magic_hour/core/base_client.py +0 -618
  217. magic_hour/core/binary_response.py +0 -23
  218. magic_hour/core/query.py +0 -106
  219. magic_hour/core/request.py +0 -156
  220. magic_hour/core/response.py +0 -293
  221. magic_hour/core/type_utils.py +0 -28
  222. magic_hour/core/utils.py +0 -55
  223. magic_hour/types/models/post_v1_ai_clothes_changer_response.py +0 -25
  224. magic_hour/types/models/post_v1_ai_headshot_generator_response.py +0 -25
  225. magic_hour/types/models/post_v1_ai_image_generator_response.py +0 -25
  226. magic_hour/types/models/post_v1_ai_image_upscaler_response.py +0 -25
  227. magic_hour/types/models/post_v1_ai_photo_editor_response.py +0 -25
  228. magic_hour/types/models/post_v1_ai_qr_code_generator_response.py +0 -25
  229. magic_hour/types/models/post_v1_animation_response.py +0 -25
  230. magic_hour/types/models/post_v1_face_swap_photo_response.py +0 -25
  231. magic_hour/types/models/post_v1_face_swap_response.py +0 -25
  232. magic_hour/types/models/post_v1_files_upload_urls_response.py +0 -21
  233. magic_hour/types/models/post_v1_image_background_remover_response.py +0 -25
  234. magic_hour/types/models/post_v1_image_to_video_response.py +0 -25
  235. magic_hour/types/models/post_v1_lip_sync_response.py +0 -25
  236. magic_hour/types/models/post_v1_text_to_video_response.py +0 -25
  237. magic_hour/types/models/post_v1_video_to_video_response.py +0 -25
  238. magic_hour/types/params/post_v1_ai_clothes_changer_body.py +0 -40
  239. magic_hour/types/params/post_v1_ai_clothes_changer_body_assets.py +0 -45
  240. magic_hour/types/params/post_v1_ai_headshot_generator_body.py +0 -40
  241. magic_hour/types/params/post_v1_ai_headshot_generator_body_assets.py +0 -28
  242. magic_hour/types/params/post_v1_ai_image_upscaler_body.py +0 -57
  243. magic_hour/types/params/post_v1_ai_image_upscaler_body_assets.py +0 -28
  244. magic_hour/types/params/post_v1_ai_photo_editor_body_assets.py +0 -28
  245. magic_hour/types/params/post_v1_ai_qr_code_generator_body.py +0 -45
  246. magic_hour/types/params/post_v1_face_swap_body.py +0 -72
  247. magic_hour/types/params/post_v1_face_swap_body_assets.py +0 -52
  248. magic_hour/types/params/post_v1_face_swap_photo_body.py +0 -40
  249. magic_hour/types/params/post_v1_face_swap_photo_body_assets.py +0 -36
  250. magic_hour/types/params/post_v1_files_upload_urls_body.py +0 -31
  251. magic_hour/types/params/post_v1_files_upload_urls_body_items_item.py +0 -38
  252. magic_hour/types/params/post_v1_image_background_remover_body.py +0 -40
  253. magic_hour/types/params/post_v1_image_background_remover_body_assets.py +0 -28
  254. magic_hour/types/params/post_v1_image_to_video_body.py +0 -73
  255. magic_hour/types/params/post_v1_image_to_video_body_assets.py +0 -28
  256. magic_hour/types/params/post_v1_image_to_video_body_style.py +0 -37
  257. magic_hour/types/params/post_v1_lip_sync_body.py +0 -80
  258. magic_hour/types/params/post_v1_text_to_video_body.py +0 -57
  259. magic_hour/types/params/post_v1_text_to_video_body_style.py +0 -28
  260. magic_hour/types/params/post_v1_video_to_video_body.py +0 -93
  261. magic_hour-0.9.5.dist-info/METADATA +0 -133
  262. magic_hour-0.9.5.dist-info/RECORD +0 -132
  263. {magic_hour-0.9.5.dist-info → magic_hour-0.44.0.dist-info}/LICENSE +0 -0
  264. {magic_hour-0.9.5.dist-info → magic_hour-0.44.0.dist-info}/WHEEL +0 -0
@@ -1,11 +1,121 @@
1
+ # v1.animation
1
2
 
2
- ### create <a name="create"></a>
3
- Animation
3
+ ## Module Functions
4
+
5
+ <!-- CUSTOM DOCS START -->
6
+
7
+ ### Animation Generate Workflow <a name="generate"></a>
8
+
9
+ The workflow performs the following action
10
+
11
+ 1. upload local assets to Magic Hour storage. So you can pass in a local path instead of having to upload files yourself
12
+ 2. trigger a generation
13
+ 3. poll for a completion status. This is configurable
14
+ 4. if success, download the output to local directory
15
+
16
+ > [!TIP]
17
+ > This is the recommended way to use the SDK unless you have specific needs where it is necessary to split up the actions.
18
+
19
+ #### Parameters
20
+
21
+ In Additional to the parameters listed in the `.create` section below, `.generate` introduces 3 new parameters:
22
+
23
+ - `wait_for_completion` (bool, default True): Whether to wait for the project to complete.
24
+ - `download_outputs` (bool, default True): Whether to download the generated files
25
+ - `download_directory` (str, optional): Directory to save downloaded files (defaults to current directory)
26
+
27
+ #### Synchronous Client
28
+
29
+ ```python
30
+ from magic_hour import Client
31
+ from os import getenv
32
+
33
+ client = Client(token=getenv("API_TOKEN"))
34
+ res = client.v1.animation.generate(
35
+ assets={
36
+ "audio_file_path": "/path/to/1234.mp3",
37
+ "audio_source": "file",
38
+ "image_file_path": "/path/to/1234.png",
39
+ },
40
+ end_seconds=15.0,
41
+ fps=12.0,
42
+ height=960,
43
+ style={
44
+ "art_style": "Painterly Illustration",
45
+ "camera_effect": "Simple Zoom In",
46
+ "prompt": "Cyberpunk city",
47
+ "prompt_type": "custom",
48
+ "transition_speed": 5,
49
+ },
50
+ width=512,
51
+ name="Animation video",
52
+ wait_for_completion=True,
53
+ download_outputs=True,
54
+ download_directory="outputs"
55
+ )
56
+ ```
57
+
58
+ #### Asynchronous Client
59
+
60
+ ```python
61
+ from magic_hour import AsyncClient
62
+ from os import getenv
63
+
64
+ client = AsyncClient(token=getenv("API_TOKEN"))
65
+ res = await client.v1.animation.generate(
66
+ assets={
67
+ "audio_file_path": "/path/to/1234.mp3",
68
+ "audio_source": "file",
69
+ "image_file_path": "/path/to/1234.png",
70
+ },
71
+ end_seconds=15.0,
72
+ fps=12.0,
73
+ height=960,
74
+ style={
75
+ "art_style": "Painterly Illustration",
76
+ "camera_effect": "Simple Zoom In",
77
+ "prompt": "Cyberpunk city",
78
+ "prompt_type": "custom",
79
+ "transition_speed": 5,
80
+ },
81
+ width=512,
82
+ name="Animation video",
83
+ wait_for_completion=True,
84
+ download_outputs=True,
85
+ download_directory="outputs"
86
+ )
87
+ ```
88
+
89
+ <!-- CUSTOM DOCS END -->
90
+
91
+ ### Animation <a name="create"></a>
4
92
 
5
93
  Create a Animation video. The estimated frame cost is calculated based on the `fps` and `end_seconds` input.
6
94
 
7
95
  **API Endpoint**: `POST /v1/animation`
8
96
 
97
+ #### Parameters
98
+
99
+ | Parameter | Required | Description | Example |
100
+ | --------------------- | :------: | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
101
+ | `assets` | ✓ | Provide the assets for animation. | `{"audio_file_path": "api-assets/id/1234.mp3", "audio_source": "file", "image_file_path": "api-assets/id/1234.png"}` |
102
+ | `└─ audio_file_path` | ✗ | The path of the input audio. This field is required if `audio_source` is `file`. This value is either - a direct URL to the video file - `file_path` field from the response of the [upload urls API](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls). Please refer to the [Input File documentation](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls#input-file) to learn more. | `"api-assets/id/1234.mp3"` |
103
+ | `└─ audio_source` | ✓ | Optionally add an audio source if you'd like to incorporate audio into your video | `"file"` |
104
+ | `└─ image_file_path` | ✗ | An initial image to use a the first frame of the video. This value is either - a direct URL to the video file - `file_path` field from the response of the [upload urls API](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls). Please refer to the [Input File documentation](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls#input-file) to learn more. | `"api-assets/id/1234.png"` |
105
+ | `└─ youtube_url` | ✗ | Using a youtube video as the input source. This field is required if `audio_source` is `youtube` | `"http://www.example.com"` |
106
+ | `end_seconds` | ✓ | This value determines the duration of the output video. | `15.0` |
107
+ | `fps` | ✓ | The desire output video frame rate | `12.0` |
108
+ | `height` | ✓ | The height of the final output video. The maximum height depends on your subscription. Please refer to our [pricing page](https://magichour.ai/pricing) for more details | `960` |
109
+ | `style` | ✓ | Defines the style of the output video | `{"art_style": "Painterly Illustration", "camera_effect": "Simple Zoom In", "prompt": "Cyberpunk city", "prompt_type": "custom", "transition_speed": 5}` |
110
+ | `└─ art_style` | ✓ | The art style used to create the output video | `"Painterly Illustration"` |
111
+ | `└─ art_style_custom` | ✗ | Describe custom art style. This field is required if `art_style` is `Custom` | `"string"` |
112
+ | `└─ camera_effect` | ✓ | The camera effect used to create the output video | `"Simple Zoom In"` |
113
+ | `└─ prompt` | ✗ | The prompt used for the video. Prompt is required if `prompt_type` is `custom`. Otherwise this value is ignored | `"Cyberpunk city"` |
114
+ | `└─ prompt_type` | ✓ | * `custom` - Use your own prompt for the video. * `use_lyrics` - Use the lyrics of the audio to create the prompt. If this option is selected, then `assets.audio_source` must be `file` or `youtube`. * `ai_choose` - Let AI write the prompt. If this option is selected, then `assets.audio_source` must be `file` or `youtube`. | `"custom"` |
115
+ | `└─ transition_speed` | ✓ | Change determines how quickly the video's content changes across frames. * Higher = more rapid transitions. * Lower = more stable visual experience. | `5` |
116
+ | `width` | ✓ | The width of the final output video. The maximum width depends on your subscription. Please refer to our [pricing page](https://magichour.ai/pricing) for more details | `512` |
117
+ | `name` | ✗ | The name of video. This value is mainly used for your own identification of the video. | `"Animation video"` |
118
+
9
119
  #### Synchronous Client
10
120
 
11
121
  ```python
@@ -24,9 +134,9 @@ res = client.v1.animation.create(
24
134
  height=960,
25
135
  style={
26
136
  "art_style": "Painterly Illustration",
27
- "camera_effect": "Accelerate",
137
+ "camera_effect": "Simple Zoom In",
28
138
  "prompt": "Cyberpunk city",
29
- "prompt_type": "ai_choose",
139
+ "prompt_type": "custom",
30
140
  "transition_speed": 5,
31
141
  },
32
142
  width=512,
@@ -52,12 +162,24 @@ res = await client.v1.animation.create(
52
162
  height=960,
53
163
  style={
54
164
  "art_style": "Painterly Illustration",
55
- "camera_effect": "Accelerate",
165
+ "camera_effect": "Simple Zoom In",
56
166
  "prompt": "Cyberpunk city",
57
- "prompt_type": "ai_choose",
167
+ "prompt_type": "custom",
58
168
  "transition_speed": 5,
59
169
  },
60
170
  width=512,
61
171
  name="Animation video",
62
172
  )
63
173
  ```
174
+
175
+ #### Response
176
+
177
+ ##### Type
178
+
179
+ [V1AnimationCreateResponse](/magic_hour/types/models/v1_animation_create_response.py)
180
+
181
+ ##### Example
182
+
183
+ ```python
184
+ {"credits_charged": 450, "estimated_frame_cost": 450, "id": "cuid-example"}
185
+ ```
@@ -1,6 +1,13 @@
1
1
  import typing
2
2
 
3
- from magic_hour.core import (
3
+ from magic_hour.helpers.logger import get_sdk_logger
4
+ from magic_hour.resources.v1.files.client import AsyncFilesClient, FilesClient
5
+ from magic_hour.resources.v1.video_projects.client import (
6
+ AsyncVideoProjectsClient,
7
+ VideoProjectsClient,
8
+ )
9
+ from magic_hour.types import models, params
10
+ from make_api_request import (
4
11
  AsyncBaseClient,
5
12
  RequestOptions,
6
13
  SyncBaseClient,
@@ -8,27 +15,131 @@ from magic_hour.core import (
8
15
  to_encodable,
9
16
  type_utils,
10
17
  )
11
- from magic_hour.types import models, params
18
+
19
+
20
+ logger = get_sdk_logger(__name__)
12
21
 
13
22
 
14
23
  class AnimationClient:
15
24
  def __init__(self, *, base_client: SyncBaseClient):
16
25
  self._base_client = base_client
17
26
 
27
+ def generate(
28
+ self,
29
+ *,
30
+ assets: params.V1AnimationGenerateBodyAssets,
31
+ end_seconds: float,
32
+ fps: float,
33
+ height: int,
34
+ style: params.V1AnimationCreateBodyStyle,
35
+ width: int,
36
+ name: typing.Union[
37
+ typing.Optional[str], type_utils.NotGiven
38
+ ] = type_utils.NOT_GIVEN,
39
+ wait_for_completion: bool = True,
40
+ download_outputs: bool = True,
41
+ download_directory: typing.Optional[str] = None,
42
+ request_options: typing.Optional[RequestOptions] = None,
43
+ ):
44
+ """
45
+ Generate animation (alias for create with additional functionality).
46
+
47
+ Create a Animation video. The estimated frame cost is calculated based on the `fps` and `end_seconds` input.
48
+
49
+ Args:
50
+ name: The name of video. This value is mainly used for your own identification of the video.
51
+ assets: Provide the assets for animation.
52
+ end_seconds: This value determines the duration of the output video.
53
+ fps: The desire output video frame rate
54
+ height: The height of the final output video. The maximum height depends on your subscription. Please refer to our [pricing page](https://magichour.ai/pricing) for more details
55
+ style: Defines the style of the output video
56
+ width: The width of the final output video. The maximum width depends on your subscription. Please refer to our [pricing page](https://magichour.ai/pricing) for more details
57
+ wait_for_completion: Whether to wait for the video project to complete
58
+ download_outputs: Whether to download the outputs
59
+ download_directory: The directory to download the outputs to. If not provided, the outputs will be downloaded to the current working directory
60
+ request_options: Additional options to customize the HTTP request
61
+
62
+ Returns:
63
+ V1VideoProjectsGetResponseWithDownloads: The response from the Animation API with the downloaded paths if `download_outputs` is True.
64
+
65
+ Examples:
66
+ ```py
67
+ response = client.v1.animation.generate(
68
+ assets={
69
+ "audio_file_path": "path/to/audio.mp3",
70
+ "audio_source": "file",
71
+ "image_file_path": "path/to/image.png",
72
+ },
73
+ end_seconds=15.0,
74
+ fps=12.0,
75
+ height=960,
76
+ style={
77
+ "art_style": "Painterly Illustration",
78
+ "camera_effect": "Simple Zoom In",
79
+ "prompt": "Cyberpunk city",
80
+ "prompt_type": "custom",
81
+ "transition_speed": 5,
82
+ },
83
+ width=512,
84
+ wait_for_completion=True,
85
+ download_outputs=True,
86
+ download_directory="outputs/",
87
+ )
88
+ ```
89
+ """
90
+
91
+ file_client = FilesClient(base_client=self._base_client)
92
+
93
+ # Upload image file if provided
94
+ if "image_file_path" in assets and assets["image_file_path"]:
95
+ image_file_path = assets["image_file_path"]
96
+ assets["image_file_path"] = file_client.upload_file(file=image_file_path)
97
+
98
+ # Upload audio file if audio_source is "file" and audio_file_path is provided
99
+ if (
100
+ assets.get("audio_source") == "file"
101
+ and "audio_file_path" in assets
102
+ and assets["audio_file_path"]
103
+ ):
104
+ audio_file_path = assets["audio_file_path"]
105
+ assets["audio_file_path"] = file_client.upload_file(file=audio_file_path)
106
+
107
+ create_response = self.create(
108
+ assets=assets,
109
+ end_seconds=end_seconds,
110
+ fps=fps,
111
+ height=height,
112
+ style=style,
113
+ width=width,
114
+ name=name,
115
+ request_options=request_options,
116
+ )
117
+ logger.info(f"Animation response: {create_response}")
118
+
119
+ video_projects_client = VideoProjectsClient(base_client=self._base_client)
120
+ response = video_projects_client.check_result(
121
+ id=create_response.id,
122
+ wait_for_completion=wait_for_completion,
123
+ download_outputs=download_outputs,
124
+ download_directory=download_directory,
125
+ )
126
+
127
+ return response
128
+
18
129
  def create(
19
130
  self,
20
131
  *,
21
- assets: params.PostV1AnimationBodyAssets,
132
+ assets: params.V1AnimationCreateBodyAssets,
22
133
  end_seconds: float,
23
134
  fps: float,
24
135
  height: int,
25
- style: params.PostV1AnimationBodyStyle,
136
+ style: params.V1AnimationCreateBodyStyle,
26
137
  width: int,
27
138
  name: typing.Union[
28
139
  typing.Optional[str], type_utils.NotGiven
29
140
  ] = type_utils.NOT_GIVEN,
30
141
  request_options: typing.Optional[RequestOptions] = None,
31
- ) -> models.PostV1AnimationResponse:
142
+ ) -> models.V1AnimationCreateResponse:
32
143
  """
33
144
  Animation
34
145
 
@@ -37,9 +148,9 @@ class AnimationClient:
37
148
  POST /v1/animation
38
149
 
39
150
  Args:
40
- name: The name of video
151
+ name: The name of video. This value is mainly used for your own identification of the video.
41
152
  assets: Provide the assets for animation.
42
- end_seconds: The end time of the input video in seconds
153
+ end_seconds: This value determines the duration of the output video.
43
154
  fps: The desire output video frame rate
44
155
  height: The height of the final output video. The maximum height depends on your subscription. Please refer to our [pricing page](https://magichour.ai/pricing) for more details
45
156
  style: Defines the style of the output video
@@ -56,15 +167,19 @@ class AnimationClient:
56
167
  Examples:
57
168
  ```py
58
169
  client.v1.animation.create(
59
- assets={"audio_source": "file"},
170
+ assets={
171
+ "audio_file_path": "api-assets/id/1234.mp3",
172
+ "audio_source": "file",
173
+ "image_file_path": "api-assets/id/1234.png",
174
+ },
60
175
  end_seconds=15.0,
61
176
  fps=12.0,
62
177
  height=960,
63
178
  style={
64
179
  "art_style": "Painterly Illustration",
65
- "camera_effect": "Accelerate",
180
+ "camera_effect": "Simple Zoom In",
66
181
  "prompt": "Cyberpunk city",
67
- "prompt_type": "ai_choose",
182
+ "prompt_type": "custom",
68
183
  "transition_speed": 5,
69
184
  },
70
185
  width=512,
@@ -82,14 +197,14 @@ class AnimationClient:
82
197
  "style": style,
83
198
  "width": width,
84
199
  },
85
- dump_with=params._SerializerPostV1AnimationBody,
200
+ dump_with=params._SerializerV1AnimationCreateBody,
86
201
  )
87
202
  return self._base_client.request(
88
203
  method="POST",
89
204
  path="/v1/animation",
90
205
  auth_names=["bearerAuth"],
91
206
  json=_json,
92
- cast_to=models.PostV1AnimationResponse,
207
+ cast_to=models.V1AnimationCreateResponse,
93
208
  request_options=request_options or default_request_options(),
94
209
  )
95
210
 
@@ -98,20 +213,126 @@ class AsyncAnimationClient:
98
213
  def __init__(self, *, base_client: AsyncBaseClient):
99
214
  self._base_client = base_client
100
215
 
216
+ async def generate(
217
+ self,
218
+ *,
219
+ assets: params.V1AnimationGenerateBodyAssets,
220
+ end_seconds: float,
221
+ fps: float,
222
+ height: int,
223
+ style: params.V1AnimationCreateBodyStyle,
224
+ width: int,
225
+ name: typing.Union[
226
+ typing.Optional[str], type_utils.NotGiven
227
+ ] = type_utils.NOT_GIVEN,
228
+ wait_for_completion: bool = True,
229
+ download_outputs: bool = True,
230
+ download_directory: typing.Optional[str] = None,
231
+ request_options: typing.Optional[RequestOptions] = None,
232
+ ):
233
+ """
234
+ Generate animation (alias for create with additional functionality).
235
+
236
+ Create a Animation video. The estimated frame cost is calculated based on the `fps` and `end_seconds` input.
237
+
238
+ Args:
239
+ name: The name of video. This value is mainly used for your own identification of the video.
240
+ assets: Provide the assets for animation.
241
+ end_seconds: This value determines the duration of the output video.
242
+ fps: The desire output video frame rate
243
+ height: The height of the final output video. The maximum height depends on your subscription. Please refer to our [pricing page](https://magichour.ai/pricing) for more details
244
+ style: Defines the style of the output video
245
+ width: The width of the final output video. The maximum width depends on your subscription. Please refer to our [pricing page](https://magichour.ai/pricing) for more details
246
+ wait_for_completion: Whether to wait for the video project to complete
247
+ download_outputs: Whether to download the outputs
248
+ download_directory: The directory to download the outputs to. If not provided, the outputs will be downloaded to the current working directory
249
+ request_options: Additional options to customize the HTTP request
250
+
251
+ Returns:
252
+ V1VideoProjectsGetResponseWithDownloads: The response from the Animation API with the downloaded paths if `download_outputs` is True.
253
+
254
+ Examples:
255
+ ```py
256
+ response = await client.v1.animation.generate(
257
+ assets={
258
+ "audio_file_path": "path/to/audio.mp3",
259
+ "audio_source": "file",
260
+ "image_file_path": "path/to/image.png",
261
+ },
262
+ end_seconds=15.0,
263
+ fps=12.0,
264
+ height=960,
265
+ style={
266
+ "art_style": "Painterly Illustration",
267
+ "camera_effect": "Simple Zoom In",
268
+ "prompt": "Cyberpunk city",
269
+ "prompt_type": "custom",
270
+ "transition_speed": 5,
271
+ },
272
+ width=512,
273
+ wait_for_completion=True,
274
+ download_outputs=True,
275
+ download_directory="outputs/",
276
+ )
277
+ ```
278
+ """
279
+
280
+ file_client = AsyncFilesClient(base_client=self._base_client)
281
+
282
+ # Upload image file if provided
283
+ if "image_file_path" in assets and assets["image_file_path"]:
284
+ image_file_path = assets["image_file_path"]
285
+ assets["image_file_path"] = await file_client.upload_file(
286
+ file=image_file_path
287
+ )
288
+
289
+ # Upload audio file if audio_source is "file" and audio_file_path is provided
290
+ if (
291
+ assets.get("audio_source") == "file"
292
+ and "audio_file_path" in assets
293
+ and assets["audio_file_path"]
294
+ ):
295
+ audio_file_path = assets["audio_file_path"]
296
+ assets["audio_file_path"] = await file_client.upload_file(
297
+ file=audio_file_path
298
+ )
299
+
300
+ create_response = await self.create(
301
+ assets=assets,
302
+ end_seconds=end_seconds,
303
+ fps=fps,
304
+ height=height,
305
+ style=style,
306
+ width=width,
307
+ name=name,
308
+ request_options=request_options,
309
+ )
310
+ logger.info(f"Animation response: {create_response}")
311
+
312
+ video_projects_client = AsyncVideoProjectsClient(base_client=self._base_client)
313
+ response = await video_projects_client.check_result(
314
+ id=create_response.id,
315
+ wait_for_completion=wait_for_completion,
316
+ download_outputs=download_outputs,
317
+ download_directory=download_directory,
318
+ )
319
+
320
+ return response
321
+
101
322
  async def create(
102
323
  self,
103
324
  *,
104
- assets: params.PostV1AnimationBodyAssets,
325
+ assets: params.V1AnimationCreateBodyAssets,
105
326
  end_seconds: float,
106
327
  fps: float,
107
328
  height: int,
108
- style: params.PostV1AnimationBodyStyle,
329
+ style: params.V1AnimationCreateBodyStyle,
109
330
  width: int,
110
331
  name: typing.Union[
111
332
  typing.Optional[str], type_utils.NotGiven
112
333
  ] = type_utils.NOT_GIVEN,
113
334
  request_options: typing.Optional[RequestOptions] = None,
114
- ) -> models.PostV1AnimationResponse:
335
+ ) -> models.V1AnimationCreateResponse:
115
336
  """
116
337
  Animation
117
338
 
@@ -120,9 +341,9 @@ class AsyncAnimationClient:
120
341
  POST /v1/animation
121
342
 
122
343
  Args:
123
- name: The name of video
344
+ name: The name of video. This value is mainly used for your own identification of the video.
124
345
  assets: Provide the assets for animation.
125
- end_seconds: The end time of the input video in seconds
346
+ end_seconds: This value determines the duration of the output video.
126
347
  fps: The desire output video frame rate
127
348
  height: The height of the final output video. The maximum height depends on your subscription. Please refer to our [pricing page](https://magichour.ai/pricing) for more details
128
349
  style: Defines the style of the output video
@@ -139,15 +360,19 @@ class AsyncAnimationClient:
139
360
  Examples:
140
361
  ```py
141
362
  await client.v1.animation.create(
142
- assets={"audio_source": "file"},
363
+ assets={
364
+ "audio_file_path": "api-assets/id/1234.mp3",
365
+ "audio_source": "file",
366
+ "image_file_path": "api-assets/id/1234.png",
367
+ },
143
368
  end_seconds=15.0,
144
369
  fps=12.0,
145
370
  height=960,
146
371
  style={
147
372
  "art_style": "Painterly Illustration",
148
- "camera_effect": "Accelerate",
373
+ "camera_effect": "Simple Zoom In",
149
374
  "prompt": "Cyberpunk city",
150
- "prompt_type": "ai_choose",
375
+ "prompt_type": "custom",
151
376
  "transition_speed": 5,
152
377
  },
153
378
  width=512,
@@ -165,13 +390,13 @@ class AsyncAnimationClient:
165
390
  "style": style,
166
391
  "width": width,
167
392
  },
168
- dump_with=params._SerializerPostV1AnimationBody,
393
+ dump_with=params._SerializerV1AnimationCreateBody,
169
394
  )
170
395
  return await self._base_client.request(
171
396
  method="POST",
172
397
  path="/v1/animation",
173
398
  auth_names=["bearerAuth"],
174
399
  json=_json,
175
- cast_to=models.PostV1AnimationResponse,
400
+ cast_to=models.V1AnimationCreateResponse,
176
401
  request_options=request_options or default_request_options(),
177
402
  )