magic_hour 0.8.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.
Potentially problematic release.
This version of magic_hour might be problematic. Click here for more details.
- magic_hour/__init__.py +6 -0
- magic_hour/client.py +61 -0
- magic_hour/core/__init__.py +53 -0
- magic_hour/core/api_error.py +48 -0
- magic_hour/core/auth.py +314 -0
- magic_hour/core/base_client.py +600 -0
- magic_hour/core/binary_response.py +23 -0
- magic_hour/core/request.py +158 -0
- magic_hour/core/response.py +293 -0
- magic_hour/core/type_utils.py +28 -0
- magic_hour/core/utils.py +38 -0
- magic_hour/environment.py +6 -0
- magic_hour/resources/v1/__init__.py +4 -0
- magic_hour/resources/v1/ai_clothes_changer/README.md +41 -0
- magic_hour/resources/v1/ai_clothes_changer/__init__.py +4 -0
- magic_hour/resources/v1/ai_clothes_changer/client.py +129 -0
- magic_hour/resources/v1/ai_headshot_generator/README.md +31 -0
- magic_hour/resources/v1/ai_headshot_generator/__init__.py +4 -0
- magic_hour/resources/v1/ai_headshot_generator/client.py +119 -0
- magic_hour/resources/v1/ai_image_generator/README.md +37 -0
- magic_hour/resources/v1/ai_image_generator/__init__.py +4 -0
- magic_hour/resources/v1/ai_image_generator/client.py +144 -0
- magic_hour/resources/v1/ai_image_upscaler/README.md +37 -0
- magic_hour/resources/v1/ai_image_upscaler/__init__.py +4 -0
- magic_hour/resources/v1/ai_image_upscaler/client.py +143 -0
- magic_hour/resources/v1/ai_photo_editor/README.md +53 -0
- magic_hour/resources/v1/ai_photo_editor/__init__.py +4 -0
- magic_hour/resources/v1/ai_photo_editor/client.py +167 -0
- magic_hour/resources/v1/ai_qr_code_generator/README.md +35 -0
- magic_hour/resources/v1/ai_qr_code_generator/__init__.py +4 -0
- magic_hour/resources/v1/ai_qr_code_generator/client.py +127 -0
- magic_hour/resources/v1/animation/README.md +63 -0
- magic_hour/resources/v1/animation/__init__.py +4 -0
- magic_hour/resources/v1/animation/client.py +179 -0
- magic_hour/resources/v1/client.py +153 -0
- magic_hour/resources/v1/face_swap/README.md +52 -0
- magic_hour/resources/v1/face_swap/__init__.py +4 -0
- magic_hour/resources/v1/face_swap/client.py +165 -0
- magic_hour/resources/v1/face_swap_photo/README.md +39 -0
- magic_hour/resources/v1/face_swap_photo/__init__.py +4 -0
- magic_hour/resources/v1/face_swap_photo/client.py +127 -0
- magic_hour/resources/v1/files/__init__.py +4 -0
- magic_hour/resources/v1/files/client.py +19 -0
- magic_hour/resources/v1/files/upload_urls/README.md +56 -0
- magic_hour/resources/v1/files/upload_urls/__init__.py +4 -0
- magic_hour/resources/v1/files/upload_urls/client.py +142 -0
- magic_hour/resources/v1/image_background_remover/README.md +31 -0
- magic_hour/resources/v1/image_background_remover/__init__.py +4 -0
- magic_hour/resources/v1/image_background_remover/client.py +121 -0
- magic_hour/resources/v1/image_projects/README.md +63 -0
- magic_hour/resources/v1/image_projects/__init__.py +4 -0
- magic_hour/resources/v1/image_projects/client.py +177 -0
- magic_hour/resources/v1/image_to_video/README.md +44 -0
- magic_hour/resources/v1/image_to_video/__init__.py +4 -0
- magic_hour/resources/v1/image_to_video/client.py +165 -0
- magic_hour/resources/v1/lip_sync/README.md +54 -0
- magic_hour/resources/v1/lip_sync/__init__.py +4 -0
- magic_hour/resources/v1/lip_sync/client.py +177 -0
- magic_hour/resources/v1/text_to_video/README.md +40 -0
- magic_hour/resources/v1/text_to_video/__init__.py +4 -0
- magic_hour/resources/v1/text_to_video/client.py +150 -0
- magic_hour/resources/v1/video_projects/README.md +63 -0
- magic_hour/resources/v1/video_projects/__init__.py +4 -0
- magic_hour/resources/v1/video_projects/client.py +177 -0
- magic_hour/resources/v1/video_to_video/README.md +60 -0
- magic_hour/resources/v1/video_to_video/__init__.py +4 -0
- magic_hour/resources/v1/video_to_video/client.py +204 -0
- magic_hour/types/models/__init__.py +60 -0
- magic_hour/types/models/get_v1_image_projects_id_response.py +82 -0
- magic_hour/types/models/get_v1_image_projects_id_response_downloads_item.py +19 -0
- magic_hour/types/models/get_v1_image_projects_id_response_error.py +25 -0
- magic_hour/types/models/get_v1_video_projects_id_response.py +114 -0
- magic_hour/types/models/get_v1_video_projects_id_response_download.py +19 -0
- magic_hour/types/models/get_v1_video_projects_id_response_downloads_item.py +19 -0
- magic_hour/types/models/get_v1_video_projects_id_response_error.py +25 -0
- magic_hour/types/models/post_v1_ai_clothes_changer_response.py +25 -0
- magic_hour/types/models/post_v1_ai_headshot_generator_response.py +25 -0
- magic_hour/types/models/post_v1_ai_image_generator_response.py +25 -0
- magic_hour/types/models/post_v1_ai_image_upscaler_response.py +25 -0
- magic_hour/types/models/post_v1_ai_photo_editor_response.py +25 -0
- magic_hour/types/models/post_v1_ai_qr_code_generator_response.py +25 -0
- magic_hour/types/models/post_v1_animation_response.py +25 -0
- magic_hour/types/models/post_v1_face_swap_photo_response.py +25 -0
- magic_hour/types/models/post_v1_face_swap_response.py +25 -0
- magic_hour/types/models/post_v1_files_upload_urls_response.py +21 -0
- magic_hour/types/models/post_v1_files_upload_urls_response_items_item.py +31 -0
- magic_hour/types/models/post_v1_image_background_remover_response.py +25 -0
- magic_hour/types/models/post_v1_image_to_video_response.py +25 -0
- magic_hour/types/models/post_v1_lip_sync_response.py +25 -0
- magic_hour/types/models/post_v1_text_to_video_response.py +25 -0
- magic_hour/types/models/post_v1_video_to_video_response.py +25 -0
- magic_hour/types/params/__init__.py +205 -0
- magic_hour/types/params/post_v1_ai_clothes_changer_body.py +40 -0
- magic_hour/types/params/post_v1_ai_clothes_changer_body_assets.py +45 -0
- magic_hour/types/params/post_v1_ai_headshot_generator_body.py +40 -0
- magic_hour/types/params/post_v1_ai_headshot_generator_body_assets.py +28 -0
- magic_hour/types/params/post_v1_ai_image_generator_body.py +54 -0
- magic_hour/types/params/post_v1_ai_image_generator_body_style.py +28 -0
- magic_hour/types/params/post_v1_ai_image_upscaler_body.py +54 -0
- magic_hour/types/params/post_v1_ai_image_upscaler_body_assets.py +28 -0
- magic_hour/types/params/post_v1_ai_image_upscaler_body_style.py +36 -0
- magic_hour/types/params/post_v1_ai_photo_editor_body.py +63 -0
- magic_hour/types/params/post_v1_ai_photo_editor_body_assets.py +28 -0
- magic_hour/types/params/post_v1_ai_photo_editor_body_style.py +67 -0
- magic_hour/types/params/post_v1_ai_qr_code_generator_body.py +45 -0
- magic_hour/types/params/post_v1_ai_qr_code_generator_body_style.py +28 -0
- magic_hour/types/params/post_v1_animation_body.py +84 -0
- magic_hour/types/params/post_v1_animation_body_assets.py +55 -0
- magic_hour/types/params/post_v1_animation_body_style.py +279 -0
- magic_hour/types/params/post_v1_face_swap_body.py +72 -0
- magic_hour/types/params/post_v1_face_swap_body_assets.py +52 -0
- magic_hour/types/params/post_v1_face_swap_photo_body.py +40 -0
- magic_hour/types/params/post_v1_face_swap_photo_body_assets.py +36 -0
- magic_hour/types/params/post_v1_files_upload_urls_body.py +31 -0
- magic_hour/types/params/post_v1_files_upload_urls_body_items_item.py +38 -0
- magic_hour/types/params/post_v1_image_background_remover_body.py +40 -0
- magic_hour/types/params/post_v1_image_background_remover_body_assets.py +28 -0
- magic_hour/types/params/post_v1_image_to_video_body.py +73 -0
- magic_hour/types/params/post_v1_image_to_video_body_assets.py +28 -0
- magic_hour/types/params/post_v1_image_to_video_body_style.py +29 -0
- magic_hour/types/params/post_v1_lip_sync_body.py +80 -0
- magic_hour/types/params/post_v1_lip_sync_body_assets.py +52 -0
- magic_hour/types/params/post_v1_text_to_video_body.py +57 -0
- magic_hour/types/params/post_v1_text_to_video_body_style.py +28 -0
- magic_hour/types/params/post_v1_video_to_video_body.py +93 -0
- magic_hour/types/params/post_v1_video_to_video_body_assets.py +44 -0
- magic_hour/types/params/post_v1_video_to_video_body_style.py +199 -0
- magic_hour-0.8.0.dist-info/LICENSE +21 -0
- magic_hour-0.8.0.dist-info/METADATA +138 -0
- magic_hour-0.8.0.dist-info/RECORD +131 -0
- magic_hour-0.8.0.dist-info/WHEEL +4 -0
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
from magic_hour.core import AsyncBaseClient, SyncBaseClient
|
|
2
|
+
from magic_hour.resources.v1.image_projects import (
|
|
3
|
+
AsyncImageProjectsClient,
|
|
4
|
+
ImageProjectsClient,
|
|
5
|
+
)
|
|
6
|
+
from magic_hour.resources.v1.video_projects import (
|
|
7
|
+
AsyncVideoProjectsClient,
|
|
8
|
+
VideoProjectsClient,
|
|
9
|
+
)
|
|
10
|
+
from magic_hour.resources.v1.ai_clothes_changer import (
|
|
11
|
+
AiClothesChangerClient,
|
|
12
|
+
AsyncAiClothesChangerClient,
|
|
13
|
+
)
|
|
14
|
+
from magic_hour.resources.v1.ai_headshot_generator import (
|
|
15
|
+
AiHeadshotGeneratorClient,
|
|
16
|
+
AsyncAiHeadshotGeneratorClient,
|
|
17
|
+
)
|
|
18
|
+
from magic_hour.resources.v1.ai_image_generator import (
|
|
19
|
+
AiImageGeneratorClient,
|
|
20
|
+
AsyncAiImageGeneratorClient,
|
|
21
|
+
)
|
|
22
|
+
from magic_hour.resources.v1.ai_image_upscaler import (
|
|
23
|
+
AiImageUpscalerClient,
|
|
24
|
+
AsyncAiImageUpscalerClient,
|
|
25
|
+
)
|
|
26
|
+
from magic_hour.resources.v1.ai_photo_editor import (
|
|
27
|
+
AiPhotoEditorClient,
|
|
28
|
+
AsyncAiPhotoEditorClient,
|
|
29
|
+
)
|
|
30
|
+
from magic_hour.resources.v1.ai_qr_code_generator import (
|
|
31
|
+
AiQrCodeGeneratorClient,
|
|
32
|
+
AsyncAiQrCodeGeneratorClient,
|
|
33
|
+
)
|
|
34
|
+
from magic_hour.resources.v1.animation import AnimationClient, AsyncAnimationClient
|
|
35
|
+
from magic_hour.resources.v1.face_swap import AsyncFaceSwapClient, FaceSwapClient
|
|
36
|
+
from magic_hour.resources.v1.face_swap_photo import (
|
|
37
|
+
AsyncFaceSwapPhotoClient,
|
|
38
|
+
FaceSwapPhotoClient,
|
|
39
|
+
)
|
|
40
|
+
from magic_hour.resources.v1.files import AsyncFilesClient, FilesClient
|
|
41
|
+
from magic_hour.resources.v1.image_background_remover import (
|
|
42
|
+
AsyncImageBackgroundRemoverClient,
|
|
43
|
+
ImageBackgroundRemoverClient,
|
|
44
|
+
)
|
|
45
|
+
from magic_hour.resources.v1.image_to_video import (
|
|
46
|
+
AsyncImageToVideoClient,
|
|
47
|
+
ImageToVideoClient,
|
|
48
|
+
)
|
|
49
|
+
from magic_hour.resources.v1.lip_sync import AsyncLipSyncClient, LipSyncClient
|
|
50
|
+
from magic_hour.resources.v1.text_to_video import (
|
|
51
|
+
AsyncTextToVideoClient,
|
|
52
|
+
TextToVideoClient,
|
|
53
|
+
)
|
|
54
|
+
from magic_hour.resources.v1.video_to_video import (
|
|
55
|
+
AsyncVideoToVideoClient,
|
|
56
|
+
VideoToVideoClient,
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
class V1Client:
|
|
61
|
+
def __init__(self, *, base_client: SyncBaseClient):
|
|
62
|
+
self._base_client = base_client
|
|
63
|
+
|
|
64
|
+
self.image_projects = ImageProjectsClient(base_client=self._base_client)
|
|
65
|
+
|
|
66
|
+
self.video_projects = VideoProjectsClient(base_client=self._base_client)
|
|
67
|
+
|
|
68
|
+
self.ai_clothes_changer = AiClothesChangerClient(base_client=self._base_client)
|
|
69
|
+
|
|
70
|
+
self.ai_headshot_generator = AiHeadshotGeneratorClient(
|
|
71
|
+
base_client=self._base_client
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
self.ai_image_generator = AiImageGeneratorClient(base_client=self._base_client)
|
|
75
|
+
|
|
76
|
+
self.ai_image_upscaler = AiImageUpscalerClient(base_client=self._base_client)
|
|
77
|
+
|
|
78
|
+
self.ai_photo_editor = AiPhotoEditorClient(base_client=self._base_client)
|
|
79
|
+
|
|
80
|
+
self.ai_qr_code_generator = AiQrCodeGeneratorClient(
|
|
81
|
+
base_client=self._base_client
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
self.animation = AnimationClient(base_client=self._base_client)
|
|
85
|
+
|
|
86
|
+
self.face_swap = FaceSwapClient(base_client=self._base_client)
|
|
87
|
+
|
|
88
|
+
self.face_swap_photo = FaceSwapPhotoClient(base_client=self._base_client)
|
|
89
|
+
|
|
90
|
+
self.files = FilesClient(base_client=self._base_client)
|
|
91
|
+
|
|
92
|
+
self.image_background_remover = ImageBackgroundRemoverClient(
|
|
93
|
+
base_client=self._base_client
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
self.image_to_video = ImageToVideoClient(base_client=self._base_client)
|
|
97
|
+
|
|
98
|
+
self.lip_sync = LipSyncClient(base_client=self._base_client)
|
|
99
|
+
|
|
100
|
+
self.text_to_video = TextToVideoClient(base_client=self._base_client)
|
|
101
|
+
|
|
102
|
+
self.video_to_video = VideoToVideoClient(base_client=self._base_client)
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
class AsyncV1Client:
|
|
106
|
+
def __init__(self, *, base_client: AsyncBaseClient):
|
|
107
|
+
self._base_client = base_client
|
|
108
|
+
|
|
109
|
+
self.image_projects = AsyncImageProjectsClient(base_client=self._base_client)
|
|
110
|
+
|
|
111
|
+
self.video_projects = AsyncVideoProjectsClient(base_client=self._base_client)
|
|
112
|
+
|
|
113
|
+
self.ai_clothes_changer = AsyncAiClothesChangerClient(
|
|
114
|
+
base_client=self._base_client
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
self.ai_headshot_generator = AsyncAiHeadshotGeneratorClient(
|
|
118
|
+
base_client=self._base_client
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
self.ai_image_generator = AsyncAiImageGeneratorClient(
|
|
122
|
+
base_client=self._base_client
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
self.ai_image_upscaler = AsyncAiImageUpscalerClient(
|
|
126
|
+
base_client=self._base_client
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
self.ai_photo_editor = AsyncAiPhotoEditorClient(base_client=self._base_client)
|
|
130
|
+
|
|
131
|
+
self.ai_qr_code_generator = AsyncAiQrCodeGeneratorClient(
|
|
132
|
+
base_client=self._base_client
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
self.animation = AsyncAnimationClient(base_client=self._base_client)
|
|
136
|
+
|
|
137
|
+
self.face_swap = AsyncFaceSwapClient(base_client=self._base_client)
|
|
138
|
+
|
|
139
|
+
self.face_swap_photo = AsyncFaceSwapPhotoClient(base_client=self._base_client)
|
|
140
|
+
|
|
141
|
+
self.files = AsyncFilesClient(base_client=self._base_client)
|
|
142
|
+
|
|
143
|
+
self.image_background_remover = AsyncImageBackgroundRemoverClient(
|
|
144
|
+
base_client=self._base_client
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
self.image_to_video = AsyncImageToVideoClient(base_client=self._base_client)
|
|
148
|
+
|
|
149
|
+
self.lip_sync = AsyncLipSyncClient(base_client=self._base_client)
|
|
150
|
+
|
|
151
|
+
self.text_to_video = AsyncTextToVideoClient(base_client=self._base_client)
|
|
152
|
+
|
|
153
|
+
self.video_to_video = AsyncVideoToVideoClient(base_client=self._base_client)
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
|
|
2
|
+
### create <a name="create"></a>
|
|
3
|
+
Face Swap video
|
|
4
|
+
|
|
5
|
+
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.
|
|
6
|
+
|
|
7
|
+
Get more information about this mode at our [product page](/products/face-swap).
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
**API Endpoint**: `POST /v1/face-swap`
|
|
11
|
+
|
|
12
|
+
#### Synchronous Client
|
|
13
|
+
|
|
14
|
+
```python
|
|
15
|
+
from magic_hour import Client
|
|
16
|
+
from os import getenv
|
|
17
|
+
|
|
18
|
+
client = Client(token=getenv("API_TOKEN"))
|
|
19
|
+
res = client.v1.face_swap.create(
|
|
20
|
+
assets={
|
|
21
|
+
"image_file_path": "image/id/1234.png",
|
|
22
|
+
"video_file_path": "video/id/1234.mp4",
|
|
23
|
+
"video_source": "file",
|
|
24
|
+
},
|
|
25
|
+
end_seconds=15,
|
|
26
|
+
height=960,
|
|
27
|
+
start_seconds=0,
|
|
28
|
+
width=512,
|
|
29
|
+
name="Face Swap video",
|
|
30
|
+
)
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
#### Asynchronous Client
|
|
34
|
+
|
|
35
|
+
```python
|
|
36
|
+
from magic_hour import AsyncClient
|
|
37
|
+
from os import getenv
|
|
38
|
+
|
|
39
|
+
client = AsyncClient(token=getenv("API_TOKEN"))
|
|
40
|
+
res = await client.v1.face_swap.create(
|
|
41
|
+
assets={
|
|
42
|
+
"image_file_path": "image/id/1234.png",
|
|
43
|
+
"video_file_path": "video/id/1234.mp4",
|
|
44
|
+
"video_source": "file",
|
|
45
|
+
},
|
|
46
|
+
end_seconds=15,
|
|
47
|
+
height=960,
|
|
48
|
+
start_seconds=0,
|
|
49
|
+
width=512,
|
|
50
|
+
name="Face Swap video",
|
|
51
|
+
)
|
|
52
|
+
```
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import typing
|
|
2
|
+
|
|
3
|
+
from magic_hour.core import (
|
|
4
|
+
AsyncBaseClient,
|
|
5
|
+
RequestOptions,
|
|
6
|
+
SyncBaseClient,
|
|
7
|
+
default_request_options,
|
|
8
|
+
to_encodable,
|
|
9
|
+
type_utils,
|
|
10
|
+
)
|
|
11
|
+
from magic_hour.types import models, params
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class FaceSwapClient:
|
|
15
|
+
def __init__(self, *, base_client: SyncBaseClient):
|
|
16
|
+
self._base_client = base_client
|
|
17
|
+
|
|
18
|
+
def create(
|
|
19
|
+
self,
|
|
20
|
+
*,
|
|
21
|
+
assets: params.PostV1FaceSwapBodyAssets,
|
|
22
|
+
end_seconds: float,
|
|
23
|
+
height: int,
|
|
24
|
+
start_seconds: float,
|
|
25
|
+
width: int,
|
|
26
|
+
name: typing.Union[
|
|
27
|
+
typing.Optional[str], type_utils.NotGiven
|
|
28
|
+
] = type_utils.NOT_GIVEN,
|
|
29
|
+
request_options: typing.Optional[RequestOptions] = None,
|
|
30
|
+
) -> models.PostV1FaceSwapResponse:
|
|
31
|
+
"""
|
|
32
|
+
Face Swap video
|
|
33
|
+
|
|
34
|
+
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
|
+
|
|
36
|
+
Get more information about this mode at our [product page](/products/face-swap).
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
POST /v1/face-swap
|
|
40
|
+
|
|
41
|
+
Args:
|
|
42
|
+
name: The name of video
|
|
43
|
+
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
|
|
48
|
+
request_options: Additional options to customize the HTTP request
|
|
49
|
+
|
|
50
|
+
Returns:
|
|
51
|
+
Success
|
|
52
|
+
|
|
53
|
+
Raises:
|
|
54
|
+
ApiError: A custom exception class that provides additional context
|
|
55
|
+
for API errors, including the HTTP status code and response body.
|
|
56
|
+
|
|
57
|
+
Examples:
|
|
58
|
+
```py
|
|
59
|
+
client.v1.face_swap.create(
|
|
60
|
+
assets={"image_file_path": "image/id/1234.png", "video_source": "file"},
|
|
61
|
+
end_seconds=15,
|
|
62
|
+
height=960,
|
|
63
|
+
start_seconds=0,
|
|
64
|
+
width=512,
|
|
65
|
+
name="Face Swap video",
|
|
66
|
+
)
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
"""
|
|
70
|
+
_json = to_encodable(
|
|
71
|
+
item={
|
|
72
|
+
"name": name,
|
|
73
|
+
"assets": assets,
|
|
74
|
+
"end_seconds": end_seconds,
|
|
75
|
+
"height": height,
|
|
76
|
+
"start_seconds": start_seconds,
|
|
77
|
+
"width": width,
|
|
78
|
+
},
|
|
79
|
+
dump_with=params._SerializerPostV1FaceSwapBody,
|
|
80
|
+
)
|
|
81
|
+
return self._base_client.request(
|
|
82
|
+
method="POST",
|
|
83
|
+
path="/v1/face-swap",
|
|
84
|
+
auth_names=["bearerAuth"],
|
|
85
|
+
json=_json,
|
|
86
|
+
cast_to=models.PostV1FaceSwapResponse,
|
|
87
|
+
request_options=request_options or default_request_options(),
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
class AsyncFaceSwapClient:
|
|
92
|
+
def __init__(self, *, base_client: AsyncBaseClient):
|
|
93
|
+
self._base_client = base_client
|
|
94
|
+
|
|
95
|
+
async def create(
|
|
96
|
+
self,
|
|
97
|
+
*,
|
|
98
|
+
assets: params.PostV1FaceSwapBodyAssets,
|
|
99
|
+
end_seconds: float,
|
|
100
|
+
height: int,
|
|
101
|
+
start_seconds: float,
|
|
102
|
+
width: int,
|
|
103
|
+
name: typing.Union[
|
|
104
|
+
typing.Optional[str], type_utils.NotGiven
|
|
105
|
+
] = type_utils.NOT_GIVEN,
|
|
106
|
+
request_options: typing.Optional[RequestOptions] = None,
|
|
107
|
+
) -> models.PostV1FaceSwapResponse:
|
|
108
|
+
"""
|
|
109
|
+
Face Swap video
|
|
110
|
+
|
|
111
|
+
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.
|
|
112
|
+
|
|
113
|
+
Get more information about this mode at our [product page](/products/face-swap).
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
POST /v1/face-swap
|
|
117
|
+
|
|
118
|
+
Args:
|
|
119
|
+
name: The name of video
|
|
120
|
+
assets: Provide the assets for face swap. For video, The `video_source` field determines whether `video_file_path` or `youtube_url` field is used
|
|
121
|
+
end_seconds: The end time of the input video in seconds
|
|
122
|
+
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
|
|
123
|
+
start_seconds: The start time of the input video in seconds
|
|
124
|
+
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
|
|
125
|
+
request_options: Additional options to customize the HTTP request
|
|
126
|
+
|
|
127
|
+
Returns:
|
|
128
|
+
Success
|
|
129
|
+
|
|
130
|
+
Raises:
|
|
131
|
+
ApiError: A custom exception class that provides additional context
|
|
132
|
+
for API errors, including the HTTP status code and response body.
|
|
133
|
+
|
|
134
|
+
Examples:
|
|
135
|
+
```py
|
|
136
|
+
await client.v1.face_swap.create(
|
|
137
|
+
assets={"image_file_path": "image/id/1234.png", "video_source": "file"},
|
|
138
|
+
end_seconds=15,
|
|
139
|
+
height=960,
|
|
140
|
+
start_seconds=0,
|
|
141
|
+
width=512,
|
|
142
|
+
name="Face Swap video",
|
|
143
|
+
)
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
"""
|
|
147
|
+
_json = to_encodable(
|
|
148
|
+
item={
|
|
149
|
+
"name": name,
|
|
150
|
+
"assets": assets,
|
|
151
|
+
"end_seconds": end_seconds,
|
|
152
|
+
"height": height,
|
|
153
|
+
"start_seconds": start_seconds,
|
|
154
|
+
"width": width,
|
|
155
|
+
},
|
|
156
|
+
dump_with=params._SerializerPostV1FaceSwapBody,
|
|
157
|
+
)
|
|
158
|
+
return await self._base_client.request(
|
|
159
|
+
method="POST",
|
|
160
|
+
path="/v1/face-swap",
|
|
161
|
+
auth_names=["bearerAuth"],
|
|
162
|
+
json=_json,
|
|
163
|
+
cast_to=models.PostV1FaceSwapResponse,
|
|
164
|
+
request_options=request_options or default_request_options(),
|
|
165
|
+
)
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
|
|
2
|
+
### create <a name="create"></a>
|
|
3
|
+
Face Swap Photo
|
|
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
|
|
6
|
+
|
|
7
|
+
**API Endpoint**: `POST /v1/face-swap-photo`
|
|
8
|
+
|
|
9
|
+
#### Synchronous Client
|
|
10
|
+
|
|
11
|
+
```python
|
|
12
|
+
from magic_hour import Client
|
|
13
|
+
from os import getenv
|
|
14
|
+
|
|
15
|
+
client = Client(token=getenv("API_TOKEN"))
|
|
16
|
+
res = client.v1.face_swap_photo.create(
|
|
17
|
+
assets={
|
|
18
|
+
"source_file_path": "api-assets/id/1234.png",
|
|
19
|
+
"target_file_path": "api-assets/id/1234.png",
|
|
20
|
+
},
|
|
21
|
+
name="Face Swap image",
|
|
22
|
+
)
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
#### Asynchronous Client
|
|
26
|
+
|
|
27
|
+
```python
|
|
28
|
+
from magic_hour import AsyncClient
|
|
29
|
+
from os import getenv
|
|
30
|
+
|
|
31
|
+
client = AsyncClient(token=getenv("API_TOKEN"))
|
|
32
|
+
res = await client.v1.face_swap_photo.create(
|
|
33
|
+
assets={
|
|
34
|
+
"source_file_path": "api-assets/id/1234.png",
|
|
35
|
+
"target_file_path": "api-assets/id/1234.png",
|
|
36
|
+
},
|
|
37
|
+
name="Face Swap image",
|
|
38
|
+
)
|
|
39
|
+
```
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import typing
|
|
2
|
+
|
|
3
|
+
from magic_hour.core import (
|
|
4
|
+
AsyncBaseClient,
|
|
5
|
+
RequestOptions,
|
|
6
|
+
SyncBaseClient,
|
|
7
|
+
default_request_options,
|
|
8
|
+
to_encodable,
|
|
9
|
+
type_utils,
|
|
10
|
+
)
|
|
11
|
+
from magic_hour.types import models, params
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class FaceSwapPhotoClient:
|
|
15
|
+
def __init__(self, *, base_client: SyncBaseClient):
|
|
16
|
+
self._base_client = base_client
|
|
17
|
+
|
|
18
|
+
def create(
|
|
19
|
+
self,
|
|
20
|
+
*,
|
|
21
|
+
assets: params.PostV1FaceSwapPhotoBodyAssets,
|
|
22
|
+
name: typing.Union[
|
|
23
|
+
typing.Optional[str], type_utils.NotGiven
|
|
24
|
+
] = type_utils.NOT_GIVEN,
|
|
25
|
+
request_options: typing.Optional[RequestOptions] = None,
|
|
26
|
+
) -> models.PostV1FaceSwapPhotoResponse:
|
|
27
|
+
"""
|
|
28
|
+
Face Swap Photo
|
|
29
|
+
|
|
30
|
+
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
|
|
31
|
+
|
|
32
|
+
POST /v1/face-swap-photo
|
|
33
|
+
|
|
34
|
+
Args:
|
|
35
|
+
name: The name of image
|
|
36
|
+
assets: Provide the assets for face swap photo
|
|
37
|
+
request_options: Additional options to customize the HTTP request
|
|
38
|
+
|
|
39
|
+
Returns:
|
|
40
|
+
Success
|
|
41
|
+
|
|
42
|
+
Raises:
|
|
43
|
+
ApiError: A custom exception class that provides additional context
|
|
44
|
+
for API errors, including the HTTP status code and response body.
|
|
45
|
+
|
|
46
|
+
Examples:
|
|
47
|
+
```py
|
|
48
|
+
client.v1.face_swap_photo.create(
|
|
49
|
+
assets={
|
|
50
|
+
"source_file_path": "api-assets/id/1234.png",
|
|
51
|
+
"target_file_path": "api-assets/id/1234.png",
|
|
52
|
+
},
|
|
53
|
+
name="Face Swap image",
|
|
54
|
+
)
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
"""
|
|
58
|
+
_json = to_encodable(
|
|
59
|
+
item={"name": name, "assets": assets},
|
|
60
|
+
dump_with=params._SerializerPostV1FaceSwapPhotoBody,
|
|
61
|
+
)
|
|
62
|
+
return self._base_client.request(
|
|
63
|
+
method="POST",
|
|
64
|
+
path="/v1/face-swap-photo",
|
|
65
|
+
auth_names=["bearerAuth"],
|
|
66
|
+
json=_json,
|
|
67
|
+
cast_to=models.PostV1FaceSwapPhotoResponse,
|
|
68
|
+
request_options=request_options or default_request_options(),
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
class AsyncFaceSwapPhotoClient:
|
|
73
|
+
def __init__(self, *, base_client: AsyncBaseClient):
|
|
74
|
+
self._base_client = base_client
|
|
75
|
+
|
|
76
|
+
async def create(
|
|
77
|
+
self,
|
|
78
|
+
*,
|
|
79
|
+
assets: params.PostV1FaceSwapPhotoBodyAssets,
|
|
80
|
+
name: typing.Union[
|
|
81
|
+
typing.Optional[str], type_utils.NotGiven
|
|
82
|
+
] = type_utils.NOT_GIVEN,
|
|
83
|
+
request_options: typing.Optional[RequestOptions] = None,
|
|
84
|
+
) -> models.PostV1FaceSwapPhotoResponse:
|
|
85
|
+
"""
|
|
86
|
+
Face Swap Photo
|
|
87
|
+
|
|
88
|
+
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
|
|
89
|
+
|
|
90
|
+
POST /v1/face-swap-photo
|
|
91
|
+
|
|
92
|
+
Args:
|
|
93
|
+
name: The name of image
|
|
94
|
+
assets: Provide the assets for face swap photo
|
|
95
|
+
request_options: Additional options to customize the HTTP request
|
|
96
|
+
|
|
97
|
+
Returns:
|
|
98
|
+
Success
|
|
99
|
+
|
|
100
|
+
Raises:
|
|
101
|
+
ApiError: A custom exception class that provides additional context
|
|
102
|
+
for API errors, including the HTTP status code and response body.
|
|
103
|
+
|
|
104
|
+
Examples:
|
|
105
|
+
```py
|
|
106
|
+
await client.v1.face_swap_photo.create(
|
|
107
|
+
assets={
|
|
108
|
+
"source_file_path": "api-assets/id/1234.png",
|
|
109
|
+
"target_file_path": "api-assets/id/1234.png",
|
|
110
|
+
},
|
|
111
|
+
name="Face Swap image",
|
|
112
|
+
)
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
"""
|
|
116
|
+
_json = to_encodable(
|
|
117
|
+
item={"name": name, "assets": assets},
|
|
118
|
+
dump_with=params._SerializerPostV1FaceSwapPhotoBody,
|
|
119
|
+
)
|
|
120
|
+
return await self._base_client.request(
|
|
121
|
+
method="POST",
|
|
122
|
+
path="/v1/face-swap-photo",
|
|
123
|
+
auth_names=["bearerAuth"],
|
|
124
|
+
json=_json,
|
|
125
|
+
cast_to=models.PostV1FaceSwapPhotoResponse,
|
|
126
|
+
request_options=request_options or default_request_options(),
|
|
127
|
+
)
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
from magic_hour.core import AsyncBaseClient, SyncBaseClient
|
|
2
|
+
from magic_hour.resources.v1.files.upload_urls import (
|
|
3
|
+
AsyncUploadUrlsClient,
|
|
4
|
+
UploadUrlsClient,
|
|
5
|
+
)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class FilesClient:
|
|
9
|
+
def __init__(self, *, base_client: SyncBaseClient):
|
|
10
|
+
self._base_client = base_client
|
|
11
|
+
|
|
12
|
+
self.upload_urls = UploadUrlsClient(base_client=self._base_client)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class AsyncFilesClient:
|
|
16
|
+
def __init__(self, *, base_client: AsyncBaseClient):
|
|
17
|
+
self._base_client = base_client
|
|
18
|
+
|
|
19
|
+
self.upload_urls = AsyncUploadUrlsClient(base_client=self._base_client)
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
|
|
2
|
+
### create <a name="create"></a>
|
|
3
|
+
Generate asset upload urls
|
|
4
|
+
|
|
5
|
+
Create a list of urls used to upload the assets needed to generate a video. Each video type has their own requirements on what assets are required. Please refer to the specific mode API for more details. The response array will be in the same order as the request body.
|
|
6
|
+
|
|
7
|
+
Below is the list of valid extensions for each asset type:
|
|
8
|
+
|
|
9
|
+
- video: mp4, mov, webm
|
|
10
|
+
- audio: mp3, mpeg, wav, aac, aiff, flac
|
|
11
|
+
- image: png, jpg, jpeg, webp, avif, jp2, tiff, bmp
|
|
12
|
+
|
|
13
|
+
Note: `.gif` is supported for face swap API `video_file_path` field.
|
|
14
|
+
|
|
15
|
+
After receiving the upload url, you can upload the file by sending a PUT request with the header `'Content-Type: application/octet-stream'`.
|
|
16
|
+
|
|
17
|
+
For example using curl
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
curl -X PUT -H 'Content-Type: application/octet-stream' \
|
|
21
|
+
--data '@/path/to/file/video.mp4' \
|
|
22
|
+
https://videos.magichour.ai/api-assets/id/video.mp4?auth-value=1234567890
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
**API Endpoint**: `POST /v1/files/upload-urls`
|
|
27
|
+
|
|
28
|
+
#### Synchronous Client
|
|
29
|
+
|
|
30
|
+
```python
|
|
31
|
+
from magic_hour import Client
|
|
32
|
+
from os import getenv
|
|
33
|
+
|
|
34
|
+
client = Client(token=getenv("API_TOKEN"))
|
|
35
|
+
res = client.v1.files.upload_urls.create(
|
|
36
|
+
items=[
|
|
37
|
+
{"extension": "mp4", "type_field": "video"},
|
|
38
|
+
{"extension": "mp3", "type_field": "audio"},
|
|
39
|
+
]
|
|
40
|
+
)
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
#### Asynchronous Client
|
|
44
|
+
|
|
45
|
+
```python
|
|
46
|
+
from magic_hour import AsyncClient
|
|
47
|
+
from os import getenv
|
|
48
|
+
|
|
49
|
+
client = AsyncClient(token=getenv("API_TOKEN"))
|
|
50
|
+
res = await client.v1.files.upload_urls.create(
|
|
51
|
+
items=[
|
|
52
|
+
{"extension": "mp4", "type_field": "video"},
|
|
53
|
+
{"extension": "mp3", "type_field": "audio"},
|
|
54
|
+
]
|
|
55
|
+
)
|
|
56
|
+
```
|