magic_hour 0.34.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 (97) 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 -12
  41. magic_hour/resources/v1/face_swap/client.py +262 -28
  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 +210 -8
  56. magic_hour/resources/v1/lip_sync/README.md +87 -13
  57. magic_hour/resources/v1/lip_sync/client.py +230 -28
  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 -14
  67. magic_hour/resources/v1/video_to_video/client.py +242 -28
  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 +24 -14
  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_create_body.py +14 -6
  87. magic_hour/types/params/v1_image_to_video_generate_body_assets.py +17 -0
  88. magic_hour/types/params/v1_lip_sync_create_body.py +12 -14
  89. magic_hour/types/params/v1_lip_sync_generate_body_assets.py +36 -0
  90. magic_hour/types/params/v1_photo_colorizer_generate_body_assets.py +17 -0
  91. magic_hour/types/params/v1_video_to_video_create_body.py +12 -14
  92. magic_hour/types/params/v1_video_to_video_generate_body_assets.py +27 -0
  93. magic_hour-0.36.0.dist-info/METADATA +303 -0
  94. {magic_hour-0.34.0.dist-info → magic_hour-0.36.0.dist-info}/RECORD +96 -68
  95. magic_hour-0.34.0.dist-info/METADATA +0 -166
  96. {magic_hour-0.34.0.dist-info → magic_hour-0.36.0.dist-info}/LICENSE +0 -0
  97. {magic_hour-0.34.0.dist-info → magic_hour-0.36.0.dist-info}/WHEEL +0 -0
@@ -1,3 +1,66 @@
1
+ # v1_ai_image_upscaler
2
+
3
+ ## Module Functions
4
+
5
+ <!-- CUSTOM DOCS START -->
6
+
7
+ ### Ai Image Upscaler 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_image_upscaler.generate(
35
+ assets={"image_file_path": "/path/to/1234.png"},
36
+ scale_factor=2.0,
37
+ style={"enhancement": "Balanced"},
38
+ name="Image Upscaler image",
39
+ wait_for_completion=True,
40
+ download_outputs=True,
41
+ download_directory="outputs"
42
+ )
43
+ ```
44
+
45
+ #### Asynchronous Client
46
+
47
+ ```python
48
+ from magic_hour import AsyncClient
49
+ from os import getenv
50
+
51
+ client = AsyncClient(token=getenv("API_TOKEN"))
52
+ res = await client.v1.ai_image_upscaler.generate(
53
+ assets={"image_file_path": "/path/to/1234.png"},
54
+ scale_factor=2.0,
55
+ style={"enhancement": "Balanced"},
56
+ name="Image Upscaler image",
57
+ wait_for_completion=True,
58
+ download_outputs=True,
59
+ download_directory="outputs"
60
+ )
61
+ ```
62
+
63
+ <!-- CUSTOM DOCS END -->
1
64
 
2
65
  ### AI Image Upscaler <a name="create"></a>
3
66
 
@@ -10,8 +73,11 @@ Upscale your image using AI. Each 2x upscale costs 50 credits, and 4x upscale co
10
73
  | Parameter | Required | Description | Example |
11
74
  |-----------|:--------:|-------------|--------|
12
75
  | `assets` | ✓ | Provide the assets for upscaling | `{"image_file_path": "api-assets/id/1234.png"}` |
76
+ | `└─ image_file_path` | ✓ | The image to upscale. 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
77
  | `scale_factor` | ✓ | How much to scale the image. Must be either 2 or 4. Note: 4x upscale is only available on Creator, Pro, or Business tier. | `2.0` |
14
78
  | `style` | ✓ | | `{"enhancement": "Balanced"}` |
79
+ | `└─ enhancement` | ✓ | | `"Balanced"` |
80
+ | `└─ prompt` | ✗ | A prompt to guide the final image. This value is ignored if `enhancement` is not Creative | `"string"` |
15
81
  | `name` | ✗ | The name of image. This value is mainly used for your own identification of the image. | `"Image Upscaler image"` |
16
82
 
17
83
  #### Synchronous Client
@@ -53,3 +119,4 @@ res = await client.v1.ai_image_upscaler.create(
53
119
 
54
120
  ##### Example
55
121
  `{"credits_charged": 50, "frame_cost": 50, "id": "cuid-example"}`
122
+
@@ -1,3 +1,4 @@
1
+ import logging
1
2
  import typing
2
3
 
3
4
  from magic_hour.core import (
@@ -8,13 +9,92 @@ 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 AiImageUpscalerClient:
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.V1AiImageUpscalerGenerateBodyAssets,
32
+ scale_factor: float,
33
+ style: params.V1AiImageUpscalerCreateBodyStyle,
34
+ name: typing.Union[
35
+ typing.Optional[str], type_utils.NotGiven
36
+ ] = type_utils.NOT_GIVEN,
37
+ wait_for_completion: bool = True,
38
+ download_outputs: bool = True,
39
+ download_directory: typing.Optional[str] = None,
40
+ request_options: typing.Optional[RequestOptions] = None,
41
+ ):
42
+ """
43
+ Generate upscaled image (alias for create with additional functionality).
44
+
45
+ Upscale image using AI. Each upscale costs 5 credits.
46
+
47
+ Args:
48
+ name: The name of image. This value is mainly used for your own identification of the image.
49
+ assets: Provide the assets for image upscaler
50
+ scale_factor: How much to scale the image. Must be either 2 or 4.
51
+ style: Image upscaling parameters
52
+ wait_for_completion: Whether to wait for the image project to complete
53
+ download_outputs: Whether to download the outputs
54
+ download_directory: The directory to download the outputs to. If not provided, the outputs will be downloaded to the current working directory
55
+ request_options: Additional options to customize the HTTP request
56
+
57
+ Returns:
58
+ V1ImageProjectsGetResponseWithDownloads: The response from the AI Image Upscaler API with the downloaded paths if `download_outputs` is True.
59
+
60
+ Examples:
61
+ ```py
62
+ response = client.v1.ai_image_upscaler.generate(
63
+ assets={"image_file_path": "path/to/image.png"},
64
+ scale_factor=2.0,
65
+ style={"enhancement": "Balanced"},
66
+ name="Upscaled Image",
67
+ wait_for_completion=True,
68
+ download_outputs=True,
69
+ download_directory="outputs/",
70
+ )
71
+ ```
72
+ """
73
+
74
+ file_client = FilesClient(base_client=self._base_client)
75
+
76
+ image_file_path = assets["image_file_path"]
77
+ assets["image_file_path"] = file_client.upload_file(file=image_file_path)
78
+
79
+ create_response = self.create(
80
+ assets=assets,
81
+ scale_factor=scale_factor,
82
+ style=style,
83
+ name=name,
84
+ request_options=request_options,
85
+ )
86
+ logger.info(f"AI Image Upscaler response: {create_response}")
87
+
88
+ image_projects_client = ImageProjectsClient(base_client=self._base_client)
89
+ response = image_projects_client.check_result(
90
+ id=create_response.id,
91
+ wait_for_completion=wait_for_completion,
92
+ download_outputs=download_outputs,
93
+ download_directory=download_directory,
94
+ )
95
+
96
+ return response
97
+
18
98
  def create(
19
99
  self,
20
100
  *,
@@ -82,6 +162,76 @@ class AsyncAiImageUpscalerClient:
82
162
  def __init__(self, *, base_client: AsyncBaseClient):
83
163
  self._base_client = base_client
84
164
 
165
+ async def generate(
166
+ self,
167
+ *,
168
+ assets: params.V1AiImageUpscalerGenerateBodyAssets,
169
+ scale_factor: float,
170
+ style: params.V1AiImageUpscalerCreateBodyStyle,
171
+ name: typing.Union[
172
+ typing.Optional[str], type_utils.NotGiven
173
+ ] = type_utils.NOT_GIVEN,
174
+ wait_for_completion: bool = True,
175
+ download_outputs: bool = True,
176
+ download_directory: typing.Optional[str] = None,
177
+ request_options: typing.Optional[RequestOptions] = None,
178
+ ):
179
+ """
180
+ Generate upscaled image (alias for create with additional functionality).
181
+
182
+ Upscale image using AI. Each upscale costs 5 credits.
183
+
184
+ Args:
185
+ name: The name of image. This value is mainly used for your own identification of the image.
186
+ assets: Provide the assets for image upscaler
187
+ scale_factor: How much to scale the image. Must be either 2 or 4.
188
+ style: Image upscaling parameters
189
+ wait_for_completion: Whether to wait for the image project to complete
190
+ download_outputs: Whether to download the outputs
191
+ download_directory: The directory to download the outputs to. If not provided, the outputs will be downloaded to the current working directory
192
+ request_options: Additional options to customize the HTTP request
193
+
194
+ Returns:
195
+ V1ImageProjectsGetResponseWithDownloads: The response from the AI Image Upscaler API with the downloaded paths if `download_outputs` is True.
196
+
197
+ Examples:
198
+ ```py
199
+ response = await client.v1.ai_image_upscaler.generate(
200
+ assets={"image_file_path": "path/to/image.png"},
201
+ scale_factor=2.0,
202
+ style={"enhancement": "Balanced"},
203
+ name="Upscaled Image",
204
+ wait_for_completion=True,
205
+ download_outputs=True,
206
+ download_directory="outputs/",
207
+ )
208
+ ```
209
+ """
210
+
211
+ file_client = AsyncFilesClient(base_client=self._base_client)
212
+
213
+ image_file_path = assets["image_file_path"]
214
+ assets["image_file_path"] = await file_client.upload_file(file=image_file_path)
215
+
216
+ create_response = await self.create(
217
+ assets=assets,
218
+ scale_factor=scale_factor,
219
+ style=style,
220
+ name=name,
221
+ request_options=request_options,
222
+ )
223
+ logger.info(f"AI Image Upscaler response: {create_response}")
224
+
225
+ image_projects_client = AsyncImageProjectsClient(base_client=self._base_client)
226
+ response = await image_projects_client.check_result(
227
+ id=create_response.id,
228
+ wait_for_completion=wait_for_completion,
229
+ download_outputs=download_outputs,
230
+ download_directory=download_directory,
231
+ )
232
+
233
+ return response
234
+
85
235
  async def create(
86
236
  self,
87
237
  *,
@@ -1,3 +1,70 @@
1
+ # v1_ai_meme_generator
2
+
3
+ ## Module Functions
4
+
5
+ <!-- CUSTOM DOCS START -->
6
+
7
+ ### Ai Meme 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_meme_generator.generate(
35
+ style={
36
+ "search_web": False,
37
+ "template": "Drake Hotline Bling",
38
+ "topic": "When the code finally works",
39
+ },
40
+ name="My Funny Meme",
41
+ wait_for_completion=True,
42
+ download_outputs=True,
43
+ download_directory="outputs"
44
+ )
45
+ ```
46
+
47
+ #### Asynchronous Client
48
+
49
+ ```python
50
+ from magic_hour import AsyncClient
51
+ from os import getenv
52
+
53
+ client = AsyncClient(token=getenv("API_TOKEN"))
54
+ res = await client.v1.ai_meme_generator.generate(
55
+ style={
56
+ "search_web": False,
57
+ "template": "Drake Hotline Bling",
58
+ "topic": "When the code finally works",
59
+ },
60
+ name="My Funny Meme",
61
+ wait_for_completion=True,
62
+ download_outputs=True,
63
+ download_directory="outputs"
64
+ )
65
+ ```
66
+
67
+ <!-- CUSTOM DOCS END -->
1
68
 
2
69
  ### AI Meme Generator <a name="create"></a>
3
70
 
@@ -10,6 +77,9 @@ Create an AI generated meme. Each meme costs 10 credits.
10
77
  | Parameter | Required | Description | Example |
11
78
  |-----------|:--------:|-------------|--------|
12
79
  | `style` | ✓ | | `{"search_web": False, "template": "Drake Hotline Bling", "topic": "When the code finally works"}` |
80
+ | `└─ search_web` | ✗ | Whether to search the web for meme content. | `False` |
81
+ | `└─ template` | ✓ | To use our templates, pass in one of the enum values. | `"Drake Hotline Bling"` |
82
+ | `└─ topic` | ✓ | The topic of the meme. | `"When the code finally works"` |
13
83
  | `name` | ✗ | The name of the meme. | `"My Funny Meme"` |
14
84
 
15
85
  #### Synchronous Client
@@ -55,3 +125,4 @@ res = await client.v1.ai_meme_generator.create(
55
125
 
56
126
  ##### Example
57
127
  `{"credits_charged": 10, "frame_cost": 10, "id": "cuid-example"}`
128
+
@@ -1,3 +1,4 @@
1
+ import logging
1
2
  import typing
2
3
 
3
4
  from magic_hour.core import (
@@ -8,13 +9,80 @@ 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 AiMemeGeneratorClient:
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.V1AiMemeGeneratorCreateBodyStyle,
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 meme (alias for create with additional functionality).
41
+
42
+ Create an AI meme. Each meme 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 meme 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 Meme Generator API with the downloaded paths if `download_outputs` is True.
54
+
55
+ Examples:
56
+ ```py
57
+ response = client.v1.ai_meme_generator.generate(
58
+ style={
59
+ "search_web": False,
60
+ "template": "Drake Hotline Bling",
61
+ "topic": "When the code finally works",
62
+ },
63
+ name="Funny Programming Meme",
64
+ wait_for_completion=True,
65
+ download_outputs=True,
66
+ download_directory="outputs/",
67
+ )
68
+ ```
69
+ """
70
+
71
+ create_response = self.create(
72
+ style=style, name=name, request_options=request_options
73
+ )
74
+ logger.info(f"AI Meme Generator response: {create_response}")
75
+
76
+ image_projects_client = ImageProjectsClient(base_client=self._base_client)
77
+ response = image_projects_client.check_result(
78
+ id=create_response.id,
79
+ wait_for_completion=wait_for_completion,
80
+ download_outputs=download_outputs,
81
+ download_directory=download_directory,
82
+ )
83
+
84
+ return response
85
+
18
86
  def create(
19
87
  self,
20
88
  *,
@@ -73,6 +141,65 @@ class AsyncAiMemeGeneratorClient:
73
141
  def __init__(self, *, base_client: AsyncBaseClient):
74
142
  self._base_client = base_client
75
143
 
144
+ async def generate(
145
+ self,
146
+ *,
147
+ style: params.V1AiMemeGeneratorCreateBodyStyle,
148
+ name: typing.Union[
149
+ typing.Optional[str], type_utils.NotGiven
150
+ ] = type_utils.NOT_GIVEN,
151
+ wait_for_completion: bool = True,
152
+ download_outputs: bool = True,
153
+ download_directory: typing.Optional[str] = None,
154
+ request_options: typing.Optional[RequestOptions] = None,
155
+ ):
156
+ """
157
+ Generate meme (alias for create with additional functionality).
158
+
159
+ Create an AI meme. Each meme costs 5 credits.
160
+
161
+ Args:
162
+ name: The name of image. This value is mainly used for your own identification of the image.
163
+ style: The art style to use for meme generation
164
+ wait_for_completion: Whether to wait for the image project to complete
165
+ download_outputs: Whether to download the outputs
166
+ download_directory: The directory to download the outputs to. If not provided, the outputs will be downloaded to the current working directory
167
+ request_options: Additional options to customize the HTTP request
168
+
169
+ Returns:
170
+ V1ImageProjectsGetResponseWithDownloads: The response from the AI Meme Generator API with the downloaded paths if `download_outputs` is True.
171
+
172
+ Examples:
173
+ ```py
174
+ response = await client.v1.ai_meme_generator.generate(
175
+ style={
176
+ "search_web": False,
177
+ "template": "Drake Hotline Bling",
178
+ "topic": "When the code finally works",
179
+ },
180
+ name="Funny Programming Meme",
181
+ wait_for_completion=True,
182
+ download_outputs=True,
183
+ download_directory="outputs/",
184
+ )
185
+ ```
186
+ """
187
+
188
+ create_response = await self.create(
189
+ style=style, name=name, request_options=request_options
190
+ )
191
+ logger.info(f"AI Meme Generator response: {create_response}")
192
+
193
+ image_projects_client = AsyncImageProjectsClient(base_client=self._base_client)
194
+ response = await image_projects_client.check_result(
195
+ id=create_response.id,
196
+ wait_for_completion=wait_for_completion,
197
+ download_outputs=download_outputs,
198
+ download_directory=download_directory,
199
+ )
200
+
201
+ return response
202
+
76
203
  async def create(
77
204
  self,
78
205
  *,
@@ -1,3 +1,84 @@
1
+ # v1_ai_photo_editor
2
+
3
+ ## Module Functions
4
+
5
+ <!-- CUSTOM DOCS START -->
6
+
7
+ ### Ai Photo 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_photo_editor.generate(
35
+ assets={"image_file_path": "/path/to/1234.png"},
36
+ resolution=768,
37
+ style={
38
+ "image_description": "A photo of a person",
39
+ "likeness_strength": 5.2,
40
+ "negative_prompt": "painting, cartoon, sketch",
41
+ "prompt": "A photo portrait of a person wearing a hat",
42
+ "prompt_strength": 3.75,
43
+ "steps": 4,
44
+ "upscale_factor": 2,
45
+ "upscale_fidelity": 0.5,
46
+ },
47
+ name="Photo Editor image",
48
+ wait_for_completion=True,
49
+ download_outputs=True,
50
+ download_directory="outputs"
51
+ )
52
+ ```
53
+
54
+ #### Asynchronous Client
55
+
56
+ ```python
57
+ from magic_hour import AsyncClient
58
+ from os import getenv
59
+
60
+ client = AsyncClient(token=getenv("API_TOKEN"))
61
+ res = await client.v1.ai_photo_editor.generate(
62
+ assets={"image_file_path": "/path/to/1234.png"},
63
+ resolution=768,
64
+ style={
65
+ "image_description": "A photo of a person",
66
+ "likeness_strength": 5.2,
67
+ "negative_prompt": "painting, cartoon, sketch",
68
+ "prompt": "A photo portrait of a person wearing a hat",
69
+ "prompt_strength": 3.75,
70
+ "steps": 4,
71
+ "upscale_factor": 2,
72
+ "upscale_fidelity": 0.5,
73
+ },
74
+ name="Photo Editor image",
75
+ wait_for_completion=True,
76
+ download_outputs=True,
77
+ download_directory="outputs"
78
+ )
79
+ ```
80
+
81
+ <!-- CUSTOM DOCS END -->
1
82
 
2
83
  ### AI Photo Editor <a name="create"></a>
3
84
 
@@ -9,13 +90,22 @@ Edit photo using AI. Each photo costs 10 credits.
9
90
 
10
91
  #### Parameters
11
92
 
12
- | Parameter | Required | Description | Example |
13
- |-----------|:--------:|-------------|--------|
14
- | `assets` | ✓ | Provide the assets for photo editor | `{"image_file_path": "api-assets/id/1234.png"}` |
15
- | `resolution` | ✓ | The resolution of the final output image. The allowed value is based on your subscription. Please refer to our [pricing page](https://magichour.ai/pricing) for more details | `768` |
16
- | `style` | ✓ | | `{"image_description": "A photo of a person", "likeness_strength": 5.2, "negative_prompt": "painting, cartoon, sketch", "prompt": "A photo portrait of a person wearing a hat", "prompt_strength": 3.75, "steps": 4, "upscale_factor": 2, "upscale_fidelity": 0.5}` |
17
- | `name` | ✗ | The name of image. This value is mainly used for your own identification of the image. | `"Photo Editor image"` |
18
- | `steps` | | Deprecated: Please use `.style.steps` instead. Number of iterations used to generate the output. Higher values improve quality and increase the strength of the prompt but increase processing time. | `123` |
93
+ | Parameter | Required | Deprecated | Description | Example |
94
+ |-----------|:--------:|:----------:|-------------|--------|
95
+ | `assets` | ✓ | ✗ | Provide the assets for photo editor | `{"image_file_path": "api-assets/id/1234.png"}` |
96
+ | `└─ image_file_path` | ✓ | — | The image used to generate the output. 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"` |
97
+ | `resolution` | ✓ || The resolution of the final output image. The allowed value is based on your subscription. Please refer to our [pricing page](https://magichour.ai/pricing) for more details | `768` |
98
+ | `style` | ✓ | ✗ | | `{"image_description": "A photo of a person", "likeness_strength": 5.2, "negative_prompt": "painting, cartoon, sketch", "prompt": "A photo portrait of a person wearing a hat", "prompt_strength": 3.75, "steps": 4, "upscale_factor": 2, "upscale_fidelity": 0.5}` |
99
+ | `└─ image_description` | | | Use this to describe what your input image is. This helps maintain aspects of the image you don't want to change. | `"A photo of a person"` |
100
+ | `└─ likeness_strength` | ✓ | — | Determines the input image's influence. Higher values align the output more with the initial image. | `5.2` |
101
+ | `└─ negative_prompt` | ✗ | — | What you want to avoid seeing in the final output; has a minor effect. | `"painting, cartoon, sketch"` |
102
+ | `└─ prompt` | ✓ | — | What you want your final output to look like. We recommend starting with the image description and making minor edits for best results. | `"A photo portrait of a person wearing a hat"` |
103
+ | `└─ prompt_strength` | ✓ | — | Determines the prompt's influence. Higher values align the output more with the prompt. | `3.75` |
104
+ | `└─ steps` | ✗ | — | Number of iterations used to generate the output. Higher values improve quality and increase the strength of the prompt but increase processing time. | `4` |
105
+ | `└─ upscale_factor` | ✗ | — | The multiplier applied to an image's original dimensions during the upscaling process. For example, a scale of 2 doubles the width and height (e.g., from 512x512 to 1024x1024). | `2` |
106
+ | `└─ upscale_fidelity` | ✗ | — | Upscale fidelity refers to the level of quality desired in the generated image. Fidelity value of 1 means more details. | `0.5` |
107
+ | `name` | ✗ | ✗ | The name of image. This value is mainly used for your own identification of the image. | `"Photo Editor image"` |
108
+ | `steps` | ✗ | ✓ | Deprecated: Please use `.style.steps` instead. Number of iterations used to generate the output. Higher values improve quality and increase the strength of the prompt but increase processing time. | `123` |
19
109
 
20
110
  #### Synchronous Client
21
111
 
@@ -74,3 +164,4 @@ res = await client.v1.ai_photo_editor.create(
74
164
 
75
165
  ##### Example
76
166
  `{"credits_charged": 10, "frame_cost": 10, "id": "cuid-example"}`
167
+