Skip to content

Commit 5929172

Browse files
authored
feat: add generate function to ai voice generator (#102)
1 parent b99c032 commit 5929172

File tree

6 files changed

+183
-4
lines changed

6 files changed

+183
-4
lines changed

.sdk.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"id": "719cfc51-c189-4e81-9bf6-d25195f86e4f",
2+
"id": "2d9e6849-88f7-4a65-9c0f-1532d0c32953",
33
"tracked_paths": [
44
{
55
"editable": true,

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,7 @@ download_urls = result.downloads
211211
### [v1.ai_voice_generator](magic_hour/resources/v1/ai_voice_generator/README.md)
212212

213213
* [create](magic_hour/resources/v1/ai_voice_generator/README.md#create) - AI Voice Generator
214+
* [generate](magic_hour/resources/v1/ai_voice_generator/README.md#generate) - Ai Voice Generator Generate Workflow
214215

215216
### [v1.animation](magic_hour/resources/v1/animation/README.md)
216217

magic_hour/resources/v1/ai_voice_generator/README.md

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,62 @@
22

33
## Module Functions
44

5+
<!-- CUSTOM DOCS START -->
6+
7+
### Ai Talking Photo 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_talking_photo.generate(
35+
style={"prompt": "Hello, how are you?", "voice_name": "Elon Musk"},
36+
name="Voice Generator audio",
37+
wait_for_completion=True,
38+
download_outputs=True,
39+
download_directory="outputs"
40+
)
41+
```
42+
43+
#### Asynchronous Client
44+
45+
```python
46+
from magic_hour import AsyncClient
47+
from os import getenv
48+
49+
client = AsyncClient(token=getenv("API_TOKEN"))
50+
res = await client.v1.ai_talking_photo.generate(
51+
style={"prompt": "Hello, how are you?", "voice_name": "Elon Musk"},
52+
name="Voice Generator audio",
53+
wait_for_completion=True,
54+
download_outputs=True,
55+
download_directory="outputs"
56+
)
57+
```
58+
59+
<!-- CUSTOM DOCS END -->
60+
561
### AI Voice Generator <a name="create"></a>
662

763
Generate speech from text. Each character costs 0.05 credits. The cost is rounded up to the nearest whole number.

magic_hour/resources/v1/ai_voice_generator/client.py

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
import typing
22

3+
from magic_hour.helpers.logger import get_sdk_logger
4+
from magic_hour.resources.v1.audio_projects.client import (
5+
AsyncAudioProjectsClient,
6+
AudioProjectsClient,
7+
)
38
from magic_hour.types import models, params
49
from make_api_request import (
510
AsyncBaseClient,
@@ -11,10 +16,70 @@
1116
)
1217

1318

19+
logger = get_sdk_logger(__name__)
20+
21+
1422
class AiVoiceGeneratorClient:
1523
def __init__(self, *, base_client: SyncBaseClient):
1624
self._base_client = base_client
1725

26+
def generate(
27+
self,
28+
*,
29+
style: params.V1AiVoiceGeneratorCreateBodyStyle,
30+
name: typing.Union[
31+
typing.Optional[str], type_utils.NotGiven
32+
] = type_utils.NOT_GIVEN,
33+
wait_for_completion: bool = True,
34+
download_outputs: bool = True,
35+
download_directory: typing.Optional[str] = None,
36+
request_options: typing.Optional[RequestOptions] = None,
37+
):
38+
"""
39+
Generate AI voice (alias for create with additional functionality).
40+
41+
Generate speech from text. Each character costs 0.05 credits. The cost is rounded up to the nearest whole number.
42+
43+
Args:
44+
style: The content used to generate speech.
45+
name: The name of audio. This value is mainly used for your own identification of the audio.
46+
wait_for_completion: Whether to wait for the audio project to complete
47+
download_outputs: Whether to download the outputs
48+
download_directory: The directory to download the outputs to. If not provided, the outputs will be downloaded to the current working directory
49+
request_options: Additional options to customize the HTTP request
50+
51+
Returns:
52+
V1AudioProjectsGetResponseWithDownloads: The response from the AI Voice Generator API with the downloaded paths if `download_outputs` is True.
53+
54+
Examples:
55+
```py
56+
response = client.v1.ai_voice_generator.generate(
57+
style={"prompt": "Hello, how are you?", "voice_name": "Elon Musk"},
58+
name="Generated Voice",
59+
wait_for_completion=True,
60+
download_outputs=True,
61+
download_directory="outputs/",
62+
)
63+
```
64+
"""
65+
66+
create_response = self.create(
67+
style=style,
68+
name=name,
69+
request_options=request_options,
70+
)
71+
logger.info(f"AI Voice Generator response: {create_response}")
72+
73+
audio_projects_client = AudioProjectsClient(base_client=self._base_client)
74+
response = audio_projects_client.check_result(
75+
id=create_response.id,
76+
wait_for_completion=wait_for_completion,
77+
download_outputs=download_outputs,
78+
download_directory=download_directory,
79+
)
80+
81+
return response
82+
1883
def create(
1984
self,
2085
*,
@@ -69,6 +134,63 @@ class AsyncAiVoiceGeneratorClient:
69134
def __init__(self, *, base_client: AsyncBaseClient):
70135
self._base_client = base_client
71136

137+
async def generate(
138+
self,
139+
*,
140+
style: params.V1AiVoiceGeneratorCreateBodyStyle,
141+
name: typing.Union[
142+
typing.Optional[str], type_utils.NotGiven
143+
] = type_utils.NOT_GIVEN,
144+
wait_for_completion: bool = True,
145+
download_outputs: bool = True,
146+
download_directory: typing.Optional[str] = None,
147+
request_options: typing.Optional[RequestOptions] = None,
148+
):
149+
"""
150+
Generate AI voice (alias for create with additional functionality).
151+
152+
Generate speech from text. Each character costs 0.05 credits. The cost is rounded up to the nearest whole number.
153+
154+
Args:
155+
style: The content used to generate speech.
156+
name: The name of audio. This value is mainly used for your own identification of the audio.
157+
wait_for_completion: Whether to wait for the audio project to complete
158+
download_outputs: Whether to download the outputs
159+
download_directory: The directory to download the outputs to. If not provided, the outputs will be downloaded to the current working directory
160+
request_options: Additional options to customize the HTTP request
161+
162+
Returns:
163+
V1AudioProjectsGetResponseWithDownloads: The response from the AI Voice Generator API with the downloaded paths if `download_outputs` is True.
164+
165+
Examples:
166+
```py
167+
response = await client.v1.ai_voice_generator.generate(
168+
style={"prompt": "Hello, how are you?", "voice_name": "Elon Musk"},
169+
name="Generated Voice",
170+
wait_for_completion=True,
171+
download_outputs=True,
172+
download_directory="outputs/",
173+
)
174+
```
175+
"""
176+
177+
create_response = await self.create(
178+
style=style,
179+
name=name,
180+
request_options=request_options,
181+
)
182+
logger.info(f"AI Voice Generator response: {create_response}")
183+
184+
audio_projects_client = AsyncAudioProjectsClient(base_client=self._base_client)
185+
response = await audio_projects_client.check_result(
186+
id=create_response.id,
187+
wait_for_completion=wait_for_completion,
188+
download_outputs=download_outputs,
189+
download_directory=download_directory,
190+
)
191+
192+
return response
193+
72194
async def create(
73195
self,
74196
*,
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
from .client import (
22
AsyncAudioProjectsClient,
3-
V1AudioProjectsGetResponseWithDownloads,
43
AudioProjectsClient,
4+
V1AudioProjectsGetResponseWithDownloads,
55
)
66

77

88
__all__ = [
99
"AsyncAudioProjectsClient",
10-
"V1AudioProjectsGetResponseWithDownloads",
1110
"AudioProjectsClient",
11+
"V1AudioProjectsGetResponseWithDownloads",
1212
]

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "magic_hour"
3-
version = "0.41.1"
3+
version = "0.42.0"
44
description = "Python SDK for Magic Hour API"
55
readme = "README.md"
66
authors = []

0 commit comments

Comments
 (0)