magic_hour 0.35.0__py3-none-any.whl → 0.36.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 (94) hide show
  1. magic_hour/README.md +35 -0
  2. magic_hour/core/base_client.py +6 -5
  3. magic_hour/core/query.py +12 -6
  4. magic_hour/core/request.py +3 -3
  5. magic_hour/core/response.py +18 -14
  6. magic_hour/core/utils.py +3 -3
  7. magic_hour/environment.py +1 -1
  8. magic_hour/helpers/__init__.py +3 -0
  9. magic_hour/helpers/download.py +75 -0
  10. magic_hour/resources/v1/README.md +33 -0
  11. magic_hour/resources/v1/ai_clothes_changer/README.md +73 -0
  12. magic_hour/resources/v1/ai_clothes_changer/client.py +146 -0
  13. magic_hour/resources/v1/ai_face_editor/README.md +110 -0
  14. magic_hour/resources/v1/ai_face_editor/client.py +168 -0
  15. magic_hour/resources/v1/ai_gif_generator/README.md +59 -0
  16. magic_hour/resources/v1/ai_gif_generator/client.py +119 -0
  17. magic_hour/resources/v1/ai_headshot_generator/README.md +60 -0
  18. magic_hour/resources/v1/ai_headshot_generator/client.py +140 -0
  19. magic_hour/resources/v1/ai_image_editor/README.md +64 -0
  20. magic_hour/resources/v1/ai_image_editor/client.py +136 -0
  21. magic_hour/resources/v1/ai_image_generator/README.md +66 -0
  22. magic_hour/resources/v1/ai_image_generator/client.py +139 -0
  23. magic_hour/resources/v1/ai_image_upscaler/README.md +67 -0
  24. magic_hour/resources/v1/ai_image_upscaler/client.py +150 -0
  25. magic_hour/resources/v1/ai_meme_generator/README.md +71 -0
  26. magic_hour/resources/v1/ai_meme_generator/client.py +127 -0
  27. magic_hour/resources/v1/ai_photo_editor/README.md +98 -7
  28. magic_hour/resources/v1/ai_photo_editor/client.py +174 -0
  29. magic_hour/resources/v1/ai_qr_code_generator/README.md +63 -0
  30. magic_hour/resources/v1/ai_qr_code_generator/client.py +123 -0
  31. magic_hour/resources/v1/ai_talking_photo/README.md +74 -0
  32. magic_hour/resources/v1/ai_talking_photo/client.py +170 -0
  33. magic_hour/resources/v1/animation/README.md +100 -0
  34. magic_hour/resources/v1/animation/client.py +218 -0
  35. magic_hour/resources/v1/auto_subtitle_generator/README.md +69 -0
  36. magic_hour/resources/v1/auto_subtitle_generator/client.py +178 -0
  37. magic_hour/resources/v1/face_detection/README.md +59 -0
  38. magic_hour/resources/v1/face_detection/__init__.py +10 -2
  39. magic_hour/resources/v1/face_detection/client.py +179 -0
  40. magic_hour/resources/v1/face_swap/README.md +105 -8
  41. magic_hour/resources/v1/face_swap/client.py +242 -0
  42. magic_hour/resources/v1/face_swap_photo/README.md +84 -0
  43. magic_hour/resources/v1/face_swap_photo/client.py +172 -0
  44. magic_hour/resources/v1/files/README.md +6 -0
  45. magic_hour/resources/v1/files/client.py +350 -0
  46. magic_hour/resources/v1/files/client_test.py +414 -0
  47. magic_hour/resources/v1/files/upload_urls/README.md +8 -0
  48. magic_hour/resources/v1/image_background_remover/README.md +68 -0
  49. magic_hour/resources/v1/image_background_remover/client.py +130 -0
  50. magic_hour/resources/v1/image_projects/README.md +8 -0
  51. magic_hour/resources/v1/image_projects/__init__.py +10 -2
  52. magic_hour/resources/v1/image_projects/client.py +138 -0
  53. magic_hour/resources/v1/image_projects/client_test.py +527 -0
  54. magic_hour/resources/v1/image_to_video/README.md +77 -9
  55. magic_hour/resources/v1/image_to_video/client.py +186 -0
  56. magic_hour/resources/v1/lip_sync/README.md +87 -9
  57. magic_hour/resources/v1/lip_sync/client.py +210 -0
  58. magic_hour/resources/v1/photo_colorizer/README.md +59 -0
  59. magic_hour/resources/v1/photo_colorizer/client.py +130 -0
  60. magic_hour/resources/v1/text_to_video/README.md +68 -0
  61. magic_hour/resources/v1/text_to_video/client.py +151 -0
  62. magic_hour/resources/v1/video_projects/README.md +8 -0
  63. magic_hour/resources/v1/video_projects/__init__.py +10 -2
  64. magic_hour/resources/v1/video_projects/client.py +137 -0
  65. magic_hour/resources/v1/video_projects/client_test.py +527 -0
  66. magic_hour/resources/v1/video_to_video/README.md +98 -10
  67. magic_hour/resources/v1/video_to_video/client.py +222 -0
  68. magic_hour/types/params/__init__.py +58 -0
  69. magic_hour/types/params/v1_ai_clothes_changer_generate_body_assets.py +33 -0
  70. magic_hour/types/params/v1_ai_face_editor_generate_body_assets.py +17 -0
  71. magic_hour/types/params/v1_ai_headshot_generator_generate_body_assets.py +17 -0
  72. magic_hour/types/params/v1_ai_image_editor_generate_body_assets.py +17 -0
  73. magic_hour/types/params/v1_ai_image_upscaler_generate_body_assets.py +17 -0
  74. magic_hour/types/params/v1_ai_photo_editor_generate_body_assets.py +17 -0
  75. magic_hour/types/params/v1_ai_talking_photo_generate_body_assets.py +26 -0
  76. magic_hour/types/params/v1_animation_generate_body_assets.py +39 -0
  77. magic_hour/types/params/v1_auto_subtitle_generator_generate_body_assets.py +17 -0
  78. magic_hour/types/params/v1_face_detection_generate_body_assets.py +17 -0
  79. magic_hour/types/params/v1_face_swap_create_body.py +12 -0
  80. magic_hour/types/params/v1_face_swap_create_body_style.py +33 -0
  81. magic_hour/types/params/v1_face_swap_generate_body_assets.py +56 -0
  82. magic_hour/types/params/v1_face_swap_generate_body_assets_face_mappings_item.py +25 -0
  83. magic_hour/types/params/v1_face_swap_photo_generate_body_assets.py +47 -0
  84. magic_hour/types/params/v1_face_swap_photo_generate_body_assets_face_mappings_item.py +25 -0
  85. magic_hour/types/params/v1_image_background_remover_generate_body_assets.py +27 -0
  86. magic_hour/types/params/v1_image_to_video_generate_body_assets.py +17 -0
  87. magic_hour/types/params/v1_lip_sync_generate_body_assets.py +36 -0
  88. magic_hour/types/params/v1_photo_colorizer_generate_body_assets.py +17 -0
  89. magic_hour/types/params/v1_video_to_video_generate_body_assets.py +27 -0
  90. magic_hour-0.36.0.dist-info/METADATA +303 -0
  91. {magic_hour-0.35.0.dist-info → magic_hour-0.36.0.dist-info}/RECORD +93 -65
  92. magic_hour-0.35.0.dist-info/METADATA +0 -166
  93. {magic_hour-0.35.0.dist-info → magic_hour-0.36.0.dist-info}/LICENSE +0 -0
  94. {magic_hour-0.35.0.dist-info → magic_hour-0.36.0.dist-info}/WHEEL +0 -0
@@ -1,3 +1,96 @@
1
+ # v1_ai_face_editor
2
+
3
+ ## Module Functions
4
+
5
+ <!-- CUSTOM DOCS START -->
6
+
7
+ ### Ai Face Editor Generate Workflow <a name="generate"></a>
8
+
9
+ The workflow performs the following action
10
+
11
+ 1. upload local assets to Magic Hour storage. So you can pass in a local path instead of having to upload files yourself
12
+ 2. trigger a generation
13
+ 3. poll for a completion status. This is configurable
14
+ 4. if success, download the output to local directory
15
+
16
+ > [!TIP]
17
+ > This is the recommended way to use the SDK unless you have specific needs where it is necessary to split up the actions.
18
+
19
+ #### Parameters
20
+
21
+ In Additional to the parameters listed in the `.create` section below, `.generate` introduces 3 new parameters:
22
+
23
+ - `wait_for_completion` (bool, default True): Whether to wait for the project to complete.
24
+ - `download_outputs` (bool, default True): Whether to download the generated files
25
+ - `download_directory` (str, optional): Directory to save downloaded files (defaults to current directory)
26
+
27
+ #### Synchronous Client
28
+
29
+ ```python
30
+ from magic_hour import Client
31
+ from os import getenv
32
+
33
+ client = Client(token=getenv("API_TOKEN"))
34
+ res = client.v1.ai_face_editor.generate(
35
+ assets={"image_file_path": "/path/to/1234.png"},
36
+ style={
37
+ "enhance_face": False,
38
+ "eye_gaze_horizontal": 0.0,
39
+ "eye_gaze_vertical": 0.0,
40
+ "eye_open_ratio": 0.0,
41
+ "eyebrow_direction": 0.0,
42
+ "head_pitch": 0.0,
43
+ "head_roll": 0.0,
44
+ "head_yaw": 0.0,
45
+ "lip_open_ratio": 0.0,
46
+ "mouth_grim": 0.0,
47
+ "mouth_position_horizontal": 0.0,
48
+ "mouth_position_vertical": 0.0,
49
+ "mouth_pout": 0.0,
50
+ "mouth_purse": 0.0,
51
+ "mouth_smile": 0.0,
52
+ },
53
+ name="Face Editor image",
54
+ wait_for_completion=True,
55
+ download_outputs=True,
56
+ download_directory="outputs"
57
+ )
58
+ ```
59
+
60
+ #### Asynchronous Client
61
+
62
+ ```python
63
+ from magic_hour import AsyncClient
64
+ from os import getenv
65
+
66
+ client = AsyncClient(token=getenv("API_TOKEN"))
67
+ res = await client.v1.ai_face_editor.generate(
68
+ assets={"image_file_path": "/path/to/1234.png"},
69
+ style={
70
+ "enhance_face": False,
71
+ "eye_gaze_horizontal": 0.0,
72
+ "eye_gaze_vertical": 0.0,
73
+ "eye_open_ratio": 0.0,
74
+ "eyebrow_direction": 0.0,
75
+ "head_pitch": 0.0,
76
+ "head_roll": 0.0,
77
+ "head_yaw": 0.0,
78
+ "lip_open_ratio": 0.0,
79
+ "mouth_grim": 0.0,
80
+ "mouth_position_horizontal": 0.0,
81
+ "mouth_position_vertical": 0.0,
82
+ "mouth_pout": 0.0,
83
+ "mouth_purse": 0.0,
84
+ "mouth_smile": 0.0,
85
+ },
86
+ name="Face Editor image",
87
+ wait_for_completion=True,
88
+ download_outputs=True,
89
+ download_directory="outputs"
90
+ )
91
+ ```
92
+
93
+ <!-- CUSTOM DOCS END -->
1
94
 
2
95
  ### AI Face Editor <a name="create"></a>
3
96
 
@@ -10,7 +103,23 @@ Edit facial features of an image using AI. Each edit costs 1 frame. The height/w
10
103
  | Parameter | Required | Description | Example |
11
104
  |-----------|:--------:|-------------|--------|
12
105
  | `assets` | ✓ | Provide the assets for face editor | `{"image_file_path": "api-assets/id/1234.png"}` |
106
+ | `└─ image_file_path` | ✓ | This is the image whose face will be edited. This value is either - a direct URL to the video file - `file_path` field from the response of the [upload urls API](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls). Please refer to the [Input File documentation](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls#input-file) to learn more. | `"api-assets/id/1234.png"` |
13
107
  | `style` | ✓ | Face editing parameters | `{"enhance_face": False, "eye_gaze_horizontal": 0.0, "eye_gaze_vertical": 0.0, "eye_open_ratio": 0.0, "eyebrow_direction": 0.0, "head_pitch": 0.0, "head_roll": 0.0, "head_yaw": 0.0, "lip_open_ratio": 0.0, "mouth_grim": 0.0, "mouth_position_horizontal": 0.0, "mouth_position_vertical": 0.0, "mouth_pout": 0.0, "mouth_purse": 0.0, "mouth_smile": 0.0}` |
108
+ | `└─ enhance_face` | ✗ | Enhance face features | `False` |
109
+ | `└─ eye_gaze_horizontal` | ✗ | Horizontal eye gaze (-100 to 100), in increments of 5 | `0.0` |
110
+ | `└─ eye_gaze_vertical` | ✗ | Vertical eye gaze (-100 to 100), in increments of 5 | `0.0` |
111
+ | `└─ eye_open_ratio` | ✗ | Eye open ratio (-100 to 100), in increments of 5 | `0.0` |
112
+ | `└─ eyebrow_direction` | ✗ | Eyebrow direction (-100 to 100), in increments of 5 | `0.0` |
113
+ | `└─ head_pitch` | ✗ | Head pitch (-100 to 100), in increments of 5 | `0.0` |
114
+ | `└─ head_roll` | ✗ | Head roll (-100 to 100), in increments of 5 | `0.0` |
115
+ | `└─ head_yaw` | ✗ | Head yaw (-100 to 100), in increments of 5 | `0.0` |
116
+ | `└─ lip_open_ratio` | ✗ | Lip open ratio (-100 to 100), in increments of 5 | `0.0` |
117
+ | `└─ mouth_grim` | ✗ | Mouth grim (-100 to 100), in increments of 5 | `0.0` |
118
+ | `└─ mouth_position_horizontal` | ✗ | Horizontal mouth position (-100 to 100), in increments of 5 | `0.0` |
119
+ | `└─ mouth_position_vertical` | ✗ | Vertical mouth position (-100 to 100), in increments of 5 | `0.0` |
120
+ | `└─ mouth_pout` | ✗ | Mouth pout (-100 to 100), in increments of 5 | `0.0` |
121
+ | `└─ mouth_purse` | ✗ | Mouth purse (-100 to 100), in increments of 5 | `0.0` |
122
+ | `└─ mouth_smile` | ✗ | Mouth smile (-100 to 100), in increments of 5 | `0.0` |
14
123
  | `name` | ✗ | The name of image. This value is mainly used for your own identification of the image. | `"Face Editor image"` |
15
124
 
16
125
  #### Synchronous Client
@@ -82,3 +191,4 @@ res = await client.v1.ai_face_editor.create(
82
191
 
83
192
  ##### Example
84
193
  `{"credits_charged": 1, "frame_cost": 1, "id": "cuid-example"}`
194
+
@@ -1,3 +1,4 @@
1
+ import logging
1
2
  import typing
2
3
 
3
4
  from magic_hour.core import (
@@ -8,13 +9,101 @@ from magic_hour.core import (
8
9
  to_encodable,
9
10
  type_utils,
10
11
  )
12
+ from magic_hour.resources.v1.files.client import AsyncFilesClient, FilesClient
13
+ from magic_hour.resources.v1.image_projects.client import (
14
+ AsyncImageProjectsClient,
15
+ ImageProjectsClient,
16
+ )
11
17
  from magic_hour.types import models, params
12
18
 
13
19
 
20
+ logging.basicConfig(level=logging.INFO)
21
+ logger = logging.getLogger(__name__)
22
+
23
+
14
24
  class AiFaceEditorClient:
15
25
  def __init__(self, *, base_client: SyncBaseClient):
16
26
  self._base_client = base_client
17
27
 
28
+ def generate(
29
+ self,
30
+ *,
31
+ assets: params.V1AiFaceEditorGenerateBodyAssets,
32
+ style: params.V1AiFaceEditorCreateBodyStyle,
33
+ name: typing.Union[
34
+ typing.Optional[str], type_utils.NotGiven
35
+ ] = type_utils.NOT_GIVEN,
36
+ wait_for_completion: bool = True,
37
+ download_outputs: bool = True,
38
+ download_directory: typing.Optional[str] = None,
39
+ request_options: typing.Optional[RequestOptions] = None,
40
+ ):
41
+ """
42
+ Generate face edited image (alias for create with additional functionality).
43
+
44
+ Edit facial features of an image using AI. Each edit costs 1 frame. The height/width of the output image depends on your subscription. Please refer to our [pricing](/pricing) page for more details
45
+
46
+ Args:
47
+ name: The name of image. This value is mainly used for your own identification of the image.
48
+ assets: Provide the assets for face editor
49
+ style: Face editing parameters
50
+ wait_for_completion: Whether to wait for the image project to complete
51
+ download_outputs: Whether to download the outputs
52
+ download_directory: The directory to download the outputs to. If not provided, the outputs will be downloaded to the current working directory
53
+ request_options: Additional options to customize the HTTP request
54
+
55
+ Returns:
56
+ V1ImageProjectsGetResponseWithDownloads: The response from the AI Face Editor API with the downloaded paths if `download_outputs` is True.
57
+
58
+ Examples:
59
+ ```py
60
+ response = client.v1.ai_face_editor.generate(
61
+ assets={"image_file_path": "path/to/face.png"},
62
+ style={
63
+ "enhance_face": True,
64
+ "eye_gaze_horizontal": 0.2,
65
+ "eye_gaze_vertical": -0.1,
66
+ "eye_open_ratio": 0.8,
67
+ "eyebrow_direction": 0.3,
68
+ "head_pitch": 0.1,
69
+ "head_roll": 0.0,
70
+ "head_yaw": -0.2,
71
+ "lip_open_ratio": 0.0,
72
+ "mouth_grim": 0.0,
73
+ "mouth_position_horizontal": 0.0,
74
+ "mouth_position_vertical": 0.0,
75
+ "mouth_pout": 0.0,
76
+ "mouth_purse": 0.0,
77
+ "mouth_smile": 0.5,
78
+ },
79
+ name="Face Editor image",
80
+ wait_for_completion=True,
81
+ download_outputs=True,
82
+ download_directory="outputs/",
83
+ )
84
+ ```
85
+ """
86
+
87
+ file_client = FilesClient(base_client=self._base_client)
88
+
89
+ image_file_path = assets["image_file_path"]
90
+ assets["image_file_path"] = file_client.upload_file(file=image_file_path)
91
+
92
+ create_response = self.create(
93
+ assets=assets, style=style, name=name, request_options=request_options
94
+ )
95
+ logger.info(f"AI Face Editor response: {create_response}")
96
+
97
+ image_projects_client = ImageProjectsClient(base_client=self._base_client)
98
+ response = image_projects_client.check_result(
99
+ id=create_response.id,
100
+ wait_for_completion=wait_for_completion,
101
+ download_outputs=download_outputs,
102
+ download_directory=download_directory,
103
+ )
104
+
105
+ return response
106
+
18
107
  def create(
19
108
  self,
20
109
  *,
@@ -88,6 +177,85 @@ class AsyncAiFaceEditorClient:
88
177
  def __init__(self, *, base_client: AsyncBaseClient):
89
178
  self._base_client = base_client
90
179
 
180
+ async def generate(
181
+ self,
182
+ *,
183
+ assets: params.V1AiFaceEditorGenerateBodyAssets,
184
+ style: params.V1AiFaceEditorCreateBodyStyle,
185
+ name: typing.Union[
186
+ typing.Optional[str], type_utils.NotGiven
187
+ ] = type_utils.NOT_GIVEN,
188
+ wait_for_completion: bool = True,
189
+ download_outputs: bool = True,
190
+ download_directory: typing.Optional[str] = None,
191
+ request_options: typing.Optional[RequestOptions] = None,
192
+ ):
193
+ """
194
+ Generate face edited image (alias for create with additional functionality).
195
+
196
+ Edit facial features of an image using AI. Each edit costs 1 frame. The height/width of the output image depends on your subscription. Please refer to our [pricing](/pricing) page for more details
197
+
198
+ Args:
199
+ name: The name of image. This value is mainly used for your own identification of the image.
200
+ assets: Provide the assets for face editor
201
+ style: Face editing parameters
202
+ wait_for_completion: Whether to wait for the image project to complete
203
+ download_outputs: Whether to download the outputs
204
+ download_directory: The directory to download the outputs to. If not provided, the outputs will be downloaded to the current working directory
205
+ request_options: Additional options to customize the HTTP request
206
+
207
+ Returns:
208
+ V1ImageProjectsGetResponseWithDownloads: The response from the AI Face Editor API with the downloaded paths if `download_outputs` is True.
209
+
210
+ Examples:
211
+ ```py
212
+ response = await client.v1.ai_face_editor.generate(
213
+ assets={"image_file_path": "path/to/face.png"},
214
+ style={
215
+ "enhance_face": True,
216
+ "eye_gaze_horizontal": 0.2,
217
+ "eye_gaze_vertical": -0.1,
218
+ "eye_open_ratio": 0.8,
219
+ "eyebrow_direction": 0.3,
220
+ "head_pitch": 0.1,
221
+ "head_roll": 0.0,
222
+ "head_yaw": -0.2,
223
+ "lip_open_ratio": 0.0,
224
+ "mouth_grim": 0.0,
225
+ "mouth_position_horizontal": 0.0,
226
+ "mouth_position_vertical": 0.0,
227
+ "mouth_pout": 0.0,
228
+ "mouth_purse": 0.0,
229
+ "mouth_smile": 0.5,
230
+ },
231
+ name="Face Editor image",
232
+ wait_for_completion=True,
233
+ download_outputs=True,
234
+ download_directory="outputs/",
235
+ )
236
+ ```
237
+ """
238
+
239
+ file_client = AsyncFilesClient(base_client=self._base_client)
240
+
241
+ image_file_path = assets["image_file_path"]
242
+ assets["image_file_path"] = await file_client.upload_file(file=image_file_path)
243
+
244
+ create_response = await self.create(
245
+ assets=assets, style=style, name=name, request_options=request_options
246
+ )
247
+ logger.info(f"AI Face Editor response: {create_response}")
248
+
249
+ image_projects_client = AsyncImageProjectsClient(base_client=self._base_client)
250
+ response = await image_projects_client.check_result(
251
+ id=create_response.id,
252
+ wait_for_completion=wait_for_completion,
253
+ download_outputs=download_outputs,
254
+ download_directory=download_directory,
255
+ )
256
+
257
+ return response
258
+
91
259
  async def create(
92
260
  self,
93
261
  *,
@@ -1,3 +1,60 @@
1
+ # v1_ai_gif_generator
2
+
3
+ ## Module Functions
4
+
5
+ <!-- CUSTOM DOCS START -->
6
+
7
+ ### Ai Gif Generator Generate Workflow <a name="generate"></a>
8
+
9
+ The workflow performs the following action
10
+
11
+ 1. upload local assets to Magic Hour storage. So you can pass in a local path instead of having to upload files yourself
12
+ 2. trigger a generation
13
+ 3. poll for a completion status. This is configurable
14
+ 4. if success, download the output to local directory
15
+
16
+ > [!TIP]
17
+ > This is the recommended way to use the SDK unless you have specific needs where it is necessary to split up the actions.
18
+
19
+ #### Parameters
20
+
21
+ In Additional to the parameters listed in the `.create` section below, `.generate` introduces 3 new parameters:
22
+
23
+ - `wait_for_completion` (bool, default True): Whether to wait for the project to complete.
24
+ - `download_outputs` (bool, default True): Whether to download the generated files
25
+ - `download_directory` (str, optional): Directory to save downloaded files (defaults to current directory)
26
+
27
+ #### Synchronous Client
28
+
29
+ ```python
30
+ from magic_hour import Client
31
+ from os import getenv
32
+
33
+ client = Client(token=getenv("API_TOKEN"))
34
+ res = client.v1.ai_gif_generator.generate(
35
+ style={"prompt": "Cute dancing cat, pixel art"}, name="Ai Gif gif"
36
+ wait_for_completion=True,
37
+ download_outputs=True,
38
+ download_directory="outputs"
39
+ )
40
+ ```
41
+
42
+ #### Asynchronous Client
43
+
44
+ ```python
45
+ from magic_hour import AsyncClient
46
+ from os import getenv
47
+
48
+ client = AsyncClient(token=getenv("API_TOKEN"))
49
+ res = await client.v1.ai_gif_generator.generate(
50
+ style={"prompt": "Cute dancing cat, pixel art"}, name="Ai Gif gif"
51
+ wait_for_completion=True,
52
+ download_outputs=True,
53
+ download_directory="outputs"
54
+ )
55
+ ```
56
+
57
+ <!-- CUSTOM DOCS END -->
1
58
 
2
59
  ### AI GIFs <a name="create"></a>
3
60
 
@@ -10,6 +67,7 @@ Create an AI GIF. Each GIF costs 50 credits.
10
67
  | Parameter | Required | Description | Example |
11
68
  |-----------|:--------:|-------------|--------|
12
69
  | `style` | ✓ | | `{"prompt": "Cute dancing cat, pixel art"}` |
70
+ | `└─ prompt` | ✓ | The prompt used for the GIF. | `"Cute dancing cat, pixel art"` |
13
71
  | `name` | ✗ | The name of gif. This value is mainly used for your own identification of the gif. | `"Ai Gif gif"` |
14
72
 
15
73
  #### Synchronous Client
@@ -45,3 +103,4 @@ res = await client.v1.ai_gif_generator.create(
45
103
 
46
104
  ##### Example
47
105
  `{"credits_charged": 50, "frame_cost": 50, "id": "cuid-example"}`
106
+
@@ -1,3 +1,4 @@
1
+ import logging
1
2
  import typing
2
3
 
3
4
  from magic_hour.core import (
@@ -8,13 +9,76 @@ from magic_hour.core import (
8
9
  to_encodable,
9
10
  type_utils,
10
11
  )
12
+ from magic_hour.resources.v1.image_projects.client import (
13
+ AsyncImageProjectsClient,
14
+ ImageProjectsClient,
15
+ )
11
16
  from magic_hour.types import models, params
12
17
 
13
18
 
19
+ logging.basicConfig(level=logging.INFO)
20
+ logger = logging.getLogger(__name__)
21
+
22
+
14
23
  class AiGifGeneratorClient:
15
24
  def __init__(self, *, base_client: SyncBaseClient):
16
25
  self._base_client = base_client
17
26
 
27
+ def generate(
28
+ self,
29
+ *,
30
+ style: params.V1AiGifGeneratorCreateBodyStyle,
31
+ name: typing.Union[
32
+ typing.Optional[str], type_utils.NotGiven
33
+ ] = type_utils.NOT_GIVEN,
34
+ wait_for_completion: bool = True,
35
+ download_outputs: bool = True,
36
+ download_directory: typing.Optional[str] = None,
37
+ request_options: typing.Optional[RequestOptions] = None,
38
+ ):
39
+ """
40
+ Generate GIF (alias for create with additional functionality).
41
+
42
+ Create an AI GIF. Each GIF costs 5 credits.
43
+
44
+ Args:
45
+ name: The name of image. This value is mainly used for your own identification of the image.
46
+ style: The art style to use for GIF generation
47
+ wait_for_completion: Whether to wait for the image project to complete
48
+ download_outputs: Whether to download the outputs
49
+ download_directory: The directory to download the outputs to. If not provided, the outputs will be downloaded to the current working directory
50
+ request_options: Additional options to customize the HTTP request
51
+
52
+ Returns:
53
+ V1ImageProjectsGetResponseWithDownloads: The response from the AI GIF Generator API with the downloaded paths if `download_outputs` is True.
54
+
55
+ Examples:
56
+ ```py
57
+ response = client.v1.ai_gif_generator.generate(
58
+ style={"prompt": "Cute dancing cat, pixel art"},
59
+ name="Dancing Cat GIF",
60
+ wait_for_completion=True,
61
+ download_outputs=True,
62
+ download_directory="outputs/",
63
+ )
64
+ ```
65
+ """
66
+
67
+ create_response = self.create(
68
+ style=style, name=name, request_options=request_options
69
+ )
70
+ logger.info(f"AI GIF Generator response: {create_response}")
71
+
72
+ image_projects_client = ImageProjectsClient(base_client=self._base_client)
73
+ response = image_projects_client.check_result(
74
+ id=create_response.id,
75
+ wait_for_completion=wait_for_completion,
76
+ download_outputs=download_outputs,
77
+ download_directory=download_directory,
78
+ )
79
+
80
+ return response
81
+
18
82
  def create(
19
83
  self,
20
84
  *,
@@ -68,6 +132,61 @@ class AsyncAiGifGeneratorClient:
68
132
  def __init__(self, *, base_client: AsyncBaseClient):
69
133
  self._base_client = base_client
70
134
 
135
+ async def generate(
136
+ self,
137
+ *,
138
+ style: params.V1AiGifGeneratorCreateBodyStyle,
139
+ name: typing.Union[
140
+ typing.Optional[str], type_utils.NotGiven
141
+ ] = type_utils.NOT_GIVEN,
142
+ wait_for_completion: bool = True,
143
+ download_outputs: bool = True,
144
+ download_directory: typing.Optional[str] = None,
145
+ request_options: typing.Optional[RequestOptions] = None,
146
+ ):
147
+ """
148
+ Generate GIF (alias for create with additional functionality).
149
+
150
+ Create an AI GIF. Each GIF costs 5 credits.
151
+
152
+ Args:
153
+ name: The name of image. This value is mainly used for your own identification of the image.
154
+ style: The art style to use for GIF generation
155
+ wait_for_completion: Whether to wait for the image project to complete
156
+ download_outputs: Whether to download the outputs
157
+ download_directory: The directory to download the outputs to. If not provided, the outputs will be downloaded to the current working directory
158
+ request_options: Additional options to customize the HTTP request
159
+
160
+ Returns:
161
+ V1ImageProjectsGetResponseWithDownloads: The response from the AI GIF Generator API with the downloaded paths if `download_outputs` is True.
162
+
163
+ Examples:
164
+ ```py
165
+ response = await client.v1.ai_gif_generator.generate(
166
+ style={"prompt": "Cute dancing cat, pixel art"},
167
+ name="Dancing Cat GIF",
168
+ wait_for_completion=True,
169
+ download_outputs=True,
170
+ download_directory="outputs/",
171
+ )
172
+ ```
173
+ """
174
+
175
+ create_response = await self.create(
176
+ style=style, name=name, request_options=request_options
177
+ )
178
+ logger.info(f"AI GIF Generator response: {create_response}")
179
+
180
+ image_projects_client = AsyncImageProjectsClient(base_client=self._base_client)
181
+ response = await image_projects_client.check_result(
182
+ id=create_response.id,
183
+ wait_for_completion=wait_for_completion,
184
+ download_outputs=download_outputs,
185
+ download_directory=download_directory,
186
+ )
187
+
188
+ return response
189
+
71
190
  async def create(
72
191
  self,
73
192
  *,
@@ -1,3 +1,60 @@
1
+ # v1_ai_headshot_generator
2
+
3
+ ## Module Functions
4
+
5
+ <!-- CUSTOM DOCS START -->
6
+
7
+ ### Ai Headshot Generator Generate Workflow <a name="generate"></a>
8
+
9
+ The workflow performs the following action
10
+
11
+ 1. upload local assets to Magic Hour storage. So you can pass in a local path instead of having to upload files yourself
12
+ 2. trigger a generation
13
+ 3. poll for a completion status. This is configurable
14
+ 4. if success, download the output to local directory
15
+
16
+ > [!TIP]
17
+ > This is the recommended way to use the SDK unless you have specific needs where it is necessary to split up the actions.
18
+
19
+ #### Parameters
20
+
21
+ In Additional to the parameters listed in the `.create` section below, `.generate` introduces 3 new parameters:
22
+
23
+ - `wait_for_completion` (bool, default True): Whether to wait for the project to complete.
24
+ - `download_outputs` (bool, default True): Whether to download the generated files
25
+ - `download_directory` (str, optional): Directory to save downloaded files (defaults to current directory)
26
+
27
+ #### Synchronous Client
28
+
29
+ ```python
30
+ from magic_hour import Client
31
+ from os import getenv
32
+
33
+ client = Client(token=getenv("API_TOKEN"))
34
+ res = client.v1.ai_headshot_generator.generate(
35
+ assets={"image_file_path": "/path/to/1234.png"}, name="Ai Headshot image"
36
+ wait_for_completion=True,
37
+ download_outputs=True,
38
+ download_directory="outputs"
39
+ )
40
+ ```
41
+
42
+ #### Asynchronous Client
43
+
44
+ ```python
45
+ from magic_hour import AsyncClient
46
+ from os import getenv
47
+
48
+ client = AsyncClient(token=getenv("API_TOKEN"))
49
+ res = await client.v1.ai_headshot_generator.generate(
50
+ assets={"image_file_path": "/path/to/1234.png"}, name="Ai Headshot image"
51
+ wait_for_completion=True,
52
+ download_outputs=True,
53
+ download_directory="outputs"
54
+ )
55
+ ```
56
+
57
+ <!-- CUSTOM DOCS END -->
1
58
 
2
59
  ### AI Headshots <a name="create"></a>
3
60
 
@@ -10,8 +67,10 @@ Create an AI headshot. Each headshot costs 50 credits.
10
67
  | Parameter | Required | Description | Example |
11
68
  |-----------|:--------:|-------------|--------|
12
69
  | `assets` | ✓ | Provide the assets for headshot photo | `{"image_file_path": "api-assets/id/1234.png"}` |
70
+ | `└─ image_file_path` | ✓ | The image used to generate the headshot. This image must contain one detectable face. This value is either - a direct URL to the video file - `file_path` field from the response of the [upload urls API](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls). Please refer to the [Input File documentation](https://docs.magichour.ai/api-reference/files/generate-asset-upload-urls#input-file) to learn more. | `"api-assets/id/1234.png"` |
13
71
  | `name` | ✗ | The name of image. This value is mainly used for your own identification of the image. | `"Ai Headshot image"` |
14
72
  | `style` | ✗ | | `{}` |
73
+ | `└─ prompt` | ✗ | Prompt used to guide the style of your headshot. We recommend omitting the prompt unless you want to customize your headshot. You can visit [AI headshot generator](https://magichour.ai/create/ai-headshot-generator) to view an example of a good prompt used for our 'Professional' style. | `"string"` |
15
74
 
16
75
  #### Synchronous Client
17
76
 
@@ -46,3 +105,4 @@ res = await client.v1.ai_headshot_generator.create(
46
105
 
47
106
  ##### Example
48
107
  `{"credits_charged": 50, "frame_cost": 50, "id": "cuid-example"}`
108
+