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.
- magic_hour/README.md +35 -0
- magic_hour/core/base_client.py +6 -5
- magic_hour/core/query.py +12 -6
- magic_hour/core/request.py +3 -3
- magic_hour/core/response.py +18 -14
- magic_hour/core/utils.py +3 -3
- magic_hour/environment.py +1 -1
- magic_hour/helpers/__init__.py +3 -0
- magic_hour/helpers/download.py +75 -0
- magic_hour/resources/v1/README.md +33 -0
- magic_hour/resources/v1/ai_clothes_changer/README.md +73 -0
- magic_hour/resources/v1/ai_clothes_changer/client.py +146 -0
- magic_hour/resources/v1/ai_face_editor/README.md +110 -0
- magic_hour/resources/v1/ai_face_editor/client.py +168 -0
- magic_hour/resources/v1/ai_gif_generator/README.md +59 -0
- magic_hour/resources/v1/ai_gif_generator/client.py +119 -0
- magic_hour/resources/v1/ai_headshot_generator/README.md +60 -0
- magic_hour/resources/v1/ai_headshot_generator/client.py +140 -0
- magic_hour/resources/v1/ai_image_editor/README.md +64 -0
- magic_hour/resources/v1/ai_image_editor/client.py +136 -0
- magic_hour/resources/v1/ai_image_generator/README.md +66 -0
- magic_hour/resources/v1/ai_image_generator/client.py +139 -0
- magic_hour/resources/v1/ai_image_upscaler/README.md +67 -0
- magic_hour/resources/v1/ai_image_upscaler/client.py +150 -0
- magic_hour/resources/v1/ai_meme_generator/README.md +71 -0
- magic_hour/resources/v1/ai_meme_generator/client.py +127 -0
- magic_hour/resources/v1/ai_photo_editor/README.md +98 -7
- magic_hour/resources/v1/ai_photo_editor/client.py +174 -0
- magic_hour/resources/v1/ai_qr_code_generator/README.md +63 -0
- magic_hour/resources/v1/ai_qr_code_generator/client.py +123 -0
- magic_hour/resources/v1/ai_talking_photo/README.md +74 -0
- magic_hour/resources/v1/ai_talking_photo/client.py +170 -0
- magic_hour/resources/v1/animation/README.md +100 -0
- magic_hour/resources/v1/animation/client.py +218 -0
- magic_hour/resources/v1/auto_subtitle_generator/README.md +69 -0
- magic_hour/resources/v1/auto_subtitle_generator/client.py +178 -0
- magic_hour/resources/v1/face_detection/README.md +59 -0
- magic_hour/resources/v1/face_detection/__init__.py +10 -2
- magic_hour/resources/v1/face_detection/client.py +179 -0
- magic_hour/resources/v1/face_swap/README.md +105 -12
- magic_hour/resources/v1/face_swap/client.py +262 -28
- magic_hour/resources/v1/face_swap_photo/README.md +84 -0
- magic_hour/resources/v1/face_swap_photo/client.py +172 -0
- magic_hour/resources/v1/files/README.md +6 -0
- magic_hour/resources/v1/files/client.py +350 -0
- magic_hour/resources/v1/files/client_test.py +414 -0
- magic_hour/resources/v1/files/upload_urls/README.md +8 -0
- magic_hour/resources/v1/image_background_remover/README.md +68 -0
- magic_hour/resources/v1/image_background_remover/client.py +130 -0
- magic_hour/resources/v1/image_projects/README.md +8 -0
- magic_hour/resources/v1/image_projects/__init__.py +10 -2
- magic_hour/resources/v1/image_projects/client.py +138 -0
- magic_hour/resources/v1/image_projects/client_test.py +527 -0
- magic_hour/resources/v1/image_to_video/README.md +77 -9
- magic_hour/resources/v1/image_to_video/client.py +210 -8
- magic_hour/resources/v1/lip_sync/README.md +87 -13
- magic_hour/resources/v1/lip_sync/client.py +230 -28
- magic_hour/resources/v1/photo_colorizer/README.md +59 -0
- magic_hour/resources/v1/photo_colorizer/client.py +130 -0
- magic_hour/resources/v1/text_to_video/README.md +68 -0
- magic_hour/resources/v1/text_to_video/client.py +151 -0
- magic_hour/resources/v1/video_projects/README.md +8 -0
- magic_hour/resources/v1/video_projects/__init__.py +10 -2
- magic_hour/resources/v1/video_projects/client.py +137 -0
- magic_hour/resources/v1/video_projects/client_test.py +527 -0
- magic_hour/resources/v1/video_to_video/README.md +98 -14
- magic_hour/resources/v1/video_to_video/client.py +242 -28
- magic_hour/types/params/__init__.py +58 -0
- magic_hour/types/params/v1_ai_clothes_changer_generate_body_assets.py +33 -0
- magic_hour/types/params/v1_ai_face_editor_generate_body_assets.py +17 -0
- magic_hour/types/params/v1_ai_headshot_generator_generate_body_assets.py +17 -0
- magic_hour/types/params/v1_ai_image_editor_generate_body_assets.py +17 -0
- magic_hour/types/params/v1_ai_image_upscaler_generate_body_assets.py +17 -0
- magic_hour/types/params/v1_ai_photo_editor_generate_body_assets.py +17 -0
- magic_hour/types/params/v1_ai_talking_photo_generate_body_assets.py +26 -0
- magic_hour/types/params/v1_animation_generate_body_assets.py +39 -0
- magic_hour/types/params/v1_auto_subtitle_generator_generate_body_assets.py +17 -0
- magic_hour/types/params/v1_face_detection_generate_body_assets.py +17 -0
- magic_hour/types/params/v1_face_swap_create_body.py +24 -14
- magic_hour/types/params/v1_face_swap_create_body_style.py +33 -0
- magic_hour/types/params/v1_face_swap_generate_body_assets.py +56 -0
- magic_hour/types/params/v1_face_swap_generate_body_assets_face_mappings_item.py +25 -0
- magic_hour/types/params/v1_face_swap_photo_generate_body_assets.py +47 -0
- magic_hour/types/params/v1_face_swap_photo_generate_body_assets_face_mappings_item.py +25 -0
- magic_hour/types/params/v1_image_background_remover_generate_body_assets.py +27 -0
- magic_hour/types/params/v1_image_to_video_create_body.py +14 -6
- magic_hour/types/params/v1_image_to_video_generate_body_assets.py +17 -0
- magic_hour/types/params/v1_lip_sync_create_body.py +12 -14
- magic_hour/types/params/v1_lip_sync_generate_body_assets.py +36 -0
- magic_hour/types/params/v1_photo_colorizer_generate_body_assets.py +17 -0
- magic_hour/types/params/v1_video_to_video_create_body.py +12 -14
- magic_hour/types/params/v1_video_to_video_generate_body_assets.py +27 -0
- magic_hour-0.36.0.dist-info/METADATA +303 -0
- {magic_hour-0.34.0.dist-info → magic_hour-0.36.0.dist-info}/RECORD +96 -68
- magic_hour-0.34.0.dist-info/METADATA +0 -166
- {magic_hour-0.34.0.dist-info → magic_hour-0.36.0.dist-info}/LICENSE +0 -0
- {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
|
-
| `
|
|
16
|
-
| `
|
|
17
|
-
| `
|
|
18
|
-
| `
|
|
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
|
+
|