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,177 @@
|
|
|
1
|
+
import typing
|
|
2
|
+
|
|
3
|
+
from magic_hour.core import (
|
|
4
|
+
AsyncBaseClient,
|
|
5
|
+
RequestOptions,
|
|
6
|
+
SyncBaseClient,
|
|
7
|
+
default_request_options,
|
|
8
|
+
)
|
|
9
|
+
from magic_hour.types import models
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class VideoProjectsClient:
|
|
13
|
+
def __init__(self, *, base_client: SyncBaseClient):
|
|
14
|
+
self._base_client = base_client
|
|
15
|
+
|
|
16
|
+
def delete(
|
|
17
|
+
self, *, id: str, request_options: typing.Optional[RequestOptions] = None
|
|
18
|
+
) -> None:
|
|
19
|
+
"""
|
|
20
|
+
Delete video
|
|
21
|
+
|
|
22
|
+
Permanently delete the rendered video. This action is not reversible, please be sure before deleting.
|
|
23
|
+
|
|
24
|
+
DELETE /v1/video-projects/{id}
|
|
25
|
+
|
|
26
|
+
Args:
|
|
27
|
+
id: The id of the video project
|
|
28
|
+
request_options: Additional options to customize the HTTP request
|
|
29
|
+
|
|
30
|
+
Returns:
|
|
31
|
+
204
|
|
32
|
+
|
|
33
|
+
Raises:
|
|
34
|
+
ApiError: A custom exception class that provides additional context
|
|
35
|
+
for API errors, including the HTTP status code and response body.
|
|
36
|
+
|
|
37
|
+
Examples:
|
|
38
|
+
```py
|
|
39
|
+
client.v1.video_projects.delete(id="string")
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
"""
|
|
43
|
+
self._base_client.request(
|
|
44
|
+
method="DELETE",
|
|
45
|
+
path=f"/v1/video-projects/{id}",
|
|
46
|
+
auth_names=["bearerAuth"],
|
|
47
|
+
cast_to=type(None),
|
|
48
|
+
request_options=request_options or default_request_options(),
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
def get(
|
|
52
|
+
self, *, id: str, request_options: typing.Optional[RequestOptions] = None
|
|
53
|
+
) -> models.GetV1VideoProjectsIdResponse:
|
|
54
|
+
"""
|
|
55
|
+
Get video details
|
|
56
|
+
|
|
57
|
+
Get the details of a video project. The `download` field will be `null` unless the video was successfully rendered.
|
|
58
|
+
|
|
59
|
+
The video can be one of the following status
|
|
60
|
+
- `draft` - not currently used
|
|
61
|
+
- `queued` - the job is queued and waiting for a GPU
|
|
62
|
+
- `rendering` - the generation is in progress
|
|
63
|
+
- `complete` - the video is successful created
|
|
64
|
+
- `error` - an error occurred during rendering
|
|
65
|
+
- `canceled` - video render is canceled by the user
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
GET /v1/video-projects/{id}
|
|
69
|
+
|
|
70
|
+
Args:
|
|
71
|
+
id: The id of the video
|
|
72
|
+
request_options: Additional options to customize the HTTP request
|
|
73
|
+
|
|
74
|
+
Returns:
|
|
75
|
+
Success
|
|
76
|
+
|
|
77
|
+
Raises:
|
|
78
|
+
ApiError: A custom exception class that provides additional context
|
|
79
|
+
for API errors, including the HTTP status code and response body.
|
|
80
|
+
|
|
81
|
+
Examples:
|
|
82
|
+
```py
|
|
83
|
+
client.v1.video_projects.get(id="string")
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
"""
|
|
87
|
+
return self._base_client.request(
|
|
88
|
+
method="GET",
|
|
89
|
+
path=f"/v1/video-projects/{id}",
|
|
90
|
+
auth_names=["bearerAuth"],
|
|
91
|
+
cast_to=models.GetV1VideoProjectsIdResponse,
|
|
92
|
+
request_options=request_options or default_request_options(),
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
class AsyncVideoProjectsClient:
|
|
97
|
+
def __init__(self, *, base_client: AsyncBaseClient):
|
|
98
|
+
self._base_client = base_client
|
|
99
|
+
|
|
100
|
+
async def delete(
|
|
101
|
+
self, *, id: str, request_options: typing.Optional[RequestOptions] = None
|
|
102
|
+
) -> None:
|
|
103
|
+
"""
|
|
104
|
+
Delete video
|
|
105
|
+
|
|
106
|
+
Permanently delete the rendered video. This action is not reversible, please be sure before deleting.
|
|
107
|
+
|
|
108
|
+
DELETE /v1/video-projects/{id}
|
|
109
|
+
|
|
110
|
+
Args:
|
|
111
|
+
id: The id of the video project
|
|
112
|
+
request_options: Additional options to customize the HTTP request
|
|
113
|
+
|
|
114
|
+
Returns:
|
|
115
|
+
204
|
|
116
|
+
|
|
117
|
+
Raises:
|
|
118
|
+
ApiError: A custom exception class that provides additional context
|
|
119
|
+
for API errors, including the HTTP status code and response body.
|
|
120
|
+
|
|
121
|
+
Examples:
|
|
122
|
+
```py
|
|
123
|
+
await client.v1.video_projects.delete(id="string")
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
"""
|
|
127
|
+
await self._base_client.request(
|
|
128
|
+
method="DELETE",
|
|
129
|
+
path=f"/v1/video-projects/{id}",
|
|
130
|
+
auth_names=["bearerAuth"],
|
|
131
|
+
cast_to=type(None),
|
|
132
|
+
request_options=request_options or default_request_options(),
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
async def get(
|
|
136
|
+
self, *, id: str, request_options: typing.Optional[RequestOptions] = None
|
|
137
|
+
) -> models.GetV1VideoProjectsIdResponse:
|
|
138
|
+
"""
|
|
139
|
+
Get video details
|
|
140
|
+
|
|
141
|
+
Get the details of a video project. The `download` field will be `null` unless the video was successfully rendered.
|
|
142
|
+
|
|
143
|
+
The video can be one of the following status
|
|
144
|
+
- `draft` - not currently used
|
|
145
|
+
- `queued` - the job is queued and waiting for a GPU
|
|
146
|
+
- `rendering` - the generation is in progress
|
|
147
|
+
- `complete` - the video is successful created
|
|
148
|
+
- `error` - an error occurred during rendering
|
|
149
|
+
- `canceled` - video render is canceled by the user
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
GET /v1/video-projects/{id}
|
|
153
|
+
|
|
154
|
+
Args:
|
|
155
|
+
id: The id of the video
|
|
156
|
+
request_options: Additional options to customize the HTTP request
|
|
157
|
+
|
|
158
|
+
Returns:
|
|
159
|
+
Success
|
|
160
|
+
|
|
161
|
+
Raises:
|
|
162
|
+
ApiError: A custom exception class that provides additional context
|
|
163
|
+
for API errors, including the HTTP status code and response body.
|
|
164
|
+
|
|
165
|
+
Examples:
|
|
166
|
+
```py
|
|
167
|
+
await client.v1.video_projects.get(id="string")
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
"""
|
|
171
|
+
return await self._base_client.request(
|
|
172
|
+
method="GET",
|
|
173
|
+
path=f"/v1/video-projects/{id}",
|
|
174
|
+
auth_names=["bearerAuth"],
|
|
175
|
+
cast_to=models.GetV1VideoProjectsIdResponse,
|
|
176
|
+
request_options=request_options or default_request_options(),
|
|
177
|
+
)
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
|
|
2
|
+
### create <a name="create"></a>
|
|
3
|
+
Video-to-Video
|
|
4
|
+
|
|
5
|
+
Create a Video 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/video-to-video).
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
**API Endpoint**: `POST /v1/video-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.video_to_video.create(
|
|
20
|
+
assets={"video_file_path": "video/id/1234.mp4", "video_source": "file"},
|
|
21
|
+
end_seconds=15,
|
|
22
|
+
height=960,
|
|
23
|
+
start_seconds=0,
|
|
24
|
+
style={
|
|
25
|
+
"art_style": "3D Render",
|
|
26
|
+
"model": "Absolute Reality",
|
|
27
|
+
"prompt": None,
|
|
28
|
+
"prompt_type": "append_default",
|
|
29
|
+
"version": "default",
|
|
30
|
+
},
|
|
31
|
+
width=512,
|
|
32
|
+
fps_resolution="HALF",
|
|
33
|
+
name="Video To Video video",
|
|
34
|
+
)
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
#### Asynchronous Client
|
|
38
|
+
|
|
39
|
+
```python
|
|
40
|
+
from magic_hour import AsyncClient
|
|
41
|
+
from os import getenv
|
|
42
|
+
|
|
43
|
+
client = AsyncClient(token=getenv("API_TOKEN"))
|
|
44
|
+
res = await client.v1.video_to_video.create(
|
|
45
|
+
assets={"video_file_path": "video/id/1234.mp4", "video_source": "file"},
|
|
46
|
+
end_seconds=15,
|
|
47
|
+
height=960,
|
|
48
|
+
start_seconds=0,
|
|
49
|
+
style={
|
|
50
|
+
"art_style": "3D Render",
|
|
51
|
+
"model": "Absolute Reality",
|
|
52
|
+
"prompt": None,
|
|
53
|
+
"prompt_type": "append_default",
|
|
54
|
+
"version": "default",
|
|
55
|
+
},
|
|
56
|
+
width=512,
|
|
57
|
+
fps_resolution="HALF",
|
|
58
|
+
name="Video To Video video",
|
|
59
|
+
)
|
|
60
|
+
```
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
import typing
|
|
2
|
+
import typing_extensions
|
|
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 VideoToVideoClient:
|
|
16
|
+
def __init__(self, *, base_client: SyncBaseClient):
|
|
17
|
+
self._base_client = base_client
|
|
18
|
+
|
|
19
|
+
def create(
|
|
20
|
+
self,
|
|
21
|
+
*,
|
|
22
|
+
assets: params.PostV1VideoToVideoBodyAssets,
|
|
23
|
+
end_seconds: float,
|
|
24
|
+
height: int,
|
|
25
|
+
start_seconds: float,
|
|
26
|
+
style: params.PostV1VideoToVideoBodyStyle,
|
|
27
|
+
width: int,
|
|
28
|
+
fps_resolution: typing.Union[
|
|
29
|
+
typing.Optional[typing_extensions.Literal["FULL", "HALF"]],
|
|
30
|
+
type_utils.NotGiven,
|
|
31
|
+
] = type_utils.NOT_GIVEN,
|
|
32
|
+
name: typing.Union[
|
|
33
|
+
typing.Optional[str], type_utils.NotGiven
|
|
34
|
+
] = type_utils.NOT_GIVEN,
|
|
35
|
+
request_options: typing.Optional[RequestOptions] = None,
|
|
36
|
+
) -> models.PostV1VideoToVideoResponse:
|
|
37
|
+
"""
|
|
38
|
+
Video-to-Video
|
|
39
|
+
|
|
40
|
+
Create a Video 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.
|
|
41
|
+
|
|
42
|
+
Get more information about this mode at our [product page](/products/video-to-video).
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
POST /v1/video-to-video
|
|
46
|
+
|
|
47
|
+
Args:
|
|
48
|
+
fps_resolution: Determines whether the resulting video will have the same frame per second as the original video, or half.
|
|
49
|
+
* `FULL` - the result video will have the same FPS as the input video
|
|
50
|
+
* `HALF` - the result video will have half the FPS as the input video
|
|
51
|
+
name: The name of video
|
|
52
|
+
assets: Provide the assets for video-to-video. For video, The `video_source` field determines whether `video_file_path` or `youtube_url` field is used
|
|
53
|
+
end_seconds: The end time of the input video in seconds
|
|
54
|
+
height: The height of the final output video. Must be divisible by 64. The maximum height depends on your subscription. Please refer to our [pricing page](https://magichour.ai/pricing) for more details
|
|
55
|
+
start_seconds: The start time of the input video in seconds
|
|
56
|
+
style: PostV1VideoToVideoBodyStyle
|
|
57
|
+
width: The width of the final output video. Must be divisible by 64. The maximum width depends on your subscription. Please refer to our [pricing page](https://magichour.ai/pricing) for more details
|
|
58
|
+
request_options: Additional options to customize the HTTP request
|
|
59
|
+
|
|
60
|
+
Returns:
|
|
61
|
+
Success
|
|
62
|
+
|
|
63
|
+
Raises:
|
|
64
|
+
ApiError: A custom exception class that provides additional context
|
|
65
|
+
for API errors, including the HTTP status code and response body.
|
|
66
|
+
|
|
67
|
+
Examples:
|
|
68
|
+
```py
|
|
69
|
+
client.v1.video_to_video.create(
|
|
70
|
+
assets={"video_source": "file"},
|
|
71
|
+
end_seconds=15,
|
|
72
|
+
height=960,
|
|
73
|
+
start_seconds=0,
|
|
74
|
+
style={
|
|
75
|
+
"art_style": "3D Render",
|
|
76
|
+
"model": "Absolute Reality",
|
|
77
|
+
"prompt": "string",
|
|
78
|
+
"prompt_type": "append_default",
|
|
79
|
+
"version": "default",
|
|
80
|
+
},
|
|
81
|
+
width=512,
|
|
82
|
+
fps_resolution="HALF",
|
|
83
|
+
name="Video To Video video",
|
|
84
|
+
)
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
"""
|
|
88
|
+
_json = to_encodable(
|
|
89
|
+
item={
|
|
90
|
+
"fps_resolution": fps_resolution,
|
|
91
|
+
"name": name,
|
|
92
|
+
"assets": assets,
|
|
93
|
+
"end_seconds": end_seconds,
|
|
94
|
+
"height": height,
|
|
95
|
+
"start_seconds": start_seconds,
|
|
96
|
+
"style": style,
|
|
97
|
+
"width": width,
|
|
98
|
+
},
|
|
99
|
+
dump_with=params._SerializerPostV1VideoToVideoBody,
|
|
100
|
+
)
|
|
101
|
+
return self._base_client.request(
|
|
102
|
+
method="POST",
|
|
103
|
+
path="/v1/video-to-video",
|
|
104
|
+
auth_names=["bearerAuth"],
|
|
105
|
+
json=_json,
|
|
106
|
+
cast_to=models.PostV1VideoToVideoResponse,
|
|
107
|
+
request_options=request_options or default_request_options(),
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
class AsyncVideoToVideoClient:
|
|
112
|
+
def __init__(self, *, base_client: AsyncBaseClient):
|
|
113
|
+
self._base_client = base_client
|
|
114
|
+
|
|
115
|
+
async def create(
|
|
116
|
+
self,
|
|
117
|
+
*,
|
|
118
|
+
assets: params.PostV1VideoToVideoBodyAssets,
|
|
119
|
+
end_seconds: float,
|
|
120
|
+
height: int,
|
|
121
|
+
start_seconds: float,
|
|
122
|
+
style: params.PostV1VideoToVideoBodyStyle,
|
|
123
|
+
width: int,
|
|
124
|
+
fps_resolution: typing.Union[
|
|
125
|
+
typing.Optional[typing_extensions.Literal["FULL", "HALF"]],
|
|
126
|
+
type_utils.NotGiven,
|
|
127
|
+
] = type_utils.NOT_GIVEN,
|
|
128
|
+
name: typing.Union[
|
|
129
|
+
typing.Optional[str], type_utils.NotGiven
|
|
130
|
+
] = type_utils.NOT_GIVEN,
|
|
131
|
+
request_options: typing.Optional[RequestOptions] = None,
|
|
132
|
+
) -> models.PostV1VideoToVideoResponse:
|
|
133
|
+
"""
|
|
134
|
+
Video-to-Video
|
|
135
|
+
|
|
136
|
+
Create a Video 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.
|
|
137
|
+
|
|
138
|
+
Get more information about this mode at our [product page](/products/video-to-video).
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
POST /v1/video-to-video
|
|
142
|
+
|
|
143
|
+
Args:
|
|
144
|
+
fps_resolution: Determines whether the resulting video will have the same frame per second as the original video, or half.
|
|
145
|
+
* `FULL` - the result video will have the same FPS as the input video
|
|
146
|
+
* `HALF` - the result video will have half the FPS as the input video
|
|
147
|
+
name: The name of video
|
|
148
|
+
assets: Provide the assets for video-to-video. For video, The `video_source` field determines whether `video_file_path` or `youtube_url` field is used
|
|
149
|
+
end_seconds: The end time of the input video in seconds
|
|
150
|
+
height: The height of the final output video. Must be divisible by 64. The maximum height depends on your subscription. Please refer to our [pricing page](https://magichour.ai/pricing) for more details
|
|
151
|
+
start_seconds: The start time of the input video in seconds
|
|
152
|
+
style: PostV1VideoToVideoBodyStyle
|
|
153
|
+
width: The width of the final output video. Must be divisible by 64. The maximum width depends on your subscription. Please refer to our [pricing page](https://magichour.ai/pricing) for more details
|
|
154
|
+
request_options: Additional options to customize the HTTP request
|
|
155
|
+
|
|
156
|
+
Returns:
|
|
157
|
+
Success
|
|
158
|
+
|
|
159
|
+
Raises:
|
|
160
|
+
ApiError: A custom exception class that provides additional context
|
|
161
|
+
for API errors, including the HTTP status code and response body.
|
|
162
|
+
|
|
163
|
+
Examples:
|
|
164
|
+
```py
|
|
165
|
+
await client.v1.video_to_video.create(
|
|
166
|
+
assets={"video_source": "file"},
|
|
167
|
+
end_seconds=15,
|
|
168
|
+
height=960,
|
|
169
|
+
start_seconds=0,
|
|
170
|
+
style={
|
|
171
|
+
"art_style": "3D Render",
|
|
172
|
+
"model": "Absolute Reality",
|
|
173
|
+
"prompt": "string",
|
|
174
|
+
"prompt_type": "append_default",
|
|
175
|
+
"version": "default",
|
|
176
|
+
},
|
|
177
|
+
width=512,
|
|
178
|
+
fps_resolution="HALF",
|
|
179
|
+
name="Video To Video video",
|
|
180
|
+
)
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
"""
|
|
184
|
+
_json = to_encodable(
|
|
185
|
+
item={
|
|
186
|
+
"fps_resolution": fps_resolution,
|
|
187
|
+
"name": name,
|
|
188
|
+
"assets": assets,
|
|
189
|
+
"end_seconds": end_seconds,
|
|
190
|
+
"height": height,
|
|
191
|
+
"start_seconds": start_seconds,
|
|
192
|
+
"style": style,
|
|
193
|
+
"width": width,
|
|
194
|
+
},
|
|
195
|
+
dump_with=params._SerializerPostV1VideoToVideoBody,
|
|
196
|
+
)
|
|
197
|
+
return await self._base_client.request(
|
|
198
|
+
method="POST",
|
|
199
|
+
path="/v1/video-to-video",
|
|
200
|
+
auth_names=["bearerAuth"],
|
|
201
|
+
json=_json,
|
|
202
|
+
cast_to=models.PostV1VideoToVideoResponse,
|
|
203
|
+
request_options=request_options or default_request_options(),
|
|
204
|
+
)
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
from .get_v1_image_projects_id_response_downloads_item import (
|
|
2
|
+
GetV1ImageProjectsIdResponseDownloadsItem,
|
|
3
|
+
)
|
|
4
|
+
from .get_v1_image_projects_id_response_error import GetV1ImageProjectsIdResponseError
|
|
5
|
+
from .get_v1_video_projects_id_response_download import (
|
|
6
|
+
GetV1VideoProjectsIdResponseDownload,
|
|
7
|
+
)
|
|
8
|
+
from .get_v1_video_projects_id_response_downloads_item import (
|
|
9
|
+
GetV1VideoProjectsIdResponseDownloadsItem,
|
|
10
|
+
)
|
|
11
|
+
from .get_v1_video_projects_id_response_error import GetV1VideoProjectsIdResponseError
|
|
12
|
+
from .post_v1_ai_clothes_changer_response import PostV1AiClothesChangerResponse
|
|
13
|
+
from .post_v1_ai_headshot_generator_response import PostV1AiHeadshotGeneratorResponse
|
|
14
|
+
from .post_v1_ai_image_generator_response import PostV1AiImageGeneratorResponse
|
|
15
|
+
from .post_v1_ai_image_upscaler_response import PostV1AiImageUpscalerResponse
|
|
16
|
+
from .post_v1_ai_photo_editor_response import PostV1AiPhotoEditorResponse
|
|
17
|
+
from .post_v1_ai_qr_code_generator_response import PostV1AiQrCodeGeneratorResponse
|
|
18
|
+
from .post_v1_animation_response import PostV1AnimationResponse
|
|
19
|
+
from .post_v1_face_swap_response import PostV1FaceSwapResponse
|
|
20
|
+
from .post_v1_face_swap_photo_response import PostV1FaceSwapPhotoResponse
|
|
21
|
+
from .post_v1_files_upload_urls_response_items_item import (
|
|
22
|
+
PostV1FilesUploadUrlsResponseItemsItem,
|
|
23
|
+
)
|
|
24
|
+
from .post_v1_image_background_remover_response import (
|
|
25
|
+
PostV1ImageBackgroundRemoverResponse,
|
|
26
|
+
)
|
|
27
|
+
from .post_v1_image_to_video_response import PostV1ImageToVideoResponse
|
|
28
|
+
from .post_v1_lip_sync_response import PostV1LipSyncResponse
|
|
29
|
+
from .post_v1_text_to_video_response import PostV1TextToVideoResponse
|
|
30
|
+
from .post_v1_video_to_video_response import PostV1VideoToVideoResponse
|
|
31
|
+
from .get_v1_image_projects_id_response import GetV1ImageProjectsIdResponse
|
|
32
|
+
from .get_v1_video_projects_id_response import GetV1VideoProjectsIdResponse
|
|
33
|
+
from .post_v1_files_upload_urls_response import PostV1FilesUploadUrlsResponse
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
__all__ = [
|
|
37
|
+
"GetV1ImageProjectsIdResponse",
|
|
38
|
+
"GetV1ImageProjectsIdResponseDownloadsItem",
|
|
39
|
+
"GetV1ImageProjectsIdResponseError",
|
|
40
|
+
"GetV1VideoProjectsIdResponse",
|
|
41
|
+
"GetV1VideoProjectsIdResponseDownload",
|
|
42
|
+
"GetV1VideoProjectsIdResponseDownloadsItem",
|
|
43
|
+
"GetV1VideoProjectsIdResponseError",
|
|
44
|
+
"PostV1AiClothesChangerResponse",
|
|
45
|
+
"PostV1AiHeadshotGeneratorResponse",
|
|
46
|
+
"PostV1AiImageGeneratorResponse",
|
|
47
|
+
"PostV1AiImageUpscalerResponse",
|
|
48
|
+
"PostV1AiPhotoEditorResponse",
|
|
49
|
+
"PostV1AiQrCodeGeneratorResponse",
|
|
50
|
+
"PostV1AnimationResponse",
|
|
51
|
+
"PostV1FaceSwapPhotoResponse",
|
|
52
|
+
"PostV1FaceSwapResponse",
|
|
53
|
+
"PostV1FilesUploadUrlsResponse",
|
|
54
|
+
"PostV1FilesUploadUrlsResponseItemsItem",
|
|
55
|
+
"PostV1ImageBackgroundRemoverResponse",
|
|
56
|
+
"PostV1ImageToVideoResponse",
|
|
57
|
+
"PostV1LipSyncResponse",
|
|
58
|
+
"PostV1TextToVideoResponse",
|
|
59
|
+
"PostV1VideoToVideoResponse",
|
|
60
|
+
]
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import typing
|
|
2
|
+
import typing_extensions
|
|
3
|
+
import pydantic
|
|
4
|
+
|
|
5
|
+
from .get_v1_image_projects_id_response_downloads_item import (
|
|
6
|
+
GetV1ImageProjectsIdResponseDownloadsItem,
|
|
7
|
+
)
|
|
8
|
+
from .get_v1_image_projects_id_response_error import GetV1ImageProjectsIdResponseError
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class GetV1ImageProjectsIdResponse(pydantic.BaseModel):
|
|
12
|
+
"""
|
|
13
|
+
Success
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
model_config = pydantic.ConfigDict(
|
|
17
|
+
arbitrary_types_allowed=True,
|
|
18
|
+
populate_by_name=True,
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
created_at: str = pydantic.Field(
|
|
22
|
+
alias="created_at",
|
|
23
|
+
)
|
|
24
|
+
downloads: typing.List[GetV1ImageProjectsIdResponseDownloadsItem] = pydantic.Field(
|
|
25
|
+
alias="downloads",
|
|
26
|
+
)
|
|
27
|
+
enabled: bool = pydantic.Field(
|
|
28
|
+
alias="enabled",
|
|
29
|
+
)
|
|
30
|
+
"""
|
|
31
|
+
Indicates whether the resource is deleted
|
|
32
|
+
"""
|
|
33
|
+
error: typing.Optional[GetV1ImageProjectsIdResponseError] = pydantic.Field(
|
|
34
|
+
alias="error",
|
|
35
|
+
)
|
|
36
|
+
"""
|
|
37
|
+
In the case of an error, this object will contain the error encountered during video render
|
|
38
|
+
"""
|
|
39
|
+
id: str = pydantic.Field(
|
|
40
|
+
alias="id",
|
|
41
|
+
)
|
|
42
|
+
"""
|
|
43
|
+
Unique ID of the image. This value can be used in the [get image project API](/api/tag/image-projects/get/v1/image-projects/{id}) to fetch additional details such as status
|
|
44
|
+
"""
|
|
45
|
+
image_count: int = pydantic.Field(
|
|
46
|
+
alias="image_count",
|
|
47
|
+
)
|
|
48
|
+
"""
|
|
49
|
+
Number of images generated
|
|
50
|
+
"""
|
|
51
|
+
name: typing.Optional[str] = pydantic.Field(
|
|
52
|
+
alias="name",
|
|
53
|
+
)
|
|
54
|
+
"""
|
|
55
|
+
The name of the image.
|
|
56
|
+
"""
|
|
57
|
+
status: typing_extensions.Literal[
|
|
58
|
+
"canceled", "complete", "draft", "error", "queued", "rendering"
|
|
59
|
+
] = pydantic.Field(
|
|
60
|
+
alias="status",
|
|
61
|
+
)
|
|
62
|
+
"""
|
|
63
|
+
The status of the image.
|
|
64
|
+
"""
|
|
65
|
+
total_frame_cost: int = pydantic.Field(
|
|
66
|
+
alias="total_frame_cost",
|
|
67
|
+
)
|
|
68
|
+
"""
|
|
69
|
+
The amount of frames used to generate the image.
|
|
70
|
+
"""
|
|
71
|
+
type_field: typing_extensions.Literal[
|
|
72
|
+
"AI_HEADSHOT",
|
|
73
|
+
"AI_IMAGE",
|
|
74
|
+
"BACKGROUND_REMOVER",
|
|
75
|
+
"CLOTHES_CHANGER",
|
|
76
|
+
"FACE_SWAP",
|
|
77
|
+
"IMAGE_UPSCALER",
|
|
78
|
+
"PHOTO_EDITOR",
|
|
79
|
+
"QR_CODE",
|
|
80
|
+
] = pydantic.Field(
|
|
81
|
+
alias="type",
|
|
82
|
+
)
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import pydantic
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class GetV1ImageProjectsIdResponseDownloadsItem(pydantic.BaseModel):
|
|
5
|
+
"""
|
|
6
|
+
The download url and expiration date of the image project
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
model_config = pydantic.ConfigDict(
|
|
10
|
+
arbitrary_types_allowed=True,
|
|
11
|
+
populate_by_name=True,
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
expires_at: str = pydantic.Field(
|
|
15
|
+
alias="expires_at",
|
|
16
|
+
)
|
|
17
|
+
url: str = pydantic.Field(
|
|
18
|
+
alias="url",
|
|
19
|
+
)
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import pydantic
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class GetV1ImageProjectsIdResponseError(pydantic.BaseModel):
|
|
5
|
+
"""
|
|
6
|
+
In the case of an error, this object will contain the error encountered during video render
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
model_config = pydantic.ConfigDict(
|
|
10
|
+
arbitrary_types_allowed=True,
|
|
11
|
+
populate_by_name=True,
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
code_field: str = pydantic.Field(
|
|
15
|
+
alias="code",
|
|
16
|
+
)
|
|
17
|
+
"""
|
|
18
|
+
An error code to indicate why a failure happened.
|
|
19
|
+
"""
|
|
20
|
+
message: str = pydantic.Field(
|
|
21
|
+
alias="message",
|
|
22
|
+
)
|
|
23
|
+
"""
|
|
24
|
+
Details on the reason why a failure happened.
|
|
25
|
+
"""
|