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,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 ImageToVideoClient:
|
|
15
|
+
def __init__(self, *, base_client: SyncBaseClient):
|
|
16
|
+
self._base_client = base_client
|
|
17
|
+
|
|
18
|
+
def create(
|
|
19
|
+
self,
|
|
20
|
+
*,
|
|
21
|
+
assets: params.PostV1ImageToVideoBodyAssets,
|
|
22
|
+
end_seconds: float,
|
|
23
|
+
height: int,
|
|
24
|
+
style: params.PostV1ImageToVideoBodyStyle,
|
|
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.PostV1ImageToVideoResponse:
|
|
31
|
+
"""
|
|
32
|
+
Image-to-Video
|
|
33
|
+
|
|
34
|
+
Create a Image To Video 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/image-to-video).
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
POST /v1/image-to-video
|
|
40
|
+
|
|
41
|
+
Args:
|
|
42
|
+
name: The name of video
|
|
43
|
+
assets: Provide the assets for image-to-video.
|
|
44
|
+
end_seconds: The total duration of the output video in seconds.
|
|
45
|
+
height: The height of the input video. This value will help determine the final orientation of the output video. The output video resolution may not match the input.
|
|
46
|
+
style: PostV1ImageToVideoBodyStyle
|
|
47
|
+
width: The width of the input video. This value will help determine the final orientation of the output video. The output video resolution may not match the input.
|
|
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.image_to_video.create(
|
|
60
|
+
assets={"image_file_path": "image/id/1234.png"},
|
|
61
|
+
end_seconds=5,
|
|
62
|
+
height=960,
|
|
63
|
+
style={"prompt": "string"},
|
|
64
|
+
width=512,
|
|
65
|
+
name="Image To Video 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
|
+
"style": style,
|
|
77
|
+
"width": width,
|
|
78
|
+
},
|
|
79
|
+
dump_with=params._SerializerPostV1ImageToVideoBody,
|
|
80
|
+
)
|
|
81
|
+
return self._base_client.request(
|
|
82
|
+
method="POST",
|
|
83
|
+
path="/v1/image-to-video",
|
|
84
|
+
auth_names=["bearerAuth"],
|
|
85
|
+
json=_json,
|
|
86
|
+
cast_to=models.PostV1ImageToVideoResponse,
|
|
87
|
+
request_options=request_options or default_request_options(),
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
class AsyncImageToVideoClient:
|
|
92
|
+
def __init__(self, *, base_client: AsyncBaseClient):
|
|
93
|
+
self._base_client = base_client
|
|
94
|
+
|
|
95
|
+
async def create(
|
|
96
|
+
self,
|
|
97
|
+
*,
|
|
98
|
+
assets: params.PostV1ImageToVideoBodyAssets,
|
|
99
|
+
end_seconds: float,
|
|
100
|
+
height: int,
|
|
101
|
+
style: params.PostV1ImageToVideoBodyStyle,
|
|
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.PostV1ImageToVideoResponse:
|
|
108
|
+
"""
|
|
109
|
+
Image-to-Video
|
|
110
|
+
|
|
111
|
+
Create a Image To Video 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/image-to-video).
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
POST /v1/image-to-video
|
|
117
|
+
|
|
118
|
+
Args:
|
|
119
|
+
name: The name of video
|
|
120
|
+
assets: Provide the assets for image-to-video.
|
|
121
|
+
end_seconds: The total duration of the output video in seconds.
|
|
122
|
+
height: The height of the input video. This value will help determine the final orientation of the output video. The output video resolution may not match the input.
|
|
123
|
+
style: PostV1ImageToVideoBodyStyle
|
|
124
|
+
width: The width of the input video. This value will help determine the final orientation of the output video. The output video resolution may not match the input.
|
|
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.image_to_video.create(
|
|
137
|
+
assets={"image_file_path": "image/id/1234.png"},
|
|
138
|
+
end_seconds=5,
|
|
139
|
+
height=960,
|
|
140
|
+
style={"prompt": "string"},
|
|
141
|
+
width=512,
|
|
142
|
+
name="Image To Video 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
|
+
"style": style,
|
|
154
|
+
"width": width,
|
|
155
|
+
},
|
|
156
|
+
dump_with=params._SerializerPostV1ImageToVideoBody,
|
|
157
|
+
)
|
|
158
|
+
return await self._base_client.request(
|
|
159
|
+
method="POST",
|
|
160
|
+
path="/v1/image-to-video",
|
|
161
|
+
auth_names=["bearerAuth"],
|
|
162
|
+
json=_json,
|
|
163
|
+
cast_to=models.PostV1ImageToVideoResponse,
|
|
164
|
+
request_options=request_options or default_request_options(),
|
|
165
|
+
)
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
|
|
2
|
+
### create <a name="create"></a>
|
|
3
|
+
Lip Sync
|
|
4
|
+
|
|
5
|
+
Create a Lip Sync 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/lip-sync).
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
**API Endpoint**: `POST /v1/lip-sync`
|
|
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.lip_sync.create(
|
|
20
|
+
assets={
|
|
21
|
+
"audio_file_path": "audio/id/1234.mp3",
|
|
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
|
+
max_fps_limit=12,
|
|
30
|
+
name="Lip Sync video",
|
|
31
|
+
)
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
#### Asynchronous Client
|
|
35
|
+
|
|
36
|
+
```python
|
|
37
|
+
from magic_hour import AsyncClient
|
|
38
|
+
from os import getenv
|
|
39
|
+
|
|
40
|
+
client = AsyncClient(token=getenv("API_TOKEN"))
|
|
41
|
+
res = await client.v1.lip_sync.create(
|
|
42
|
+
assets={
|
|
43
|
+
"audio_file_path": "audio/id/1234.mp3",
|
|
44
|
+
"video_file_path": "video/id/1234.mp4",
|
|
45
|
+
"video_source": "file",
|
|
46
|
+
},
|
|
47
|
+
end_seconds=15,
|
|
48
|
+
height=960,
|
|
49
|
+
start_seconds=0,
|
|
50
|
+
width=512,
|
|
51
|
+
max_fps_limit=12,
|
|
52
|
+
name="Lip Sync video",
|
|
53
|
+
)
|
|
54
|
+
```
|
|
@@ -0,0 +1,177 @@
|
|
|
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 LipSyncClient:
|
|
15
|
+
def __init__(self, *, base_client: SyncBaseClient):
|
|
16
|
+
self._base_client = base_client
|
|
17
|
+
|
|
18
|
+
def create(
|
|
19
|
+
self,
|
|
20
|
+
*,
|
|
21
|
+
assets: params.PostV1LipSyncBodyAssets,
|
|
22
|
+
end_seconds: float,
|
|
23
|
+
height: int,
|
|
24
|
+
start_seconds: float,
|
|
25
|
+
width: int,
|
|
26
|
+
max_fps_limit: typing.Union[
|
|
27
|
+
typing.Optional[float], type_utils.NotGiven
|
|
28
|
+
] = type_utils.NOT_GIVEN,
|
|
29
|
+
name: typing.Union[
|
|
30
|
+
typing.Optional[str], type_utils.NotGiven
|
|
31
|
+
] = type_utils.NOT_GIVEN,
|
|
32
|
+
request_options: typing.Optional[RequestOptions] = None,
|
|
33
|
+
) -> models.PostV1LipSyncResponse:
|
|
34
|
+
"""
|
|
35
|
+
Lip Sync
|
|
36
|
+
|
|
37
|
+
Create a Lip Sync 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.
|
|
38
|
+
|
|
39
|
+
Get more information about this mode at our [product page](/products/lip-sync).
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
POST /v1/lip-sync
|
|
43
|
+
|
|
44
|
+
Args:
|
|
45
|
+
max_fps_limit: Defines the maximum FPS (frames per second) for the output video. If the input video's FPS is lower than this limit, the output video will retain the input FPS. This is useful for reducing unnecessary frame usage in scenarios where high FPS is not required.
|
|
46
|
+
name: The name of video
|
|
47
|
+
assets: Provide the assets for lip-sync. For video, The `video_source` field determines whether `video_file_path` or `youtube_url` field is used
|
|
48
|
+
end_seconds: The end time of the input video in seconds
|
|
49
|
+
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
|
|
50
|
+
start_seconds: The start time of the input video in seconds
|
|
51
|
+
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
|
|
52
|
+
request_options: Additional options to customize the HTTP request
|
|
53
|
+
|
|
54
|
+
Returns:
|
|
55
|
+
Success
|
|
56
|
+
|
|
57
|
+
Raises:
|
|
58
|
+
ApiError: A custom exception class that provides additional context
|
|
59
|
+
for API errors, including the HTTP status code and response body.
|
|
60
|
+
|
|
61
|
+
Examples:
|
|
62
|
+
```py
|
|
63
|
+
client.v1.lip_sync.create(
|
|
64
|
+
assets={"audio_file_path": "audio/id/1234.mp3", "video_source": "file"},
|
|
65
|
+
end_seconds=15,
|
|
66
|
+
height=960,
|
|
67
|
+
start_seconds=0,
|
|
68
|
+
width=512,
|
|
69
|
+
max_fps_limit=12,
|
|
70
|
+
name="Lip Sync video",
|
|
71
|
+
)
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
"""
|
|
75
|
+
_json = to_encodable(
|
|
76
|
+
item={
|
|
77
|
+
"max_fps_limit": max_fps_limit,
|
|
78
|
+
"name": name,
|
|
79
|
+
"assets": assets,
|
|
80
|
+
"end_seconds": end_seconds,
|
|
81
|
+
"height": height,
|
|
82
|
+
"start_seconds": start_seconds,
|
|
83
|
+
"width": width,
|
|
84
|
+
},
|
|
85
|
+
dump_with=params._SerializerPostV1LipSyncBody,
|
|
86
|
+
)
|
|
87
|
+
return self._base_client.request(
|
|
88
|
+
method="POST",
|
|
89
|
+
path="/v1/lip-sync",
|
|
90
|
+
auth_names=["bearerAuth"],
|
|
91
|
+
json=_json,
|
|
92
|
+
cast_to=models.PostV1LipSyncResponse,
|
|
93
|
+
request_options=request_options or default_request_options(),
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
class AsyncLipSyncClient:
|
|
98
|
+
def __init__(self, *, base_client: AsyncBaseClient):
|
|
99
|
+
self._base_client = base_client
|
|
100
|
+
|
|
101
|
+
async def create(
|
|
102
|
+
self,
|
|
103
|
+
*,
|
|
104
|
+
assets: params.PostV1LipSyncBodyAssets,
|
|
105
|
+
end_seconds: float,
|
|
106
|
+
height: int,
|
|
107
|
+
start_seconds: float,
|
|
108
|
+
width: int,
|
|
109
|
+
max_fps_limit: typing.Union[
|
|
110
|
+
typing.Optional[float], type_utils.NotGiven
|
|
111
|
+
] = type_utils.NOT_GIVEN,
|
|
112
|
+
name: typing.Union[
|
|
113
|
+
typing.Optional[str], type_utils.NotGiven
|
|
114
|
+
] = type_utils.NOT_GIVEN,
|
|
115
|
+
request_options: typing.Optional[RequestOptions] = None,
|
|
116
|
+
) -> models.PostV1LipSyncResponse:
|
|
117
|
+
"""
|
|
118
|
+
Lip Sync
|
|
119
|
+
|
|
120
|
+
Create a Lip Sync 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.
|
|
121
|
+
|
|
122
|
+
Get more information about this mode at our [product page](/products/lip-sync).
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
POST /v1/lip-sync
|
|
126
|
+
|
|
127
|
+
Args:
|
|
128
|
+
max_fps_limit: Defines the maximum FPS (frames per second) for the output video. If the input video's FPS is lower than this limit, the output video will retain the input FPS. This is useful for reducing unnecessary frame usage in scenarios where high FPS is not required.
|
|
129
|
+
name: The name of video
|
|
130
|
+
assets: Provide the assets for lip-sync. For video, The `video_source` field determines whether `video_file_path` or `youtube_url` field is used
|
|
131
|
+
end_seconds: The end time of the input video in seconds
|
|
132
|
+
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
|
|
133
|
+
start_seconds: The start time of the input video in seconds
|
|
134
|
+
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
|
|
135
|
+
request_options: Additional options to customize the HTTP request
|
|
136
|
+
|
|
137
|
+
Returns:
|
|
138
|
+
Success
|
|
139
|
+
|
|
140
|
+
Raises:
|
|
141
|
+
ApiError: A custom exception class that provides additional context
|
|
142
|
+
for API errors, including the HTTP status code and response body.
|
|
143
|
+
|
|
144
|
+
Examples:
|
|
145
|
+
```py
|
|
146
|
+
await client.v1.lip_sync.create(
|
|
147
|
+
assets={"audio_file_path": "audio/id/1234.mp3", "video_source": "file"},
|
|
148
|
+
end_seconds=15,
|
|
149
|
+
height=960,
|
|
150
|
+
start_seconds=0,
|
|
151
|
+
width=512,
|
|
152
|
+
max_fps_limit=12,
|
|
153
|
+
name="Lip Sync video",
|
|
154
|
+
)
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
"""
|
|
158
|
+
_json = to_encodable(
|
|
159
|
+
item={
|
|
160
|
+
"max_fps_limit": max_fps_limit,
|
|
161
|
+
"name": name,
|
|
162
|
+
"assets": assets,
|
|
163
|
+
"end_seconds": end_seconds,
|
|
164
|
+
"height": height,
|
|
165
|
+
"start_seconds": start_seconds,
|
|
166
|
+
"width": width,
|
|
167
|
+
},
|
|
168
|
+
dump_with=params._SerializerPostV1LipSyncBody,
|
|
169
|
+
)
|
|
170
|
+
return await self._base_client.request(
|
|
171
|
+
method="POST",
|
|
172
|
+
path="/v1/lip-sync",
|
|
173
|
+
auth_names=["bearerAuth"],
|
|
174
|
+
json=_json,
|
|
175
|
+
cast_to=models.PostV1LipSyncResponse,
|
|
176
|
+
request_options=request_options or default_request_options(),
|
|
177
|
+
)
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
|
|
2
|
+
### create <a name="create"></a>
|
|
3
|
+
Text-to-Video
|
|
4
|
+
|
|
5
|
+
Create a Text To Video 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/text-to-video).
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
**API Endpoint**: `POST /v1/text-to-video`
|
|
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.text_to_video.create(
|
|
20
|
+
end_seconds=5,
|
|
21
|
+
orientation="landscape",
|
|
22
|
+
style={"prompt": "string"},
|
|
23
|
+
name="Text To Video video",
|
|
24
|
+
)
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
#### Asynchronous Client
|
|
28
|
+
|
|
29
|
+
```python
|
|
30
|
+
from magic_hour import AsyncClient
|
|
31
|
+
from os import getenv
|
|
32
|
+
|
|
33
|
+
client = AsyncClient(token=getenv("API_TOKEN"))
|
|
34
|
+
res = await client.v1.text_to_video.create(
|
|
35
|
+
end_seconds=5,
|
|
36
|
+
orientation="landscape",
|
|
37
|
+
style={"prompt": "string"},
|
|
38
|
+
name="Text To Video video",
|
|
39
|
+
)
|
|
40
|
+
```
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import typing_extensions
|
|
2
|
+
import typing
|
|
3
|
+
|
|
4
|
+
from magic_hour.core import (
|
|
5
|
+
AsyncBaseClient,
|
|
6
|
+
RequestOptions,
|
|
7
|
+
SyncBaseClient,
|
|
8
|
+
default_request_options,
|
|
9
|
+
to_encodable,
|
|
10
|
+
type_utils,
|
|
11
|
+
)
|
|
12
|
+
from magic_hour.types import models, params
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class TextToVideoClient:
|
|
16
|
+
def __init__(self, *, base_client: SyncBaseClient):
|
|
17
|
+
self._base_client = base_client
|
|
18
|
+
|
|
19
|
+
def create(
|
|
20
|
+
self,
|
|
21
|
+
*,
|
|
22
|
+
end_seconds: float,
|
|
23
|
+
orientation: typing_extensions.Literal["landscape", "portrait", "square"],
|
|
24
|
+
style: params.PostV1TextToVideoBodyStyle,
|
|
25
|
+
name: typing.Union[
|
|
26
|
+
typing.Optional[str], type_utils.NotGiven
|
|
27
|
+
] = type_utils.NOT_GIVEN,
|
|
28
|
+
request_options: typing.Optional[RequestOptions] = None,
|
|
29
|
+
) -> models.PostV1TextToVideoResponse:
|
|
30
|
+
"""
|
|
31
|
+
Text-to-Video
|
|
32
|
+
|
|
33
|
+
Create a Text To Video 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.
|
|
34
|
+
|
|
35
|
+
Get more information about this mode at our [product page](/products/text-to-video).
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
POST /v1/text-to-video
|
|
39
|
+
|
|
40
|
+
Args:
|
|
41
|
+
name: The name of video
|
|
42
|
+
end_seconds: The total duration of the output video in seconds.
|
|
43
|
+
orientation: Determines the orientation of the output video
|
|
44
|
+
style: PostV1TextToVideoBodyStyle
|
|
45
|
+
request_options: Additional options to customize the HTTP request
|
|
46
|
+
|
|
47
|
+
Returns:
|
|
48
|
+
Success
|
|
49
|
+
|
|
50
|
+
Raises:
|
|
51
|
+
ApiError: A custom exception class that provides additional context
|
|
52
|
+
for API errors, including the HTTP status code and response body.
|
|
53
|
+
|
|
54
|
+
Examples:
|
|
55
|
+
```py
|
|
56
|
+
client.v1.text_to_video.create(
|
|
57
|
+
end_seconds=5,
|
|
58
|
+
orientation="landscape",
|
|
59
|
+
style={"prompt": "string"},
|
|
60
|
+
name="Text To Video video",
|
|
61
|
+
)
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
"""
|
|
65
|
+
_json = to_encodable(
|
|
66
|
+
item={
|
|
67
|
+
"name": name,
|
|
68
|
+
"end_seconds": end_seconds,
|
|
69
|
+
"orientation": orientation,
|
|
70
|
+
"style": style,
|
|
71
|
+
},
|
|
72
|
+
dump_with=params._SerializerPostV1TextToVideoBody,
|
|
73
|
+
)
|
|
74
|
+
return self._base_client.request(
|
|
75
|
+
method="POST",
|
|
76
|
+
path="/v1/text-to-video",
|
|
77
|
+
auth_names=["bearerAuth"],
|
|
78
|
+
json=_json,
|
|
79
|
+
cast_to=models.PostV1TextToVideoResponse,
|
|
80
|
+
request_options=request_options or default_request_options(),
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
class AsyncTextToVideoClient:
|
|
85
|
+
def __init__(self, *, base_client: AsyncBaseClient):
|
|
86
|
+
self._base_client = base_client
|
|
87
|
+
|
|
88
|
+
async def create(
|
|
89
|
+
self,
|
|
90
|
+
*,
|
|
91
|
+
end_seconds: float,
|
|
92
|
+
orientation: typing_extensions.Literal["landscape", "portrait", "square"],
|
|
93
|
+
style: params.PostV1TextToVideoBodyStyle,
|
|
94
|
+
name: typing.Union[
|
|
95
|
+
typing.Optional[str], type_utils.NotGiven
|
|
96
|
+
] = type_utils.NOT_GIVEN,
|
|
97
|
+
request_options: typing.Optional[RequestOptions] = None,
|
|
98
|
+
) -> models.PostV1TextToVideoResponse:
|
|
99
|
+
"""
|
|
100
|
+
Text-to-Video
|
|
101
|
+
|
|
102
|
+
Create a Text To Video 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.
|
|
103
|
+
|
|
104
|
+
Get more information about this mode at our [product page](/products/text-to-video).
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
POST /v1/text-to-video
|
|
108
|
+
|
|
109
|
+
Args:
|
|
110
|
+
name: The name of video
|
|
111
|
+
end_seconds: The total duration of the output video in seconds.
|
|
112
|
+
orientation: Determines the orientation of the output video
|
|
113
|
+
style: PostV1TextToVideoBodyStyle
|
|
114
|
+
request_options: Additional options to customize the HTTP request
|
|
115
|
+
|
|
116
|
+
Returns:
|
|
117
|
+
Success
|
|
118
|
+
|
|
119
|
+
Raises:
|
|
120
|
+
ApiError: A custom exception class that provides additional context
|
|
121
|
+
for API errors, including the HTTP status code and response body.
|
|
122
|
+
|
|
123
|
+
Examples:
|
|
124
|
+
```py
|
|
125
|
+
await client.v1.text_to_video.create(
|
|
126
|
+
end_seconds=5,
|
|
127
|
+
orientation="landscape",
|
|
128
|
+
style={"prompt": "string"},
|
|
129
|
+
name="Text To Video video",
|
|
130
|
+
)
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
"""
|
|
134
|
+
_json = to_encodable(
|
|
135
|
+
item={
|
|
136
|
+
"name": name,
|
|
137
|
+
"end_seconds": end_seconds,
|
|
138
|
+
"orientation": orientation,
|
|
139
|
+
"style": style,
|
|
140
|
+
},
|
|
141
|
+
dump_with=params._SerializerPostV1TextToVideoBody,
|
|
142
|
+
)
|
|
143
|
+
return await self._base_client.request(
|
|
144
|
+
method="POST",
|
|
145
|
+
path="/v1/text-to-video",
|
|
146
|
+
auth_names=["bearerAuth"],
|
|
147
|
+
json=_json,
|
|
148
|
+
cast_to=models.PostV1TextToVideoResponse,
|
|
149
|
+
request_options=request_options or default_request_options(),
|
|
150
|
+
)
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
|
|
2
|
+
### delete <a name="delete"></a>
|
|
3
|
+
Delete video
|
|
4
|
+
|
|
5
|
+
Permanently delete the rendered video. This action is not reversible, please be sure before deleting.
|
|
6
|
+
|
|
7
|
+
**API Endpoint**: `DELETE /v1/video-projects/{id}`
|
|
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.video_projects.delete(id="string")
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
#### Asynchronous Client
|
|
20
|
+
|
|
21
|
+
```python
|
|
22
|
+
from magic_hour import AsyncClient
|
|
23
|
+
from os import getenv
|
|
24
|
+
|
|
25
|
+
client = AsyncClient(token=getenv("API_TOKEN"))
|
|
26
|
+
res = await client.v1.video_projects.delete(id="string")
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### get <a name="get"></a>
|
|
30
|
+
Get video details
|
|
31
|
+
|
|
32
|
+
Get the details of a video project. The `download` field will be `null` unless the video was successfully rendered.
|
|
33
|
+
|
|
34
|
+
The video can be one of the following status
|
|
35
|
+
- `draft` - not currently used
|
|
36
|
+
- `queued` - the job is queued and waiting for a GPU
|
|
37
|
+
- `rendering` - the generation is in progress
|
|
38
|
+
- `complete` - the video is successful created
|
|
39
|
+
- `error` - an error occurred during rendering
|
|
40
|
+
- `canceled` - video render is canceled by the user
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
**API Endpoint**: `GET /v1/video-projects/{id}`
|
|
44
|
+
|
|
45
|
+
#### Synchronous Client
|
|
46
|
+
|
|
47
|
+
```python
|
|
48
|
+
from magic_hour import Client
|
|
49
|
+
from os import getenv
|
|
50
|
+
|
|
51
|
+
client = Client(token=getenv("API_TOKEN"))
|
|
52
|
+
res = client.v1.video_projects.get(id="string")
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
#### Asynchronous Client
|
|
56
|
+
|
|
57
|
+
```python
|
|
58
|
+
from magic_hour import AsyncClient
|
|
59
|
+
from os import getenv
|
|
60
|
+
|
|
61
|
+
client = AsyncClient(token=getenv("API_TOKEN"))
|
|
62
|
+
res = await client.v1.video_projects.get(id="string")
|
|
63
|
+
```
|