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.

Files changed (131) hide show
  1. magic_hour/__init__.py +6 -0
  2. magic_hour/client.py +61 -0
  3. magic_hour/core/__init__.py +53 -0
  4. magic_hour/core/api_error.py +48 -0
  5. magic_hour/core/auth.py +314 -0
  6. magic_hour/core/base_client.py +600 -0
  7. magic_hour/core/binary_response.py +23 -0
  8. magic_hour/core/request.py +158 -0
  9. magic_hour/core/response.py +293 -0
  10. magic_hour/core/type_utils.py +28 -0
  11. magic_hour/core/utils.py +38 -0
  12. magic_hour/environment.py +6 -0
  13. magic_hour/resources/v1/__init__.py +4 -0
  14. magic_hour/resources/v1/ai_clothes_changer/README.md +41 -0
  15. magic_hour/resources/v1/ai_clothes_changer/__init__.py +4 -0
  16. magic_hour/resources/v1/ai_clothes_changer/client.py +129 -0
  17. magic_hour/resources/v1/ai_headshot_generator/README.md +31 -0
  18. magic_hour/resources/v1/ai_headshot_generator/__init__.py +4 -0
  19. magic_hour/resources/v1/ai_headshot_generator/client.py +119 -0
  20. magic_hour/resources/v1/ai_image_generator/README.md +37 -0
  21. magic_hour/resources/v1/ai_image_generator/__init__.py +4 -0
  22. magic_hour/resources/v1/ai_image_generator/client.py +144 -0
  23. magic_hour/resources/v1/ai_image_upscaler/README.md +37 -0
  24. magic_hour/resources/v1/ai_image_upscaler/__init__.py +4 -0
  25. magic_hour/resources/v1/ai_image_upscaler/client.py +143 -0
  26. magic_hour/resources/v1/ai_photo_editor/README.md +53 -0
  27. magic_hour/resources/v1/ai_photo_editor/__init__.py +4 -0
  28. magic_hour/resources/v1/ai_photo_editor/client.py +167 -0
  29. magic_hour/resources/v1/ai_qr_code_generator/README.md +35 -0
  30. magic_hour/resources/v1/ai_qr_code_generator/__init__.py +4 -0
  31. magic_hour/resources/v1/ai_qr_code_generator/client.py +127 -0
  32. magic_hour/resources/v1/animation/README.md +63 -0
  33. magic_hour/resources/v1/animation/__init__.py +4 -0
  34. magic_hour/resources/v1/animation/client.py +179 -0
  35. magic_hour/resources/v1/client.py +153 -0
  36. magic_hour/resources/v1/face_swap/README.md +52 -0
  37. magic_hour/resources/v1/face_swap/__init__.py +4 -0
  38. magic_hour/resources/v1/face_swap/client.py +165 -0
  39. magic_hour/resources/v1/face_swap_photo/README.md +39 -0
  40. magic_hour/resources/v1/face_swap_photo/__init__.py +4 -0
  41. magic_hour/resources/v1/face_swap_photo/client.py +127 -0
  42. magic_hour/resources/v1/files/__init__.py +4 -0
  43. magic_hour/resources/v1/files/client.py +19 -0
  44. magic_hour/resources/v1/files/upload_urls/README.md +56 -0
  45. magic_hour/resources/v1/files/upload_urls/__init__.py +4 -0
  46. magic_hour/resources/v1/files/upload_urls/client.py +142 -0
  47. magic_hour/resources/v1/image_background_remover/README.md +31 -0
  48. magic_hour/resources/v1/image_background_remover/__init__.py +4 -0
  49. magic_hour/resources/v1/image_background_remover/client.py +121 -0
  50. magic_hour/resources/v1/image_projects/README.md +63 -0
  51. magic_hour/resources/v1/image_projects/__init__.py +4 -0
  52. magic_hour/resources/v1/image_projects/client.py +177 -0
  53. magic_hour/resources/v1/image_to_video/README.md +44 -0
  54. magic_hour/resources/v1/image_to_video/__init__.py +4 -0
  55. magic_hour/resources/v1/image_to_video/client.py +165 -0
  56. magic_hour/resources/v1/lip_sync/README.md +54 -0
  57. magic_hour/resources/v1/lip_sync/__init__.py +4 -0
  58. magic_hour/resources/v1/lip_sync/client.py +177 -0
  59. magic_hour/resources/v1/text_to_video/README.md +40 -0
  60. magic_hour/resources/v1/text_to_video/__init__.py +4 -0
  61. magic_hour/resources/v1/text_to_video/client.py +150 -0
  62. magic_hour/resources/v1/video_projects/README.md +63 -0
  63. magic_hour/resources/v1/video_projects/__init__.py +4 -0
  64. magic_hour/resources/v1/video_projects/client.py +177 -0
  65. magic_hour/resources/v1/video_to_video/README.md +60 -0
  66. magic_hour/resources/v1/video_to_video/__init__.py +4 -0
  67. magic_hour/resources/v1/video_to_video/client.py +204 -0
  68. magic_hour/types/models/__init__.py +60 -0
  69. magic_hour/types/models/get_v1_image_projects_id_response.py +82 -0
  70. magic_hour/types/models/get_v1_image_projects_id_response_downloads_item.py +19 -0
  71. magic_hour/types/models/get_v1_image_projects_id_response_error.py +25 -0
  72. magic_hour/types/models/get_v1_video_projects_id_response.py +114 -0
  73. magic_hour/types/models/get_v1_video_projects_id_response_download.py +19 -0
  74. magic_hour/types/models/get_v1_video_projects_id_response_downloads_item.py +19 -0
  75. magic_hour/types/models/get_v1_video_projects_id_response_error.py +25 -0
  76. magic_hour/types/models/post_v1_ai_clothes_changer_response.py +25 -0
  77. magic_hour/types/models/post_v1_ai_headshot_generator_response.py +25 -0
  78. magic_hour/types/models/post_v1_ai_image_generator_response.py +25 -0
  79. magic_hour/types/models/post_v1_ai_image_upscaler_response.py +25 -0
  80. magic_hour/types/models/post_v1_ai_photo_editor_response.py +25 -0
  81. magic_hour/types/models/post_v1_ai_qr_code_generator_response.py +25 -0
  82. magic_hour/types/models/post_v1_animation_response.py +25 -0
  83. magic_hour/types/models/post_v1_face_swap_photo_response.py +25 -0
  84. magic_hour/types/models/post_v1_face_swap_response.py +25 -0
  85. magic_hour/types/models/post_v1_files_upload_urls_response.py +21 -0
  86. magic_hour/types/models/post_v1_files_upload_urls_response_items_item.py +31 -0
  87. magic_hour/types/models/post_v1_image_background_remover_response.py +25 -0
  88. magic_hour/types/models/post_v1_image_to_video_response.py +25 -0
  89. magic_hour/types/models/post_v1_lip_sync_response.py +25 -0
  90. magic_hour/types/models/post_v1_text_to_video_response.py +25 -0
  91. magic_hour/types/models/post_v1_video_to_video_response.py +25 -0
  92. magic_hour/types/params/__init__.py +205 -0
  93. magic_hour/types/params/post_v1_ai_clothes_changer_body.py +40 -0
  94. magic_hour/types/params/post_v1_ai_clothes_changer_body_assets.py +45 -0
  95. magic_hour/types/params/post_v1_ai_headshot_generator_body.py +40 -0
  96. magic_hour/types/params/post_v1_ai_headshot_generator_body_assets.py +28 -0
  97. magic_hour/types/params/post_v1_ai_image_generator_body.py +54 -0
  98. magic_hour/types/params/post_v1_ai_image_generator_body_style.py +28 -0
  99. magic_hour/types/params/post_v1_ai_image_upscaler_body.py +54 -0
  100. magic_hour/types/params/post_v1_ai_image_upscaler_body_assets.py +28 -0
  101. magic_hour/types/params/post_v1_ai_image_upscaler_body_style.py +36 -0
  102. magic_hour/types/params/post_v1_ai_photo_editor_body.py +63 -0
  103. magic_hour/types/params/post_v1_ai_photo_editor_body_assets.py +28 -0
  104. magic_hour/types/params/post_v1_ai_photo_editor_body_style.py +67 -0
  105. magic_hour/types/params/post_v1_ai_qr_code_generator_body.py +45 -0
  106. magic_hour/types/params/post_v1_ai_qr_code_generator_body_style.py +28 -0
  107. magic_hour/types/params/post_v1_animation_body.py +84 -0
  108. magic_hour/types/params/post_v1_animation_body_assets.py +55 -0
  109. magic_hour/types/params/post_v1_animation_body_style.py +279 -0
  110. magic_hour/types/params/post_v1_face_swap_body.py +72 -0
  111. magic_hour/types/params/post_v1_face_swap_body_assets.py +52 -0
  112. magic_hour/types/params/post_v1_face_swap_photo_body.py +40 -0
  113. magic_hour/types/params/post_v1_face_swap_photo_body_assets.py +36 -0
  114. magic_hour/types/params/post_v1_files_upload_urls_body.py +31 -0
  115. magic_hour/types/params/post_v1_files_upload_urls_body_items_item.py +38 -0
  116. magic_hour/types/params/post_v1_image_background_remover_body.py +40 -0
  117. magic_hour/types/params/post_v1_image_background_remover_body_assets.py +28 -0
  118. magic_hour/types/params/post_v1_image_to_video_body.py +73 -0
  119. magic_hour/types/params/post_v1_image_to_video_body_assets.py +28 -0
  120. magic_hour/types/params/post_v1_image_to_video_body_style.py +29 -0
  121. magic_hour/types/params/post_v1_lip_sync_body.py +80 -0
  122. magic_hour/types/params/post_v1_lip_sync_body_assets.py +52 -0
  123. magic_hour/types/params/post_v1_text_to_video_body.py +57 -0
  124. magic_hour/types/params/post_v1_text_to_video_body_style.py +28 -0
  125. magic_hour/types/params/post_v1_video_to_video_body.py +93 -0
  126. magic_hour/types/params/post_v1_video_to_video_body_assets.py +44 -0
  127. magic_hour/types/params/post_v1_video_to_video_body_style.py +199 -0
  128. magic_hour-0.8.0.dist-info/LICENSE +21 -0
  129. magic_hour-0.8.0.dist-info/METADATA +138 -0
  130. magic_hour-0.8.0.dist-info/RECORD +131 -0
  131. 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,4 @@
1
+ from .client import AsyncLipSyncClient, LipSyncClient
2
+
3
+
4
+ __all__ = ["AsyncLipSyncClient", "LipSyncClient"]
@@ -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,4 @@
1
+ from .client import AsyncTextToVideoClient, TextToVideoClient
2
+
3
+
4
+ __all__ = ["AsyncTextToVideoClient", "TextToVideoClient"]
@@ -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
+ ```
@@ -0,0 +1,4 @@
1
+ from .client import AsyncVideoProjectsClient, VideoProjectsClient
2
+
3
+
4
+ __all__ = ["AsyncVideoProjectsClient", "VideoProjectsClient"]