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.
- magic_hour/README.md +34 -0
- magic_hour/__init__.py +1 -1
- magic_hour/client.py +8 -17
- magic_hour/environment.py +13 -1
- magic_hour/helpers/__init__.py +4 -0
- magic_hour/helpers/download.py +77 -0
- magic_hour/helpers/logger.py +8 -0
- magic_hour/resources/v1/README.md +32 -0
- magic_hour/resources/v1/ai_clothes_changer/README.md +94 -5
- magic_hour/resources/v1/ai_clothes_changer/client.py +161 -16
- magic_hour/resources/v1/ai_face_editor/README.md +195 -0
- magic_hour/resources/v1/ai_face_editor/__init__.py +4 -0
- magic_hour/resources/v1/ai_face_editor/client.py +324 -0
- magic_hour/resources/v1/ai_gif_generator/README.md +116 -0
- magic_hour/resources/v1/ai_gif_generator/__init__.py +4 -0
- magic_hour/resources/v1/ai_gif_generator/client.py +257 -0
- magic_hour/resources/v1/ai_headshot_generator/README.md +81 -3
- magic_hour/resources/v1/ai_headshot_generator/client.py +167 -18
- magic_hour/resources/v1/ai_image_editor/README.md +125 -0
- magic_hour/resources/v1/ai_image_editor/__init__.py +4 -0
- magic_hour/resources/v1/ai_image_editor/client.py +290 -0
- magic_hour/resources/v1/ai_image_generator/README.md +99 -5
- magic_hour/resources/v1/ai_image_generator/client.py +170 -24
- magic_hour/resources/v1/ai_image_upscaler/README.md +89 -3
- magic_hour/resources/v1/ai_image_upscaler/client.py +173 -20
- magic_hour/resources/v1/ai_meme_generator/README.md +129 -0
- magic_hour/resources/v1/ai_meme_generator/__init__.py +4 -0
- magic_hour/resources/v1/ai_meme_generator/client.py +253 -0
- magic_hour/resources/v1/ai_photo_editor/README.md +119 -4
- magic_hour/resources/v1/ai_photo_editor/client.py +199 -18
- magic_hour/resources/v1/ai_qr_code_generator/README.md +84 -3
- magic_hour/resources/v1/ai_qr_code_generator/client.py +140 -18
- magic_hour/resources/v1/ai_talking_photo/README.md +137 -0
- magic_hour/resources/v1/ai_talking_photo/__init__.py +4 -0
- magic_hour/resources/v1/ai_talking_photo/client.py +326 -0
- magic_hour/resources/v1/ai_voice_cloner/README.md +62 -0
- magic_hour/resources/v1/ai_voice_cloner/__init__.py +4 -0
- magic_hour/resources/v1/ai_voice_cloner/client.py +272 -0
- magic_hour/resources/v1/ai_voice_generator/README.md +112 -0
- magic_hour/resources/v1/ai_voice_generator/__init__.py +4 -0
- magic_hour/resources/v1/ai_voice_generator/client.py +241 -0
- magic_hour/resources/v1/animation/README.md +128 -6
- magic_hour/resources/v1/animation/client.py +247 -22
- magic_hour/resources/v1/audio_projects/README.md +135 -0
- magic_hour/resources/v1/audio_projects/__init__.py +12 -0
- magic_hour/resources/v1/audio_projects/client.py +310 -0
- magic_hour/resources/v1/audio_projects/client_test.py +520 -0
- magic_hour/resources/v1/auto_subtitle_generator/README.md +128 -0
- magic_hour/resources/v1/auto_subtitle_generator/__init__.py +4 -0
- magic_hour/resources/v1/auto_subtitle_generator/client.py +346 -0
- magic_hour/resources/v1/client.py +75 -1
- magic_hour/resources/v1/face_detection/README.md +157 -0
- magic_hour/resources/v1/face_detection/__init__.py +12 -0
- magic_hour/resources/v1/face_detection/client.py +380 -0
- magic_hour/resources/v1/face_swap/README.md +137 -9
- magic_hour/resources/v1/face_swap/client.py +329 -38
- magic_hour/resources/v1/face_swap_photo/README.md +118 -3
- magic_hour/resources/v1/face_swap_photo/client.py +199 -14
- magic_hour/resources/v1/files/README.md +39 -0
- magic_hour/resources/v1/files/client.py +351 -1
- magic_hour/resources/v1/files/client_test.py +414 -0
- magic_hour/resources/v1/files/upload_urls/README.md +38 -17
- magic_hour/resources/v1/files/upload_urls/client.py +38 -34
- magic_hour/resources/v1/image_background_remover/README.md +96 -5
- magic_hour/resources/v1/image_background_remover/client.py +151 -16
- magic_hour/resources/v1/image_projects/README.md +82 -10
- magic_hour/resources/v1/image_projects/__init__.py +10 -2
- magic_hour/resources/v1/image_projects/client.py +154 -16
- magic_hour/resources/v1/image_projects/client_test.py +527 -0
- magic_hour/resources/v1/image_to_video/README.md +96 -11
- magic_hour/resources/v1/image_to_video/client.py +282 -38
- magic_hour/resources/v1/lip_sync/README.md +112 -9
- magic_hour/resources/v1/lip_sync/client.py +288 -34
- magic_hour/resources/v1/photo_colorizer/README.md +107 -0
- magic_hour/resources/v1/photo_colorizer/__init__.py +4 -0
- magic_hour/resources/v1/photo_colorizer/client.py +248 -0
- magic_hour/resources/v1/text_to_video/README.md +96 -7
- magic_hour/resources/v1/text_to_video/client.py +204 -18
- magic_hour/resources/v1/video_projects/README.md +81 -9
- magic_hour/resources/v1/video_projects/__init__.py +10 -2
- magic_hour/resources/v1/video_projects/client.py +151 -14
- magic_hour/resources/v1/video_projects/client_test.py +527 -0
- magic_hour/resources/v1/video_to_video/README.md +119 -15
- magic_hour/resources/v1/video_to_video/client.py +299 -46
- magic_hour/types/models/__init__.py +92 -56
- magic_hour/types/models/v1_ai_clothes_changer_create_response.py +33 -0
- magic_hour/types/models/v1_ai_face_editor_create_response.py +33 -0
- magic_hour/types/models/v1_ai_gif_generator_create_response.py +33 -0
- magic_hour/types/models/v1_ai_headshot_generator_create_response.py +33 -0
- magic_hour/types/models/v1_ai_image_editor_create_response.py +33 -0
- magic_hour/types/models/v1_ai_image_generator_create_response.py +33 -0
- magic_hour/types/models/v1_ai_image_upscaler_create_response.py +33 -0
- magic_hour/types/models/v1_ai_meme_generator_create_response.py +33 -0
- magic_hour/types/models/v1_ai_photo_editor_create_response.py +33 -0
- magic_hour/types/models/v1_ai_qr_code_generator_create_response.py +33 -0
- magic_hour/types/models/v1_ai_talking_photo_create_response.py +35 -0
- magic_hour/types/models/v1_ai_voice_cloner_create_response.py +27 -0
- magic_hour/types/models/v1_ai_voice_generator_create_response.py +27 -0
- magic_hour/types/models/v1_animation_create_response.py +35 -0
- magic_hour/types/models/v1_audio_projects_get_response.py +72 -0
- magic_hour/types/models/v1_audio_projects_get_response_downloads_item.py +19 -0
- magic_hour/types/models/{get_v1_image_projects_id_response_error.py → v1_audio_projects_get_response_error.py} +2 -2
- magic_hour/types/models/v1_auto_subtitle_generator_create_response.py +35 -0
- magic_hour/types/models/v1_face_detection_create_response.py +25 -0
- magic_hour/types/models/v1_face_detection_get_response.py +45 -0
- magic_hour/types/models/v1_face_detection_get_response_faces_item.py +25 -0
- magic_hour/types/models/v1_face_swap_create_response.py +35 -0
- magic_hour/types/models/v1_face_swap_photo_create_response.py +33 -0
- magic_hour/types/models/v1_files_upload_urls_create_response.py +24 -0
- magic_hour/types/models/{post_v1_files_upload_urls_response_items_item.py → v1_files_upload_urls_create_response_items_item.py} +2 -2
- magic_hour/types/models/v1_image_background_remover_create_response.py +33 -0
- magic_hour/types/models/{get_v1_image_projects_id_response.py → v1_image_projects_get_response.py} +20 -18
- magic_hour/types/models/{get_v1_video_projects_id_response_downloads_item.py → v1_image_projects_get_response_downloads_item.py} +1 -1
- magic_hour/types/models/{get_v1_video_projects_id_response_error.py → v1_image_projects_get_response_error.py} +2 -2
- magic_hour/types/models/v1_image_to_video_create_response.py +35 -0
- magic_hour/types/models/v1_lip_sync_create_response.py +35 -0
- magic_hour/types/models/v1_photo_colorizer_create_response.py +33 -0
- magic_hour/types/models/v1_text_to_video_create_response.py +35 -0
- magic_hour/types/models/{get_v1_video_projects_id_response.py → v1_video_projects_get_response.py} +26 -23
- magic_hour/types/models/{get_v1_video_projects_id_response_download.py → v1_video_projects_get_response_download.py} +1 -1
- magic_hour/types/models/{get_v1_image_projects_id_response_downloads_item.py → v1_video_projects_get_response_downloads_item.py} +1 -1
- magic_hour/types/models/v1_video_projects_get_response_error.py +25 -0
- magic_hour/types/models/v1_video_to_video_create_response.py +35 -0
- magic_hour/types/params/__init__.py +422 -176
- magic_hour/types/params/v1_ai_clothes_changer_create_body.py +40 -0
- magic_hour/types/params/v1_ai_clothes_changer_create_body_assets.py +58 -0
- magic_hour/types/params/v1_ai_clothes_changer_generate_body_assets.py +33 -0
- magic_hour/types/params/v1_ai_face_editor_create_body.py +52 -0
- magic_hour/types/params/v1_ai_face_editor_create_body_assets.py +33 -0
- magic_hour/types/params/v1_ai_face_editor_create_body_style.py +137 -0
- magic_hour/types/params/v1_ai_face_editor_generate_body_assets.py +17 -0
- magic_hour/types/params/v1_ai_gif_generator_create_body.py +47 -0
- magic_hour/types/params/{post_v1_ai_image_generator_body_style.py → v1_ai_gif_generator_create_body_style.py} +5 -5
- magic_hour/types/params/v1_ai_headshot_generator_create_body.py +49 -0
- magic_hour/types/params/v1_ai_headshot_generator_create_body_assets.py +33 -0
- magic_hour/types/params/v1_ai_headshot_generator_create_body_style.py +27 -0
- magic_hour/types/params/v1_ai_headshot_generator_generate_body_assets.py +17 -0
- magic_hour/types/params/v1_ai_image_editor_create_body.py +49 -0
- magic_hour/types/params/v1_ai_image_editor_create_body_assets.py +47 -0
- magic_hour/types/params/v1_ai_image_editor_create_body_style.py +41 -0
- magic_hour/types/params/v1_ai_image_editor_generate_body_assets.py +28 -0
- magic_hour/types/params/{post_v1_ai_image_generator_body.py → v1_ai_image_generator_create_body.py} +17 -11
- magic_hour/types/params/v1_ai_image_generator_create_body_style.py +127 -0
- magic_hour/types/params/v1_ai_image_upscaler_create_body.py +59 -0
- magic_hour/types/params/v1_ai_image_upscaler_create_body_assets.py +33 -0
- magic_hour/types/params/{post_v1_ai_image_upscaler_body_style.py → v1_ai_image_upscaler_create_body_style.py} +4 -4
- magic_hour/types/params/v1_ai_image_upscaler_generate_body_assets.py +17 -0
- magic_hour/types/params/v1_ai_meme_generator_create_body.py +37 -0
- magic_hour/types/params/v1_ai_meme_generator_create_body_style.py +73 -0
- magic_hour/types/params/{post_v1_ai_photo_editor_body.py → v1_ai_photo_editor_create_body.py} +15 -15
- magic_hour/types/params/v1_ai_photo_editor_create_body_assets.py +33 -0
- magic_hour/types/params/{post_v1_ai_photo_editor_body_style.py → v1_ai_photo_editor_create_body_style.py} +20 -4
- magic_hour/types/params/v1_ai_photo_editor_generate_body_assets.py +17 -0
- magic_hour/types/params/v1_ai_qr_code_generator_create_body.py +45 -0
- magic_hour/types/params/{post_v1_ai_qr_code_generator_body_style.py → v1_ai_qr_code_generator_create_body_style.py} +4 -4
- magic_hour/types/params/v1_ai_talking_photo_create_body.py +68 -0
- magic_hour/types/params/v1_ai_talking_photo_create_body_assets.py +46 -0
- magic_hour/types/params/v1_ai_talking_photo_create_body_style.py +44 -0
- magic_hour/types/params/v1_ai_talking_photo_generate_body_assets.py +26 -0
- magic_hour/types/params/v1_ai_voice_cloner_create_body.py +49 -0
- magic_hour/types/params/v1_ai_voice_cloner_create_body_assets.py +33 -0
- magic_hour/types/params/v1_ai_voice_cloner_create_body_style.py +28 -0
- magic_hour/types/params/v1_ai_voice_cloner_generate_body_assets.py +28 -0
- magic_hour/types/params/v1_ai_voice_generator_create_body.py +40 -0
- magic_hour/types/params/v1_ai_voice_generator_create_body_style.py +440 -0
- magic_hour/types/params/{post_v1_animation_body.py → v1_animation_create_body.py} +16 -16
- magic_hour/types/params/{post_v1_animation_body_assets.py → v1_animation_create_body_assets.py} +15 -5
- magic_hour/types/params/{post_v1_animation_body_style.py → v1_animation_create_body_style.py} +13 -10
- magic_hour/types/params/v1_animation_generate_body_assets.py +39 -0
- magic_hour/types/params/v1_auto_subtitle_generator_create_body.py +78 -0
- magic_hour/types/params/v1_auto_subtitle_generator_create_body_assets.py +33 -0
- magic_hour/types/params/v1_auto_subtitle_generator_create_body_style.py +56 -0
- magic_hour/types/params/v1_auto_subtitle_generator_create_body_style_custom_config.py +86 -0
- magic_hour/types/params/v1_auto_subtitle_generator_generate_body_assets.py +17 -0
- magic_hour/types/params/v1_face_detection_create_body.py +44 -0
- magic_hour/types/params/v1_face_detection_create_body_assets.py +33 -0
- magic_hour/types/params/v1_face_detection_generate_body_assets.py +17 -0
- magic_hour/types/params/v1_face_swap_create_body.py +92 -0
- magic_hour/types/params/v1_face_swap_create_body_assets.py +91 -0
- magic_hour/types/params/v1_face_swap_create_body_assets_face_mappings_item.py +44 -0
- magic_hour/types/params/v1_face_swap_create_body_style.py +33 -0
- magic_hour/types/params/v1_face_swap_generate_body_assets.py +56 -0
- magic_hour/types/params/v1_face_swap_generate_body_assets_face_mappings_item.py +25 -0
- magic_hour/types/params/v1_face_swap_photo_create_body.py +40 -0
- magic_hour/types/params/v1_face_swap_photo_create_body_assets.py +76 -0
- magic_hour/types/params/v1_face_swap_photo_create_body_assets_face_mappings_item.py +44 -0
- magic_hour/types/params/v1_face_swap_photo_generate_body_assets.py +47 -0
- magic_hour/types/params/v1_face_swap_photo_generate_body_assets_face_mappings_item.py +25 -0
- magic_hour/types/params/v1_files_upload_urls_create_body.py +36 -0
- magic_hour/types/params/v1_files_upload_urls_create_body_items_item.py +38 -0
- magic_hour/types/params/v1_image_background_remover_create_body.py +40 -0
- magic_hour/types/params/v1_image_background_remover_create_body_assets.py +49 -0
- magic_hour/types/params/v1_image_background_remover_generate_body_assets.py +27 -0
- magic_hour/types/params/v1_image_to_video_create_body.py +101 -0
- magic_hour/types/params/v1_image_to_video_create_body_assets.py +33 -0
- magic_hour/types/params/v1_image_to_video_create_body_style.py +53 -0
- magic_hour/types/params/v1_image_to_video_generate_body_assets.py +17 -0
- magic_hour/types/params/v1_lip_sync_create_body.py +100 -0
- magic_hour/types/params/{post_v1_lip_sync_body_assets.py → v1_lip_sync_create_body_assets.py} +15 -5
- magic_hour/types/params/v1_lip_sync_create_body_style.py +37 -0
- magic_hour/types/params/v1_lip_sync_generate_body_assets.py +36 -0
- magic_hour/types/params/v1_photo_colorizer_create_body.py +40 -0
- magic_hour/types/params/v1_photo_colorizer_create_body_assets.py +33 -0
- magic_hour/types/params/v1_photo_colorizer_generate_body_assets.py +17 -0
- magic_hour/types/params/v1_text_to_video_create_body.py +78 -0
- magic_hour/types/params/v1_text_to_video_create_body_style.py +43 -0
- magic_hour/types/params/v1_video_to_video_create_body.py +101 -0
- magic_hour/types/params/{post_v1_video_to_video_body_assets.py → v1_video_to_video_create_body_assets.py} +9 -4
- magic_hour/types/params/{post_v1_video_to_video_body_style.py → v1_video_to_video_create_body_style.py} +68 -26
- magic_hour/types/params/v1_video_to_video_generate_body_assets.py +27 -0
- magic_hour-0.44.0.dist-info/METADATA +328 -0
- magic_hour-0.44.0.dist-info/RECORD +231 -0
- magic_hour/core/__init__.py +0 -52
- magic_hour/core/api_error.py +0 -56
- magic_hour/core/auth.py +0 -314
- magic_hour/core/base_client.py +0 -618
- magic_hour/core/binary_response.py +0 -23
- magic_hour/core/query.py +0 -106
- magic_hour/core/request.py +0 -156
- magic_hour/core/response.py +0 -293
- magic_hour/core/type_utils.py +0 -28
- magic_hour/core/utils.py +0 -55
- magic_hour/types/models/post_v1_ai_clothes_changer_response.py +0 -25
- magic_hour/types/models/post_v1_ai_headshot_generator_response.py +0 -25
- magic_hour/types/models/post_v1_ai_image_generator_response.py +0 -25
- magic_hour/types/models/post_v1_ai_image_upscaler_response.py +0 -25
- magic_hour/types/models/post_v1_ai_photo_editor_response.py +0 -25
- magic_hour/types/models/post_v1_ai_qr_code_generator_response.py +0 -25
- magic_hour/types/models/post_v1_animation_response.py +0 -25
- magic_hour/types/models/post_v1_face_swap_photo_response.py +0 -25
- magic_hour/types/models/post_v1_face_swap_response.py +0 -25
- magic_hour/types/models/post_v1_files_upload_urls_response.py +0 -21
- magic_hour/types/models/post_v1_image_background_remover_response.py +0 -25
- magic_hour/types/models/post_v1_image_to_video_response.py +0 -25
- magic_hour/types/models/post_v1_lip_sync_response.py +0 -25
- magic_hour/types/models/post_v1_text_to_video_response.py +0 -25
- magic_hour/types/models/post_v1_video_to_video_response.py +0 -25
- magic_hour/types/params/post_v1_ai_clothes_changer_body.py +0 -40
- magic_hour/types/params/post_v1_ai_clothes_changer_body_assets.py +0 -45
- magic_hour/types/params/post_v1_ai_headshot_generator_body.py +0 -40
- magic_hour/types/params/post_v1_ai_headshot_generator_body_assets.py +0 -28
- magic_hour/types/params/post_v1_ai_image_upscaler_body.py +0 -57
- magic_hour/types/params/post_v1_ai_image_upscaler_body_assets.py +0 -28
- magic_hour/types/params/post_v1_ai_photo_editor_body_assets.py +0 -28
- magic_hour/types/params/post_v1_ai_qr_code_generator_body.py +0 -45
- magic_hour/types/params/post_v1_face_swap_body.py +0 -72
- magic_hour/types/params/post_v1_face_swap_body_assets.py +0 -52
- magic_hour/types/params/post_v1_face_swap_photo_body.py +0 -40
- magic_hour/types/params/post_v1_face_swap_photo_body_assets.py +0 -36
- magic_hour/types/params/post_v1_files_upload_urls_body.py +0 -31
- magic_hour/types/params/post_v1_files_upload_urls_body_items_item.py +0 -38
- magic_hour/types/params/post_v1_image_background_remover_body.py +0 -40
- magic_hour/types/params/post_v1_image_background_remover_body_assets.py +0 -28
- magic_hour/types/params/post_v1_image_to_video_body.py +0 -73
- magic_hour/types/params/post_v1_image_to_video_body_assets.py +0 -28
- magic_hour/types/params/post_v1_image_to_video_body_style.py +0 -37
- magic_hour/types/params/post_v1_lip_sync_body.py +0 -80
- magic_hour/types/params/post_v1_text_to_video_body.py +0 -57
- magic_hour/types/params/post_v1_text_to_video_body_style.py +0 -28
- magic_hour/types/params/post_v1_video_to_video_body.py +0 -93
- magic_hour-0.9.5.dist-info/METADATA +0 -133
- magic_hour-0.9.5.dist-info/RECORD +0 -132
- {magic_hour-0.9.5.dist-info → magic_hour-0.44.0.dist-info}/LICENSE +0 -0
- {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.
|
|
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
|
-
|
|
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.
|
|
138
|
+
assets: params.V1FaceSwapCreateBodyAssets,
|
|
22
139
|
end_seconds: float,
|
|
23
|
-
height: int,
|
|
24
140
|
start_seconds: float,
|
|
25
|
-
|
|
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.
|
|
154
|
+
) -> models.V1FaceSwapCreateResponse:
|
|
31
155
|
"""
|
|
32
|
-
Face Swap
|
|
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
|
-
|
|
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
|
-
|
|
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={
|
|
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.
|
|
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.
|
|
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.
|
|
357
|
+
assets: params.V1FaceSwapCreateBodyAssets,
|
|
98
358
|
end_seconds: float,
|
|
99
|
-
height: int,
|
|
100
359
|
start_seconds: float,
|
|
101
|
-
|
|
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.
|
|
373
|
+
) -> models.V1FaceSwapCreateResponse:
|
|
107
374
|
"""
|
|
108
|
-
Face Swap
|
|
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
|
-
|
|
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
|
-
|
|
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={
|
|
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.
|
|
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.
|
|
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
|
-
|
|
3
|
-
Face Swap Photo
|
|
3
|
+
## Module Functions
|
|
4
4
|
|
|
5
|
-
|
|
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
|
+
```
|