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,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,43 +15,173 @@ 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 FaceSwapClient:
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.V1FaceSwapGenerateBodyAssets,
31
+ end_seconds: float,
32
+ start_seconds: float,
33
+ height: typing.Union[
34
+ typing.Optional[int], type_utils.NotGiven
35
+ ] = type_utils.NOT_GIVEN,
36
+ name: typing.Union[
37
+ typing.Optional[str], type_utils.NotGiven
38
+ ] = type_utils.NOT_GIVEN,
39
+ style: typing.Union[
40
+ typing.Optional[params.V1FaceSwapCreateBodyStyle], type_utils.NotGiven
41
+ ] = type_utils.NOT_GIVEN,
42
+ width: typing.Union[
43
+ typing.Optional[int], type_utils.NotGiven
44
+ ] = type_utils.NOT_GIVEN,
45
+ wait_for_completion: bool = True,
46
+ download_outputs: bool = True,
47
+ download_directory: typing.Optional[str] = None,
48
+ request_options: typing.Optional[RequestOptions] = None,
49
+ ):
50
+ """
51
+ Generate face swap video (alias for create with additional functionality).
52
+
53
+ Create a Face Swap video. The estimated frame cost is calculated using 30 FPS. This amount is deducted from your account balance when a video is queued. Once the video is complete, the cost will be updated based on the actual number of frames rendered.
54
+
55
+ Args:
56
+ height: `height` is deprecated and no longer influences the output video's resolution.
57
+ name: The name of video. This value is mainly used for your own identification of the video.
58
+ width: `width` is deprecated and no longer influences the output video's resolution.
59
+ assets: Provide the assets for face swap. For video, The `video_source` field determines whether `video_file_path` or `youtube_url` field is used
60
+ end_seconds: The end time of the input video in seconds. This value is used to trim the input video. The value must be greater than 0.1, and more than the start_seconds.
61
+ start_seconds: The start time of the input video in seconds. This value is used to trim the input video. The value must be greater than 0.
62
+ wait_for_completion: Whether to wait for the video project to complete
63
+ download_outputs: Whether to download the outputs
64
+ download_directory: The directory to download the outputs to. If not provided, the outputs will be downloaded to the current working directory
65
+ request_options: Additional options to customize the HTTP request
66
+
67
+ Returns:
68
+ V1VideoProjectsGetResponseWithDownloads: The response from the Face Swap API with the downloaded paths if `download_outputs` is True.
69
+
70
+ Examples:
71
+ ```py
72
+ response = client.v1.face_swap.generate(
73
+ assets={
74
+ "face_swap_mode": "all-faces",
75
+ "video_file_path": "path/to/video.mp4",
76
+ "video_source": "file",
77
+ "image_file_path": "path/to/image.png",
78
+ },
79
+ end_seconds=15.0,
80
+ start_seconds=0.0,
81
+ wait_for_completion=True,
82
+ download_outputs=True,
83
+ download_directory="outputs/",
84
+ )
85
+ ```
86
+ """
87
+
88
+ file_client = FilesClient(base_client=self._base_client)
89
+
90
+ # Upload image file if provided (required for all-faces mode)
91
+ if "image_file_path" in assets and assets["image_file_path"]:
92
+ image_file_path = assets["image_file_path"]
93
+ assets["image_file_path"] = file_client.upload_file(file=image_file_path)
94
+
95
+ # Upload video file if video_source is "file" and video_file_path is provided
96
+ if (
97
+ assets.get("video_source") == "file"
98
+ and "video_file_path" in assets
99
+ and assets["video_file_path"]
100
+ ):
101
+ video_file_path = assets["video_file_path"]
102
+ assets["video_file_path"] = file_client.upload_file(file=video_file_path)
103
+
104
+ # Upload face mappings if present
105
+ if "face_mappings" in assets and assets["face_mappings"]:
106
+ for face_mapping in assets["face_mappings"]:
107
+ if "new_face" in face_mapping and face_mapping["new_face"]:
108
+ new_face_file_path = face_mapping["new_face"]
109
+ face_mapping["new_face"] = file_client.upload_file(
110
+ file=new_face_file_path
111
+ )
112
+
113
+ create_response = self.create(
114
+ assets=assets,
115
+ end_seconds=end_seconds,
116
+ start_seconds=start_seconds,
117
+ height=height,
118
+ name=name,
119
+ style=style,
120
+ width=width,
121
+ request_options=request_options,
122
+ )
123
+ logger.info(f"Face Swap response: {create_response}")
124
+
125
+ video_projects_client = VideoProjectsClient(base_client=self._base_client)
126
+ response = video_projects_client.check_result(
127
+ id=create_response.id,
128
+ wait_for_completion=wait_for_completion,
129
+ download_outputs=download_outputs,
130
+ download_directory=download_directory,
131
+ )
132
+
133
+ return response
134
+
18
135
  def create(
19
136
  self,
20
137
  *,
21
- assets: params.PostV1FaceSwapBodyAssets,
138
+ assets: params.V1FaceSwapCreateBodyAssets,
22
139
  end_seconds: float,
23
- height: int,
24
140
  start_seconds: float,
25
- width: int,
141
+ height: typing.Union[
142
+ typing.Optional[int], type_utils.NotGiven
143
+ ] = type_utils.NOT_GIVEN,
26
144
  name: typing.Union[
27
145
  typing.Optional[str], type_utils.NotGiven
28
146
  ] = type_utils.NOT_GIVEN,
147
+ style: typing.Union[
148
+ typing.Optional[params.V1FaceSwapCreateBodyStyle], type_utils.NotGiven
149
+ ] = type_utils.NOT_GIVEN,
150
+ width: typing.Union[
151
+ typing.Optional[int], type_utils.NotGiven
152
+ ] = type_utils.NOT_GIVEN,
29
153
  request_options: typing.Optional[RequestOptions] = None,
30
- ) -> models.PostV1FaceSwapResponse:
154
+ ) -> models.V1FaceSwapCreateResponse:
31
155
  """
32
- Face Swap video
156
+ Face Swap Video
33
157
 
34
158
  Create a Face Swap video. The estimated frame cost is calculated using 30 FPS. This amount is deducted from your account balance when a video is queued. Once the video is complete, the cost will be updated based on the actual number of frames rendered.
35
159
 
36
- Get more information about this mode at our [product page](/products/face-swap).
160
+ Get more information about this mode at our [product page](https://magichour.ai/products/face-swap).
37
161
 
38
162
 
39
163
  POST /v1/face-swap
40
164
 
41
165
  Args:
42
- name: The name of video
166
+ height: `height` is deprecated and no longer influences the output video's resolution.
167
+
168
+ Output resolution is determined by the **minimum** of:
169
+ - The resolution of the input video
170
+ - The maximum resolution allowed by your subscription tier. See our [pricing page](https://magichour.ai/pricing) for more details.
171
+
172
+ This field is retained only for backward compatibility and will be removed in a future release.
173
+ name: The name of video. This value is mainly used for your own identification of the video.
174
+ style: Style of the face swap video.
175
+ width: `width` is deprecated and no longer influences the output video's resolution.
176
+
177
+ Output resolution is determined by the **minimum** of:
178
+ - The resolution of the input video
179
+ - The maximum resolution allowed by your subscription tier. See our [pricing page](https://magichour.ai/pricing) for more details.
180
+
181
+ This field is retained only for backward compatibility and will be removed in a future release.
43
182
  assets: Provide the assets for face swap. For video, The `video_source` field determines whether `video_file_path` or `youtube_url` field is used
44
- end_seconds: The end time of the input video in seconds
45
- 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
46
- start_seconds: The start time of the input video in seconds
47
- 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
183
+ end_seconds: The end time of the input video in seconds. This value is used to trim the input video. The value must be greater than 0.1, and more than the start_seconds.
184
+ start_seconds: The start time of the input video in seconds. This value is used to trim the input video. The value must be greater than 0.
48
185
  request_options: Additional options to customize the HTTP request
49
186
 
50
187
  Returns:
@@ -57,32 +194,43 @@ class FaceSwapClient:
57
194
  Examples:
58
195
  ```py
59
196
  client.v1.face_swap.create(
60
- assets={"image_file_path": "image/id/1234.png", "video_source": "file"},
197
+ assets={
198
+ "face_mappings": [
199
+ {
200
+ "new_face": "api-assets/id/1234.png",
201
+ "original_face": "api-assets/id/0-0.png",
202
+ }
203
+ ],
204
+ "face_swap_mode": "all-faces",
205
+ "image_file_path": "image/id/1234.png",
206
+ "video_file_path": "api-assets/id/1234.mp4",
207
+ "video_source": "file",
208
+ },
61
209
  end_seconds=15.0,
62
- height=960,
63
210
  start_seconds=0.0,
64
- width=512,
65
211
  name="Face Swap video",
212
+ style={"version": "default"},
66
213
  )
67
214
  ```
68
215
  """
69
216
  _json = to_encodable(
70
217
  item={
218
+ "height": height,
71
219
  "name": name,
220
+ "style": style,
221
+ "width": width,
72
222
  "assets": assets,
73
223
  "end_seconds": end_seconds,
74
- "height": height,
75
224
  "start_seconds": start_seconds,
76
- "width": width,
77
225
  },
78
- dump_with=params._SerializerPostV1FaceSwapBody,
226
+ dump_with=params._SerializerV1FaceSwapCreateBody,
79
227
  )
80
228
  return self._base_client.request(
81
229
  method="POST",
82
230
  path="/v1/face-swap",
83
231
  auth_names=["bearerAuth"],
84
232
  json=_json,
85
- cast_to=models.PostV1FaceSwapResponse,
233
+ cast_to=models.V1FaceSwapCreateResponse,
86
234
  request_options=request_options or default_request_options(),
87
235
  )
88
236
 
@@ -91,36 +239,168 @@ class AsyncFaceSwapClient:
91
239
  def __init__(self, *, base_client: AsyncBaseClient):
92
240
  self._base_client = base_client
93
241
 
242
+ async def generate(
243
+ self,
244
+ *,
245
+ assets: params.V1FaceSwapGenerateBodyAssets,
246
+ end_seconds: float,
247
+ start_seconds: float,
248
+ height: typing.Union[
249
+ typing.Optional[int], type_utils.NotGiven
250
+ ] = type_utils.NOT_GIVEN,
251
+ name: typing.Union[
252
+ typing.Optional[str], type_utils.NotGiven
253
+ ] = type_utils.NOT_GIVEN,
254
+ style: typing.Union[
255
+ typing.Optional[params.V1FaceSwapCreateBodyStyle], type_utils.NotGiven
256
+ ] = type_utils.NOT_GIVEN,
257
+ width: typing.Union[
258
+ typing.Optional[int], type_utils.NotGiven
259
+ ] = type_utils.NOT_GIVEN,
260
+ wait_for_completion: bool = True,
261
+ download_outputs: bool = True,
262
+ download_directory: typing.Optional[str] = None,
263
+ request_options: typing.Optional[RequestOptions] = None,
264
+ ):
265
+ """
266
+ Generate face swap video (alias for create with additional functionality).
267
+
268
+ Create a Face Swap video. The estimated frame cost is calculated using 30 FPS. This amount is deducted from your account balance when a video is queued. Once the video is complete, the cost will be updated based on the actual number of frames rendered.
269
+
270
+ Args:
271
+ height: `height` is deprecated and no longer influences the output video's resolution.
272
+ name: The name of video. This value is mainly used for your own identification of the video.
273
+ width: `width` is deprecated and no longer influences the output video's resolution.
274
+ assets: Provide the assets for face swap. For video, The `video_source` field determines whether `video_file_path` or `youtube_url` field is used
275
+ end_seconds: The end time of the input video in seconds. This value is used to trim the input video. The value must be greater than 0.1, and more than the start_seconds.
276
+ start_seconds: The start time of the input video in seconds. This value is used to trim the input video. The value must be greater than 0.
277
+ wait_for_completion: Whether to wait for the video project to complete
278
+ download_outputs: Whether to download the outputs
279
+ download_directory: The directory to download the outputs to. If not provided, the outputs will be downloaded to the current working directory
280
+ request_options: Additional options to customize the HTTP request
281
+
282
+ Returns:
283
+ V1VideoProjectsGetResponseWithDownloads: The response from the Face Swap API with the downloaded paths if `download_outputs` is True.
284
+
285
+ Examples:
286
+ ```py
287
+ response = await client.v1.face_swap.generate(
288
+ assets={
289
+ "face_swap_mode": "all-faces",
290
+ "video_file_path": "path/to/video.mp4",
291
+ "video_source": "file",
292
+ "image_file_path": "path/to/image.png",
293
+ },
294
+ end_seconds=15.0,
295
+ start_seconds=0.0,
296
+ wait_for_completion=True,
297
+ download_outputs=True,
298
+ download_directory="outputs/",
299
+ )
300
+ ```
301
+ """
302
+
303
+ file_client = AsyncFilesClient(base_client=self._base_client)
304
+
305
+ # Upload image file if provided (required for all-faces mode)
306
+ if "image_file_path" in assets and assets["image_file_path"]:
307
+ image_file_path = assets["image_file_path"]
308
+ assets["image_file_path"] = await file_client.upload_file(
309
+ file=image_file_path
310
+ )
311
+
312
+ # Upload video file if video_source is "file" and video_file_path is provided
313
+ if (
314
+ assets.get("video_source") == "file"
315
+ and "video_file_path" in assets
316
+ and assets["video_file_path"]
317
+ ):
318
+ video_file_path = assets["video_file_path"]
319
+ assets["video_file_path"] = await file_client.upload_file(
320
+ file=video_file_path
321
+ )
322
+
323
+ # Upload face mappings if present
324
+ if "face_mappings" in assets and assets["face_mappings"]:
325
+ for face_mapping in assets["face_mappings"]:
326
+ if "new_face" in face_mapping and face_mapping["new_face"]:
327
+ new_face_file_path = face_mapping["new_face"]
328
+ face_mapping["new_face"] = await file_client.upload_file(
329
+ file=new_face_file_path
330
+ )
331
+
332
+ create_response = await self.create(
333
+ assets=assets,
334
+ end_seconds=end_seconds,
335
+ start_seconds=start_seconds,
336
+ height=height,
337
+ name=name,
338
+ style=style,
339
+ width=width,
340
+ request_options=request_options,
341
+ )
342
+ logger.info(f"Face Swap response: {create_response}")
343
+
344
+ video_projects_client = AsyncVideoProjectsClient(base_client=self._base_client)
345
+ response = await video_projects_client.check_result(
346
+ id=create_response.id,
347
+ wait_for_completion=wait_for_completion,
348
+ download_outputs=download_outputs,
349
+ download_directory=download_directory,
350
+ )
351
+
352
+ return response
353
+
94
354
  async def create(
95
355
  self,
96
356
  *,
97
- assets: params.PostV1FaceSwapBodyAssets,
357
+ assets: params.V1FaceSwapCreateBodyAssets,
98
358
  end_seconds: float,
99
- height: int,
100
359
  start_seconds: float,
101
- width: int,
360
+ height: typing.Union[
361
+ typing.Optional[int], type_utils.NotGiven
362
+ ] = type_utils.NOT_GIVEN,
102
363
  name: typing.Union[
103
364
  typing.Optional[str], type_utils.NotGiven
104
365
  ] = type_utils.NOT_GIVEN,
366
+ style: typing.Union[
367
+ typing.Optional[params.V1FaceSwapCreateBodyStyle], type_utils.NotGiven
368
+ ] = type_utils.NOT_GIVEN,
369
+ width: typing.Union[
370
+ typing.Optional[int], type_utils.NotGiven
371
+ ] = type_utils.NOT_GIVEN,
105
372
  request_options: typing.Optional[RequestOptions] = None,
106
- ) -> models.PostV1FaceSwapResponse:
373
+ ) -> models.V1FaceSwapCreateResponse:
107
374
  """
108
- Face Swap video
375
+ Face Swap Video
109
376
 
110
377
  Create a Face Swap video. The estimated frame cost is calculated using 30 FPS. This amount is deducted from your account balance when a video is queued. Once the video is complete, the cost will be updated based on the actual number of frames rendered.
111
378
 
112
- Get more information about this mode at our [product page](/products/face-swap).
379
+ Get more information about this mode at our [product page](https://magichour.ai/products/face-swap).
113
380
 
114
381
 
115
382
  POST /v1/face-swap
116
383
 
117
384
  Args:
118
- name: The name of video
385
+ height: `height` is deprecated and no longer influences the output video's resolution.
386
+
387
+ Output resolution is determined by the **minimum** of:
388
+ - The resolution of the input video
389
+ - The maximum resolution allowed by your subscription tier. See our [pricing page](https://magichour.ai/pricing) for more details.
390
+
391
+ This field is retained only for backward compatibility and will be removed in a future release.
392
+ name: The name of video. This value is mainly used for your own identification of the video.
393
+ style: Style of the face swap video.
394
+ width: `width` is deprecated and no longer influences the output video's resolution.
395
+
396
+ Output resolution is determined by the **minimum** of:
397
+ - The resolution of the input video
398
+ - The maximum resolution allowed by your subscription tier. See our [pricing page](https://magichour.ai/pricing) for more details.
399
+
400
+ This field is retained only for backward compatibility and will be removed in a future release.
119
401
  assets: Provide the assets for face swap. For video, The `video_source` field determines whether `video_file_path` or `youtube_url` field is used
120
- end_seconds: The end time of the input video in seconds
121
- 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
122
- start_seconds: The start time of the input video in seconds
123
- 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
402
+ end_seconds: The end time of the input video in seconds. This value is used to trim the input video. The value must be greater than 0.1, and more than the start_seconds.
403
+ start_seconds: The start time of the input video in seconds. This value is used to trim the input video. The value must be greater than 0.
124
404
  request_options: Additional options to customize the HTTP request
125
405
 
126
406
  Returns:
@@ -133,31 +413,42 @@ class AsyncFaceSwapClient:
133
413
  Examples:
134
414
  ```py
135
415
  await client.v1.face_swap.create(
136
- assets={"image_file_path": "image/id/1234.png", "video_source": "file"},
416
+ assets={
417
+ "face_mappings": [
418
+ {
419
+ "new_face": "api-assets/id/1234.png",
420
+ "original_face": "api-assets/id/0-0.png",
421
+ }
422
+ ],
423
+ "face_swap_mode": "all-faces",
424
+ "image_file_path": "image/id/1234.png",
425
+ "video_file_path": "api-assets/id/1234.mp4",
426
+ "video_source": "file",
427
+ },
137
428
  end_seconds=15.0,
138
- height=960,
139
429
  start_seconds=0.0,
140
- width=512,
141
430
  name="Face Swap video",
431
+ style={"version": "default"},
142
432
  )
143
433
  ```
144
434
  """
145
435
  _json = to_encodable(
146
436
  item={
437
+ "height": height,
147
438
  "name": name,
439
+ "style": style,
440
+ "width": width,
148
441
  "assets": assets,
149
442
  "end_seconds": end_seconds,
150
- "height": height,
151
443
  "start_seconds": start_seconds,
152
- "width": width,
153
444
  },
154
- dump_with=params._SerializerPostV1FaceSwapBody,
445
+ dump_with=params._SerializerV1FaceSwapCreateBody,
155
446
  )
156
447
  return await self._base_client.request(
157
448
  method="POST",
158
449
  path="/v1/face-swap",
159
450
  auth_names=["bearerAuth"],
160
451
  json=_json,
161
- cast_to=models.PostV1FaceSwapResponse,
452
+ cast_to=models.V1FaceSwapCreateResponse,
162
453
  request_options=request_options or default_request_options(),
163
454
  )
@@ -1,11 +1,100 @@
1
+ # v1.face_swap_photo
1
2
 
2
- ### create <a name="create"></a>
3
- Face Swap Photo
3
+ ## Module Functions
4
4
 
5
- Create a face swap photo. Each photo costs 5 frames. The height/width of the output image depends on your subscription. Please refer to our [pricing](/pricing) page for more details
5
+ <!-- CUSTOM DOCS START -->
6
+
7
+ ### Face Swap Photo 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.face_swap_photo.generate(
35
+ assets={
36
+ "face_mappings": [
37
+ {
38
+ "new_face": "/path/to/1234.png",
39
+ "original_face": "api-assets/id/0-0.png",
40
+ }
41
+ ],
42
+ "face_swap_mode": "all-faces",
43
+ "source_file_path": "/path/to/1234.png",
44
+ "target_file_path": "/path/to/1234.png",
45
+ },
46
+ name="Face Swap image",
47
+ wait_for_completion=True,
48
+ download_outputs=True,
49
+ download_directory="outputs"
50
+ )
51
+ ```
52
+
53
+ #### Asynchronous Client
54
+
55
+ ```python
56
+ from magic_hour import AsyncClient
57
+ from os import getenv
58
+
59
+ client = AsyncClient(token=getenv("API_TOKEN"))
60
+ res = await client.v1.face_swap_photo.generate(
61
+ assets={
62
+ "face_mappings": [
63
+ {
64
+ "new_face": "/path/to/1234.png",
65
+ "original_face": "api-assets/id/0-0.png",
66
+ }
67
+ ],
68
+ "face_swap_mode": "all-faces",
69
+ "source_file_path": "/path/to/1234.png",
70
+ "target_file_path": "/path/to/1234.png",
71
+ },
72
+ name="Face Swap image",
73
+ wait_for_completion=True,
74
+ download_outputs=True,
75
+ download_directory="outputs"
76
+ )
77
+ ```
78
+
79
+ <!-- CUSTOM DOCS END -->
80
+
81
+ ### Face Swap Photo <a name="create"></a>
82
+
83
+ Create a face swap photo. Each photo costs 5 credits. The height/width of the output image depends on your subscription. Please refer to our [pricing](https://magichour.ai/pricing) page for more details
6
84
 
7
85
  **API Endpoint**: `POST /v1/face-swap-photo`
8
86
 
87
+ #### Parameters
88
+
89
+ | Parameter | Required | Description | Example |
90
+ | --------------------- | :------: | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
91
+ | `assets` | ✓ | Provide the assets for face swap photo | `{"face_mappings": [{"new_face": "api-assets/id/1234.png", "original_face": "api-assets/id/0-0.png"}], "face_swap_mode": "all-faces", "source_file_path": "api-assets/id/1234.png", "target_file_path": "api-assets/id/1234.png"}` |
92
+ | `└─ face_mappings` | ✗ | This is the array of face mappings used for multiple face swap. The value is required if `face_swap_mode` is `individual-faces`. | `[{"new_face": "api-assets/id/1234.png", "original_face": "api-assets/id/0-0.png"}]` |
93
+ | `└─ face_swap_mode` | ✗ | The mode of face swap. * `all-faces` - Swap all faces in the target image or video. `source_file_path` is required. * `individual-faces` - Swap individual faces in the target image or video. `source_faces` is required. | `"all-faces"` |
94
+ | `└─ source_file_path` | ✗ | This is the image from which the face is extracted. The value is required if `face_swap_mode` is `all-faces`. 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"` |
95
+ | `└─ target_file_path` | ✓ | This is the image where the face from the source image will be placed. 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"` |
96
+ | `name` | ✗ | The name of image. This value is mainly used for your own identification of the image. | `"Face Swap image"` |
97
+
9
98
  #### Synchronous Client
10
99
 
11
100
  ```python
@@ -15,6 +104,13 @@ from os import getenv
15
104
  client = Client(token=getenv("API_TOKEN"))
16
105
  res = client.v1.face_swap_photo.create(
17
106
  assets={
107
+ "face_mappings": [
108
+ {
109
+ "new_face": "api-assets/id/1234.png",
110
+ "original_face": "api-assets/id/0-0.png",
111
+ }
112
+ ],
113
+ "face_swap_mode": "all-faces",
18
114
  "source_file_path": "api-assets/id/1234.png",
19
115
  "target_file_path": "api-assets/id/1234.png",
20
116
  },
@@ -31,9 +127,28 @@ from os import getenv
31
127
  client = AsyncClient(token=getenv("API_TOKEN"))
32
128
  res = await client.v1.face_swap_photo.create(
33
129
  assets={
130
+ "face_mappings": [
131
+ {
132
+ "new_face": "api-assets/id/1234.png",
133
+ "original_face": "api-assets/id/0-0.png",
134
+ }
135
+ ],
136
+ "face_swap_mode": "all-faces",
34
137
  "source_file_path": "api-assets/id/1234.png",
35
138
  "target_file_path": "api-assets/id/1234.png",
36
139
  },
37
140
  name="Face Swap image",
38
141
  )
39
142
  ```
143
+
144
+ #### Response
145
+
146
+ ##### Type
147
+
148
+ [V1FaceSwapPhotoCreateResponse](/magic_hour/types/models/v1_face_swap_photo_create_response.py)
149
+
150
+ ##### Example
151
+
152
+ ```python
153
+ {"credits_charged": 5, "frame_cost": 5, "id": "cuid-example"}
154
+ ```