cartesia 1.3.1__py3-none-any.whl → 2.0.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.
Files changed (181) hide show
  1. cartesia/__init__.py +302 -3
  2. cartesia/api_status/__init__.py +6 -0
  3. cartesia/api_status/client.py +104 -0
  4. cartesia/api_status/requests/__init__.py +5 -0
  5. cartesia/api_status/requests/api_info.py +8 -0
  6. cartesia/api_status/types/__init__.py +5 -0
  7. cartesia/api_status/types/api_info.py +20 -0
  8. cartesia/base_client.py +156 -0
  9. cartesia/client.py +163 -40
  10. cartesia/core/__init__.py +50 -0
  11. cartesia/core/api_error.py +15 -0
  12. cartesia/core/client_wrapper.py +55 -0
  13. cartesia/core/datetime_utils.py +28 -0
  14. cartesia/core/file.py +67 -0
  15. cartesia/core/http_client.py +499 -0
  16. cartesia/core/jsonable_encoder.py +101 -0
  17. cartesia/core/pagination.py +88 -0
  18. cartesia/core/pydantic_utilities.py +296 -0
  19. cartesia/core/query_encoder.py +58 -0
  20. cartesia/core/remove_none_from_dict.py +11 -0
  21. cartesia/core/request_options.py +35 -0
  22. cartesia/core/serialization.py +272 -0
  23. cartesia/datasets/__init__.py +24 -0
  24. cartesia/datasets/requests/__init__.py +15 -0
  25. cartesia/datasets/requests/create_dataset_request.py +7 -0
  26. cartesia/datasets/requests/dataset.py +9 -0
  27. cartesia/datasets/requests/dataset_file.py +9 -0
  28. cartesia/datasets/requests/paginated_dataset_files.py +10 -0
  29. cartesia/datasets/requests/paginated_datasets.py +10 -0
  30. cartesia/datasets/types/__init__.py +17 -0
  31. cartesia/datasets/types/create_dataset_request.py +19 -0
  32. cartesia/datasets/types/dataset.py +21 -0
  33. cartesia/datasets/types/dataset_file.py +21 -0
  34. cartesia/datasets/types/file_purpose.py +5 -0
  35. cartesia/datasets/types/paginated_dataset_files.py +21 -0
  36. cartesia/datasets/types/paginated_datasets.py +21 -0
  37. cartesia/embedding/__init__.py +5 -0
  38. cartesia/embedding/types/__init__.py +5 -0
  39. cartesia/embedding/types/embedding.py +201 -0
  40. cartesia/environment.py +7 -0
  41. cartesia/infill/__init__.py +2 -0
  42. cartesia/infill/client.py +318 -0
  43. cartesia/tts/__init__.py +167 -0
  44. cartesia/{_async_websocket.py → tts/_async_websocket.py} +212 -85
  45. cartesia/tts/_websocket.py +479 -0
  46. cartesia/tts/client.py +407 -0
  47. cartesia/tts/requests/__init__.py +76 -0
  48. cartesia/tts/requests/cancel_context_request.py +17 -0
  49. cartesia/tts/requests/controls.py +11 -0
  50. cartesia/tts/requests/generation_request.py +58 -0
  51. cartesia/tts/requests/mp_3_output_format.py +11 -0
  52. cartesia/tts/requests/output_format.py +30 -0
  53. cartesia/tts/requests/phoneme_timestamps.py +10 -0
  54. cartesia/tts/requests/raw_output_format.py +11 -0
  55. cartesia/tts/requests/speed.py +7 -0
  56. cartesia/tts/requests/tts_request.py +24 -0
  57. cartesia/tts/requests/tts_request_embedding_specifier.py +16 -0
  58. cartesia/tts/requests/tts_request_id_specifier.py +16 -0
  59. cartesia/tts/requests/tts_request_voice_specifier.py +7 -0
  60. cartesia/tts/requests/wav_output_format.py +7 -0
  61. cartesia/tts/requests/web_socket_base_response.py +11 -0
  62. cartesia/tts/requests/web_socket_chunk_response.py +11 -0
  63. cartesia/tts/requests/web_socket_done_response.py +7 -0
  64. cartesia/tts/requests/web_socket_error_response.py +7 -0
  65. cartesia/tts/requests/web_socket_flush_done_response.py +9 -0
  66. cartesia/tts/requests/web_socket_phoneme_timestamps_response.py +9 -0
  67. cartesia/tts/requests/web_socket_raw_output_format.py +11 -0
  68. cartesia/tts/requests/web_socket_request.py +7 -0
  69. cartesia/tts/requests/web_socket_response.py +70 -0
  70. cartesia/tts/requests/web_socket_stream_options.py +8 -0
  71. cartesia/tts/requests/web_socket_timestamps_response.py +9 -0
  72. cartesia/tts/requests/web_socket_tts_output.py +18 -0
  73. cartesia/tts/requests/web_socket_tts_request.py +25 -0
  74. cartesia/tts/requests/word_timestamps.py +10 -0
  75. cartesia/tts/socket_client.py +302 -0
  76. cartesia/tts/types/__init__.py +90 -0
  77. cartesia/tts/types/cancel_context_request.py +28 -0
  78. cartesia/tts/types/context_id.py +3 -0
  79. cartesia/tts/types/controls.py +22 -0
  80. cartesia/tts/types/emotion.py +34 -0
  81. cartesia/tts/types/flush_id.py +3 -0
  82. cartesia/tts/types/generation_request.py +71 -0
  83. cartesia/tts/types/mp_3_output_format.py +23 -0
  84. cartesia/tts/types/natural_specifier.py +5 -0
  85. cartesia/tts/types/numerical_specifier.py +3 -0
  86. cartesia/tts/types/output_format.py +58 -0
  87. cartesia/tts/types/phoneme_timestamps.py +21 -0
  88. cartesia/tts/types/raw_encoding.py +5 -0
  89. cartesia/tts/types/raw_output_format.py +22 -0
  90. cartesia/tts/types/speed.py +7 -0
  91. cartesia/tts/types/supported_language.py +7 -0
  92. cartesia/tts/types/tts_request.py +35 -0
  93. cartesia/tts/types/tts_request_embedding_specifier.py +27 -0
  94. cartesia/tts/types/tts_request_id_specifier.py +27 -0
  95. cartesia/tts/types/tts_request_voice_specifier.py +7 -0
  96. cartesia/tts/types/wav_output_format.py +17 -0
  97. cartesia/tts/types/web_socket_base_response.py +22 -0
  98. cartesia/tts/types/web_socket_chunk_response.py +22 -0
  99. cartesia/tts/types/web_socket_done_response.py +17 -0
  100. cartesia/tts/types/web_socket_error_response.py +19 -0
  101. cartesia/tts/types/web_socket_flush_done_response.py +21 -0
  102. cartesia/tts/types/web_socket_phoneme_timestamps_response.py +20 -0
  103. cartesia/tts/types/web_socket_raw_output_format.py +22 -0
  104. cartesia/tts/types/web_socket_request.py +7 -0
  105. cartesia/tts/types/web_socket_response.py +125 -0
  106. cartesia/tts/types/web_socket_stream_options.py +19 -0
  107. cartesia/tts/types/web_socket_timestamps_response.py +20 -0
  108. cartesia/tts/types/web_socket_tts_output.py +29 -0
  109. cartesia/tts/types/web_socket_tts_request.py +37 -0
  110. cartesia/tts/types/word_timestamps.py +21 -0
  111. cartesia/{_constants.py → tts/utils/constants.py} +2 -2
  112. cartesia/tts/utils/tts.py +64 -0
  113. cartesia/tts/utils/types.py +70 -0
  114. cartesia/version.py +3 -1
  115. cartesia/voice_changer/__init__.py +27 -0
  116. cartesia/voice_changer/client.py +395 -0
  117. cartesia/voice_changer/requests/__init__.py +15 -0
  118. cartesia/voice_changer/requests/streaming_response.py +38 -0
  119. cartesia/voice_changer/types/__init__.py +17 -0
  120. cartesia/voice_changer/types/output_format_container.py +5 -0
  121. cartesia/voice_changer/types/streaming_response.py +64 -0
  122. cartesia/voices/__init__.py +81 -0
  123. cartesia/voices/client.py +1218 -0
  124. cartesia/voices/requests/__init__.py +29 -0
  125. cartesia/voices/requests/create_voice_request.py +23 -0
  126. cartesia/voices/requests/embedding_response.py +8 -0
  127. cartesia/voices/requests/embedding_specifier.py +10 -0
  128. cartesia/voices/requests/get_voices_response.py +24 -0
  129. cartesia/voices/requests/id_specifier.py +10 -0
  130. cartesia/voices/requests/localize_dialect.py +11 -0
  131. cartesia/voices/requests/localize_voice_request.py +28 -0
  132. cartesia/voices/requests/mix_voice_specifier.py +7 -0
  133. cartesia/voices/requests/mix_voices_request.py +9 -0
  134. cartesia/voices/requests/update_voice_request.py +15 -0
  135. cartesia/voices/requests/voice.py +43 -0
  136. cartesia/voices/requests/voice_metadata.py +36 -0
  137. cartesia/voices/types/__init__.py +53 -0
  138. cartesia/voices/types/base_voice_id.py +5 -0
  139. cartesia/voices/types/clone_mode.py +5 -0
  140. cartesia/voices/types/create_voice_request.py +34 -0
  141. cartesia/voices/types/embedding_response.py +20 -0
  142. cartesia/voices/types/embedding_specifier.py +22 -0
  143. cartesia/voices/types/gender.py +5 -0
  144. cartesia/voices/types/gender_presentation.py +5 -0
  145. cartesia/voices/types/get_voices_response.py +34 -0
  146. cartesia/voices/types/id_specifier.py +22 -0
  147. cartesia/voices/types/localize_dialect.py +11 -0
  148. cartesia/voices/types/localize_english_dialect.py +5 -0
  149. cartesia/voices/types/localize_french_dialect.py +5 -0
  150. cartesia/voices/types/localize_portuguese_dialect.py +5 -0
  151. cartesia/voices/types/localize_spanish_dialect.py +5 -0
  152. cartesia/voices/types/localize_target_language.py +7 -0
  153. cartesia/voices/types/localize_voice_request.py +39 -0
  154. cartesia/voices/types/mix_voice_specifier.py +7 -0
  155. cartesia/voices/types/mix_voices_request.py +20 -0
  156. cartesia/voices/types/update_voice_request.py +27 -0
  157. cartesia/voices/types/voice.py +54 -0
  158. cartesia/voices/types/voice_expand_options.py +5 -0
  159. cartesia/voices/types/voice_id.py +3 -0
  160. cartesia/voices/types/voice_metadata.py +48 -0
  161. cartesia/voices/types/weight.py +3 -0
  162. cartesia-2.0.0.dist-info/METADATA +414 -0
  163. cartesia-2.0.0.dist-info/RECORD +165 -0
  164. {cartesia-1.3.1.dist-info → cartesia-2.0.0.dist-info}/WHEEL +1 -1
  165. cartesia/_async_sse.py +0 -95
  166. cartesia/_logger.py +0 -3
  167. cartesia/_sse.py +0 -143
  168. cartesia/_types.py +0 -70
  169. cartesia/_websocket.py +0 -358
  170. cartesia/async_client.py +0 -82
  171. cartesia/async_tts.py +0 -63
  172. cartesia/resource.py +0 -44
  173. cartesia/tts.py +0 -137
  174. cartesia/utils/deprecated.py +0 -55
  175. cartesia/utils/retry.py +0 -87
  176. cartesia/utils/tts.py +0 -78
  177. cartesia/voices.py +0 -208
  178. cartesia-1.3.1.dist-info/METADATA +0 -661
  179. cartesia-1.3.1.dist-info/RECORD +0 -23
  180. cartesia-1.3.1.dist-info/licenses/LICENSE.md +0 -21
  181. /cartesia/{utils/__init__.py → py.typed} +0 -0
@@ -0,0 +1,1218 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+ from ..core.client_wrapper import SyncClientWrapper
5
+ from .types.gender_presentation import GenderPresentation
6
+ from .types.voice_expand_options import VoiceExpandOptions
7
+ from ..core.request_options import RequestOptions
8
+ from ..core.pagination import SyncPager
9
+ from .types.voice import Voice
10
+ from .types.get_voices_response import GetVoicesResponse
11
+ from ..core.pydantic_utilities import parse_obj_as
12
+ from json.decoder import JSONDecodeError
13
+ from ..core.api_error import ApiError
14
+ from .. import core
15
+ from ..tts.types.supported_language import SupportedLanguage
16
+ from .types.clone_mode import CloneMode
17
+ from .types.voice_metadata import VoiceMetadata
18
+ from .types.voice_id import VoiceId
19
+ from ..core.jsonable_encoder import jsonable_encoder
20
+ from .types.localize_target_language import LocalizeTargetLanguage
21
+ from .types.gender import Gender
22
+ from .requests.localize_dialect import LocalizeDialectParams
23
+ from ..core.serialization import convert_and_respect_annotation_metadata
24
+ from .requests.mix_voice_specifier import MixVoiceSpecifierParams
25
+ from .types.embedding_response import EmbeddingResponse
26
+ from ..embedding.types.embedding import Embedding
27
+ from .types.base_voice_id import BaseVoiceId
28
+ from ..core.client_wrapper import AsyncClientWrapper
29
+ from ..core.pagination import AsyncPager
30
+
31
+ # this is used as the default value for optional parameters
32
+ OMIT = typing.cast(typing.Any, ...)
33
+
34
+
35
+ class VoicesClient:
36
+ def __init__(self, *, client_wrapper: SyncClientWrapper):
37
+ self._client_wrapper = client_wrapper
38
+
39
+ def list(
40
+ self,
41
+ *,
42
+ limit: typing.Optional[int] = None,
43
+ starting_after: typing.Optional[str] = None,
44
+ ending_before: typing.Optional[str] = None,
45
+ is_owner: typing.Optional[bool] = None,
46
+ is_starred: typing.Optional[bool] = None,
47
+ gender: typing.Optional[GenderPresentation] = None,
48
+ expand: typing.Optional[typing.Sequence[VoiceExpandOptions]] = None,
49
+ request_options: typing.Optional[RequestOptions] = None,
50
+ ) -> SyncPager[Voice]:
51
+ """
52
+ Parameters
53
+ ----------
54
+ limit : typing.Optional[int]
55
+ The number of Voices to return per page, ranging between 1 and 100.
56
+
57
+ starting_after : typing.Optional[str]
58
+ A cursor to use in pagination. `starting_after` is a Voice ID that defines your
59
+ place in the list. For example, if you make a /voices request and receive 100
60
+ objects, ending with `voice_abc123`, your subsequent call can include
61
+ `starting_after=voice_abc123` to fetch the next page of the list.
62
+
63
+ ending_before : typing.Optional[str]
64
+ A cursor to use in pagination. `ending_before` is a Voice ID that defines your
65
+ place in the list. For example, if you make a /voices request and receive 100
66
+ objects, starting with `voice_abc123`, your subsequent call can include
67
+ `ending_before=voice_abc123` to fetch the previous page of the list.
68
+
69
+ is_owner : typing.Optional[bool]
70
+ Whether to only return voices owned by the current user.
71
+
72
+ is_starred : typing.Optional[bool]
73
+ Whether to only return starred voices.
74
+
75
+ gender : typing.Optional[GenderPresentation]
76
+ The gender presentation of the voices to return.
77
+
78
+ expand : typing.Optional[typing.Sequence[VoiceExpandOptions]]
79
+ Additional fields to include in the response.
80
+
81
+ request_options : typing.Optional[RequestOptions]
82
+ Request-specific configuration.
83
+
84
+ Returns
85
+ -------
86
+ SyncPager[Voice]
87
+
88
+ Examples
89
+ --------
90
+ from cartesia import Cartesia
91
+
92
+ client = Cartesia(
93
+ api_key="YOUR_API_KEY",
94
+ )
95
+ response = client.voices.list()
96
+ for item in response:
97
+ yield item
98
+ # alternatively, you can paginate page-by-page
99
+ for page in response.iter_pages():
100
+ yield page
101
+ """
102
+ _response = self._client_wrapper.httpx_client.request(
103
+ "voices/",
104
+ method="GET",
105
+ params={
106
+ "limit": limit,
107
+ "starting_after": starting_after,
108
+ "ending_before": ending_before,
109
+ "is_owner": is_owner,
110
+ "is_starred": is_starred,
111
+ "gender": gender,
112
+ "expand[]": expand,
113
+ },
114
+ request_options=request_options,
115
+ )
116
+ try:
117
+ if 200 <= _response.status_code < 300:
118
+ _parsed_response = typing.cast(
119
+ GetVoicesResponse,
120
+ parse_obj_as(
121
+ type_=GetVoicesResponse, # type: ignore
122
+ object_=_response.json(),
123
+ ),
124
+ )
125
+ _parsed_next = _parsed_response.next_page
126
+ _has_next = _parsed_next is not None and _parsed_next != ""
127
+ _get_next = lambda: self.list(
128
+ limit=limit,
129
+ starting_after=_parsed_next,
130
+ ending_before=ending_before,
131
+ is_owner=is_owner,
132
+ is_starred=is_starred,
133
+ gender=gender,
134
+ expand=expand,
135
+ request_options=request_options,
136
+ )
137
+ _items = _parsed_response.data
138
+ return SyncPager(has_next=_has_next, items=_items, get_next=_get_next)
139
+ _response_json = _response.json()
140
+ except JSONDecodeError:
141
+ raise ApiError(status_code=_response.status_code, body=_response.text)
142
+ raise ApiError(status_code=_response.status_code, body=_response_json)
143
+
144
+ def clone(
145
+ self,
146
+ *,
147
+ clip: core.File,
148
+ name: str,
149
+ language: SupportedLanguage,
150
+ mode: CloneMode,
151
+ enhance: bool,
152
+ description: typing.Optional[str] = OMIT,
153
+ transcript: typing.Optional[str] = OMIT,
154
+ request_options: typing.Optional[RequestOptions] = None,
155
+ ) -> VoiceMetadata:
156
+ """
157
+ Clone a voice from an audio clip. This endpoint has two modes, stability and similarity.
158
+
159
+ Similarity mode clones are more similar to the source clip, but may reproduce background noise. For these, use an audio clip about 5 seconds long.
160
+
161
+ Stability mode clones are more stable, but may not sound as similar to the source clip. For these, use an audio clip 10-20 seconds long.
162
+
163
+ Parameters
164
+ ----------
165
+ clip : core.File
166
+ See core.File for more documentation
167
+
168
+ name : str
169
+ The name of the voice.
170
+
171
+
172
+ language : SupportedLanguage
173
+ The language of the voice.
174
+
175
+
176
+ mode : CloneMode
177
+ Tradeoff between similarity and stability. Similarity clones sound more like the source clip, but may reproduce background noise. Stability clones always sound like a studio recording, but may not sound as similar to the source clip.
178
+
179
+
180
+ enhance : bool
181
+ Whether to enhance the clip to improve its quality before cloning. Useful if the clip has background noise.
182
+
183
+
184
+ description : typing.Optional[str]
185
+ A description for the voice.
186
+
187
+
188
+ transcript : typing.Optional[str]
189
+ Optional transcript of the words spoken in the audio clip. Only used for similarity mode.
190
+
191
+
192
+ request_options : typing.Optional[RequestOptions]
193
+ Request-specific configuration.
194
+
195
+ Returns
196
+ -------
197
+ VoiceMetadata
198
+
199
+ Examples
200
+ --------
201
+ from cartesia import Cartesia
202
+
203
+ client = Cartesia(
204
+ api_key="YOUR_API_KEY",
205
+ )
206
+ client.voices.clone(
207
+ name="A high-stability cloned voice",
208
+ description="Copied from Cartesia docs",
209
+ mode="stability",
210
+ language="en",
211
+ enhance=True,
212
+ )
213
+ """
214
+ _response = self._client_wrapper.httpx_client.request(
215
+ "voices/clone",
216
+ method="POST",
217
+ data={
218
+ "name": name,
219
+ "description": description,
220
+ "language": language,
221
+ "mode": mode,
222
+ "enhance": enhance,
223
+ "transcript": transcript,
224
+ },
225
+ files={
226
+ "clip": clip,
227
+ },
228
+ request_options=request_options,
229
+ omit=OMIT,
230
+ )
231
+ try:
232
+ if 200 <= _response.status_code < 300:
233
+ return typing.cast(
234
+ VoiceMetadata,
235
+ parse_obj_as(
236
+ type_=VoiceMetadata, # type: ignore
237
+ object_=_response.json(),
238
+ ),
239
+ )
240
+ _response_json = _response.json()
241
+ except JSONDecodeError:
242
+ raise ApiError(status_code=_response.status_code, body=_response.text)
243
+ raise ApiError(status_code=_response.status_code, body=_response_json)
244
+
245
+ def delete(self, id: VoiceId, *, request_options: typing.Optional[RequestOptions] = None) -> None:
246
+ """
247
+ Parameters
248
+ ----------
249
+ id : VoiceId
250
+
251
+ request_options : typing.Optional[RequestOptions]
252
+ Request-specific configuration.
253
+
254
+ Returns
255
+ -------
256
+ None
257
+
258
+ Examples
259
+ --------
260
+ from cartesia import Cartesia
261
+
262
+ client = Cartesia(
263
+ api_key="YOUR_API_KEY",
264
+ )
265
+ client.voices.delete(
266
+ id="id",
267
+ )
268
+ """
269
+ _response = self._client_wrapper.httpx_client.request(
270
+ f"voices/{jsonable_encoder(id)}",
271
+ method="DELETE",
272
+ request_options=request_options,
273
+ )
274
+ try:
275
+ if 200 <= _response.status_code < 300:
276
+ return
277
+ _response_json = _response.json()
278
+ except JSONDecodeError:
279
+ raise ApiError(status_code=_response.status_code, body=_response.text)
280
+ raise ApiError(status_code=_response.status_code, body=_response_json)
281
+
282
+ def update(
283
+ self, id: VoiceId, *, name: str, description: str, request_options: typing.Optional[RequestOptions] = None
284
+ ) -> Voice:
285
+ """
286
+ Parameters
287
+ ----------
288
+ id : VoiceId
289
+
290
+ name : str
291
+ The name of the voice.
292
+
293
+ description : str
294
+ The description of the voice.
295
+
296
+ request_options : typing.Optional[RequestOptions]
297
+ Request-specific configuration.
298
+
299
+ Returns
300
+ -------
301
+ Voice
302
+
303
+ Examples
304
+ --------
305
+ from cartesia import Cartesia
306
+
307
+ client = Cartesia(
308
+ api_key="YOUR_API_KEY",
309
+ )
310
+ client.voices.update(
311
+ id="id",
312
+ name="name",
313
+ description="description",
314
+ )
315
+ """
316
+ _response = self._client_wrapper.httpx_client.request(
317
+ f"voices/{jsonable_encoder(id)}",
318
+ method="PATCH",
319
+ json={
320
+ "name": name,
321
+ "description": description,
322
+ },
323
+ request_options=request_options,
324
+ omit=OMIT,
325
+ )
326
+ try:
327
+ if 200 <= _response.status_code < 300:
328
+ return typing.cast(
329
+ Voice,
330
+ parse_obj_as(
331
+ type_=Voice, # type: ignore
332
+ object_=_response.json(),
333
+ ),
334
+ )
335
+ _response_json = _response.json()
336
+ except JSONDecodeError:
337
+ raise ApiError(status_code=_response.status_code, body=_response.text)
338
+ raise ApiError(status_code=_response.status_code, body=_response_json)
339
+
340
+ def get(self, id: VoiceId, *, request_options: typing.Optional[RequestOptions] = None) -> Voice:
341
+ """
342
+ Parameters
343
+ ----------
344
+ id : VoiceId
345
+
346
+ request_options : typing.Optional[RequestOptions]
347
+ Request-specific configuration.
348
+
349
+ Returns
350
+ -------
351
+ Voice
352
+
353
+ Examples
354
+ --------
355
+ from cartesia import Cartesia
356
+
357
+ client = Cartesia(
358
+ api_key="YOUR_API_KEY",
359
+ )
360
+ client.voices.get(
361
+ id="id",
362
+ )
363
+ """
364
+ _response = self._client_wrapper.httpx_client.request(
365
+ f"voices/{jsonable_encoder(id)}",
366
+ method="GET",
367
+ request_options=request_options,
368
+ )
369
+ try:
370
+ if 200 <= _response.status_code < 300:
371
+ return typing.cast(
372
+ Voice,
373
+ parse_obj_as(
374
+ type_=Voice, # type: ignore
375
+ object_=_response.json(),
376
+ ),
377
+ )
378
+ _response_json = _response.json()
379
+ except JSONDecodeError:
380
+ raise ApiError(status_code=_response.status_code, body=_response.text)
381
+ raise ApiError(status_code=_response.status_code, body=_response_json)
382
+
383
+ def localize(
384
+ self,
385
+ *,
386
+ voice_id: str,
387
+ name: str,
388
+ description: str,
389
+ language: LocalizeTargetLanguage,
390
+ original_speaker_gender: Gender,
391
+ dialect: typing.Optional[LocalizeDialectParams] = OMIT,
392
+ request_options: typing.Optional[RequestOptions] = None,
393
+ ) -> VoiceMetadata:
394
+ """
395
+ Create a new voice from an existing voice localized to a new language and dialect.
396
+
397
+ Parameters
398
+ ----------
399
+ voice_id : str
400
+ The ID of the voice to localize.
401
+
402
+ name : str
403
+ The name of the new localized voice.
404
+
405
+ description : str
406
+ The description of the new localized voice.
407
+
408
+ language : LocalizeTargetLanguage
409
+
410
+ original_speaker_gender : Gender
411
+
412
+ dialect : typing.Optional[LocalizeDialectParams]
413
+
414
+ request_options : typing.Optional[RequestOptions]
415
+ Request-specific configuration.
416
+
417
+ Returns
418
+ -------
419
+ VoiceMetadata
420
+
421
+ Examples
422
+ --------
423
+ from cartesia import Cartesia
424
+
425
+ client = Cartesia(
426
+ api_key="YOUR_API_KEY",
427
+ )
428
+ client.voices.localize(
429
+ voice_id="694f9389-aac1-45b6-b726-9d9369183238",
430
+ name="Sarah Peninsular Spanish",
431
+ description="Sarah Voice in Peninsular Spanish",
432
+ language="es",
433
+ original_speaker_gender="female",
434
+ dialect="pe",
435
+ )
436
+ """
437
+ _response = self._client_wrapper.httpx_client.request(
438
+ "voices/localize",
439
+ method="POST",
440
+ json={
441
+ "voice_id": voice_id,
442
+ "name": name,
443
+ "description": description,
444
+ "language": language,
445
+ "original_speaker_gender": original_speaker_gender,
446
+ "dialect": convert_and_respect_annotation_metadata(
447
+ object_=dialect, annotation=LocalizeDialectParams, direction="write"
448
+ ),
449
+ },
450
+ request_options=request_options,
451
+ omit=OMIT,
452
+ )
453
+ try:
454
+ if 200 <= _response.status_code < 300:
455
+ return typing.cast(
456
+ VoiceMetadata,
457
+ parse_obj_as(
458
+ type_=VoiceMetadata, # type: ignore
459
+ object_=_response.json(),
460
+ ),
461
+ )
462
+ _response_json = _response.json()
463
+ except JSONDecodeError:
464
+ raise ApiError(status_code=_response.status_code, body=_response.text)
465
+ raise ApiError(status_code=_response.status_code, body=_response_json)
466
+
467
+ def mix(
468
+ self,
469
+ *,
470
+ voices: typing.Sequence[MixVoiceSpecifierParams],
471
+ request_options: typing.Optional[RequestOptions] = None,
472
+ ) -> EmbeddingResponse:
473
+ """
474
+ Parameters
475
+ ----------
476
+ voices : typing.Sequence[MixVoiceSpecifierParams]
477
+
478
+ request_options : typing.Optional[RequestOptions]
479
+ Request-specific configuration.
480
+
481
+ Returns
482
+ -------
483
+ EmbeddingResponse
484
+
485
+ Examples
486
+ --------
487
+ from cartesia import Cartesia
488
+
489
+ client = Cartesia(
490
+ api_key="YOUR_API_KEY",
491
+ )
492
+ client.voices.mix(
493
+ voices=[{"id": "id", "weight": 1.1}, {"id": "id", "weight": 1.1}],
494
+ )
495
+ """
496
+ _response = self._client_wrapper.httpx_client.request(
497
+ "voices/mix",
498
+ method="POST",
499
+ json={
500
+ "voices": convert_and_respect_annotation_metadata(
501
+ object_=voices, annotation=typing.Sequence[MixVoiceSpecifierParams], direction="write"
502
+ ),
503
+ },
504
+ request_options=request_options,
505
+ omit=OMIT,
506
+ )
507
+ try:
508
+ if 200 <= _response.status_code < 300:
509
+ return typing.cast(
510
+ EmbeddingResponse,
511
+ parse_obj_as(
512
+ type_=EmbeddingResponse, # type: ignore
513
+ object_=_response.json(),
514
+ ),
515
+ )
516
+ _response_json = _response.json()
517
+ except JSONDecodeError:
518
+ raise ApiError(status_code=_response.status_code, body=_response.text)
519
+ raise ApiError(status_code=_response.status_code, body=_response_json)
520
+
521
+ def create(
522
+ self,
523
+ *,
524
+ name: str,
525
+ description: str,
526
+ embedding: Embedding,
527
+ language: typing.Optional[SupportedLanguage] = OMIT,
528
+ base_voice_id: typing.Optional[BaseVoiceId] = OMIT,
529
+ request_options: typing.Optional[RequestOptions] = None,
530
+ ) -> Voice:
531
+ """
532
+ Create voice from raw features. If you'd like to clone a voice from an audio file, please use Clone Voice instead.
533
+
534
+ Parameters
535
+ ----------
536
+ name : str
537
+ The name of the voice.
538
+
539
+ description : str
540
+ The description of the voice.
541
+
542
+ embedding : Embedding
543
+
544
+ language : typing.Optional[SupportedLanguage]
545
+
546
+ base_voice_id : typing.Optional[BaseVoiceId]
547
+
548
+ request_options : typing.Optional[RequestOptions]
549
+ Request-specific configuration.
550
+
551
+ Returns
552
+ -------
553
+ Voice
554
+
555
+ Examples
556
+ --------
557
+ from cartesia import Cartesia
558
+
559
+ client = Cartesia(
560
+ api_key="YOUR_API_KEY",
561
+ )
562
+ client.voices.create(
563
+ name="name",
564
+ description="description",
565
+ embedding=[1.1, 1.1],
566
+ )
567
+ """
568
+ _response = self._client_wrapper.httpx_client.request(
569
+ "voices/",
570
+ method="POST",
571
+ json={
572
+ "name": name,
573
+ "description": description,
574
+ "embedding": embedding,
575
+ "language": language,
576
+ "base_voice_id": base_voice_id,
577
+ },
578
+ request_options=request_options,
579
+ omit=OMIT,
580
+ )
581
+ try:
582
+ if 200 <= _response.status_code < 300:
583
+ return typing.cast(
584
+ Voice,
585
+ parse_obj_as(
586
+ type_=Voice, # type: ignore
587
+ object_=_response.json(),
588
+ ),
589
+ )
590
+ _response_json = _response.json()
591
+ except JSONDecodeError:
592
+ raise ApiError(status_code=_response.status_code, body=_response.text)
593
+ raise ApiError(status_code=_response.status_code, body=_response_json)
594
+
595
+
596
+ class AsyncVoicesClient:
597
+ def __init__(self, *, client_wrapper: AsyncClientWrapper):
598
+ self._client_wrapper = client_wrapper
599
+
600
+ async def list(
601
+ self,
602
+ *,
603
+ limit: typing.Optional[int] = None,
604
+ starting_after: typing.Optional[str] = None,
605
+ ending_before: typing.Optional[str] = None,
606
+ is_owner: typing.Optional[bool] = None,
607
+ is_starred: typing.Optional[bool] = None,
608
+ gender: typing.Optional[GenderPresentation] = None,
609
+ expand: typing.Optional[typing.Sequence[VoiceExpandOptions]] = None,
610
+ request_options: typing.Optional[RequestOptions] = None,
611
+ ) -> AsyncPager[Voice]:
612
+ """
613
+ Parameters
614
+ ----------
615
+ limit : typing.Optional[int]
616
+ The number of Voices to return per page, ranging between 1 and 100.
617
+
618
+ starting_after : typing.Optional[str]
619
+ A cursor to use in pagination. `starting_after` is a Voice ID that defines your
620
+ place in the list. For example, if you make a /voices request and receive 100
621
+ objects, ending with `voice_abc123`, your subsequent call can include
622
+ `starting_after=voice_abc123` to fetch the next page of the list.
623
+
624
+ ending_before : typing.Optional[str]
625
+ A cursor to use in pagination. `ending_before` is a Voice ID that defines your
626
+ place in the list. For example, if you make a /voices request and receive 100
627
+ objects, starting with `voice_abc123`, your subsequent call can include
628
+ `ending_before=voice_abc123` to fetch the previous page of the list.
629
+
630
+ is_owner : typing.Optional[bool]
631
+ Whether to only return voices owned by the current user.
632
+
633
+ is_starred : typing.Optional[bool]
634
+ Whether to only return starred voices.
635
+
636
+ gender : typing.Optional[GenderPresentation]
637
+ The gender presentation of the voices to return.
638
+
639
+ expand : typing.Optional[typing.Sequence[VoiceExpandOptions]]
640
+ Additional fields to include in the response.
641
+
642
+ request_options : typing.Optional[RequestOptions]
643
+ Request-specific configuration.
644
+
645
+ Returns
646
+ -------
647
+ AsyncPager[Voice]
648
+
649
+ Examples
650
+ --------
651
+ import asyncio
652
+
653
+ from cartesia import AsyncCartesia
654
+
655
+ client = AsyncCartesia(
656
+ api_key="YOUR_API_KEY",
657
+ )
658
+
659
+
660
+ async def main() -> None:
661
+ response = await client.voices.list()
662
+ async for item in response:
663
+ yield item
664
+ # alternatively, you can paginate page-by-page
665
+ async for page in response.iter_pages():
666
+ yield page
667
+
668
+
669
+ asyncio.run(main())
670
+ """
671
+ _response = await self._client_wrapper.httpx_client.request(
672
+ "voices/",
673
+ method="GET",
674
+ params={
675
+ "limit": limit,
676
+ "starting_after": starting_after,
677
+ "ending_before": ending_before,
678
+ "is_owner": is_owner,
679
+ "is_starred": is_starred,
680
+ "gender": gender,
681
+ "expand[]": expand,
682
+ },
683
+ request_options=request_options,
684
+ )
685
+ try:
686
+ if 200 <= _response.status_code < 300:
687
+ _parsed_response = typing.cast(
688
+ GetVoicesResponse,
689
+ parse_obj_as(
690
+ type_=GetVoicesResponse, # type: ignore
691
+ object_=_response.json(),
692
+ ),
693
+ )
694
+ _parsed_next = _parsed_response.next_page
695
+ _has_next = _parsed_next is not None and _parsed_next != ""
696
+ _get_next = lambda: self.list(
697
+ limit=limit,
698
+ starting_after=_parsed_next,
699
+ ending_before=ending_before,
700
+ is_owner=is_owner,
701
+ is_starred=is_starred,
702
+ gender=gender,
703
+ expand=expand,
704
+ request_options=request_options,
705
+ )
706
+ _items = _parsed_response.data
707
+ return AsyncPager(has_next=_has_next, items=_items, get_next=_get_next)
708
+ _response_json = _response.json()
709
+ except JSONDecodeError:
710
+ raise ApiError(status_code=_response.status_code, body=_response.text)
711
+ raise ApiError(status_code=_response.status_code, body=_response_json)
712
+
713
+ async def clone(
714
+ self,
715
+ *,
716
+ clip: core.File,
717
+ name: str,
718
+ language: SupportedLanguage,
719
+ mode: CloneMode,
720
+ enhance: bool,
721
+ description: typing.Optional[str] = OMIT,
722
+ transcript: typing.Optional[str] = OMIT,
723
+ request_options: typing.Optional[RequestOptions] = None,
724
+ ) -> VoiceMetadata:
725
+ """
726
+ Clone a voice from an audio clip. This endpoint has two modes, stability and similarity.
727
+
728
+ Similarity mode clones are more similar to the source clip, but may reproduce background noise. For these, use an audio clip about 5 seconds long.
729
+
730
+ Stability mode clones are more stable, but may not sound as similar to the source clip. For these, use an audio clip 10-20 seconds long.
731
+
732
+ Parameters
733
+ ----------
734
+ clip : core.File
735
+ See core.File for more documentation
736
+
737
+ name : str
738
+ The name of the voice.
739
+
740
+
741
+ language : SupportedLanguage
742
+ The language of the voice.
743
+
744
+
745
+ mode : CloneMode
746
+ Tradeoff between similarity and stability. Similarity clones sound more like the source clip, but may reproduce background noise. Stability clones always sound like a studio recording, but may not sound as similar to the source clip.
747
+
748
+
749
+ enhance : bool
750
+ Whether to enhance the clip to improve its quality before cloning. Useful if the clip has background noise.
751
+
752
+
753
+ description : typing.Optional[str]
754
+ A description for the voice.
755
+
756
+
757
+ transcript : typing.Optional[str]
758
+ Optional transcript of the words spoken in the audio clip. Only used for similarity mode.
759
+
760
+
761
+ request_options : typing.Optional[RequestOptions]
762
+ Request-specific configuration.
763
+
764
+ Returns
765
+ -------
766
+ VoiceMetadata
767
+
768
+ Examples
769
+ --------
770
+ import asyncio
771
+
772
+ from cartesia import AsyncCartesia
773
+
774
+ client = AsyncCartesia(
775
+ api_key="YOUR_API_KEY",
776
+ )
777
+
778
+
779
+ async def main() -> None:
780
+ await client.voices.clone(
781
+ name="A high-stability cloned voice",
782
+ description="Copied from Cartesia docs",
783
+ mode="stability",
784
+ language="en",
785
+ enhance=True,
786
+ )
787
+
788
+
789
+ asyncio.run(main())
790
+ """
791
+ _response = await self._client_wrapper.httpx_client.request(
792
+ "voices/clone",
793
+ method="POST",
794
+ data={
795
+ "name": name,
796
+ "description": description,
797
+ "language": language,
798
+ "mode": mode,
799
+ "enhance": enhance,
800
+ "transcript": transcript,
801
+ },
802
+ files={
803
+ "clip": clip,
804
+ },
805
+ request_options=request_options,
806
+ omit=OMIT,
807
+ )
808
+ try:
809
+ if 200 <= _response.status_code < 300:
810
+ return typing.cast(
811
+ VoiceMetadata,
812
+ parse_obj_as(
813
+ type_=VoiceMetadata, # type: ignore
814
+ object_=_response.json(),
815
+ ),
816
+ )
817
+ _response_json = _response.json()
818
+ except JSONDecodeError:
819
+ raise ApiError(status_code=_response.status_code, body=_response.text)
820
+ raise ApiError(status_code=_response.status_code, body=_response_json)
821
+
822
+ async def delete(self, id: VoiceId, *, request_options: typing.Optional[RequestOptions] = None) -> None:
823
+ """
824
+ Parameters
825
+ ----------
826
+ id : VoiceId
827
+
828
+ request_options : typing.Optional[RequestOptions]
829
+ Request-specific configuration.
830
+
831
+ Returns
832
+ -------
833
+ None
834
+
835
+ Examples
836
+ --------
837
+ import asyncio
838
+
839
+ from cartesia import AsyncCartesia
840
+
841
+ client = AsyncCartesia(
842
+ api_key="YOUR_API_KEY",
843
+ )
844
+
845
+
846
+ async def main() -> None:
847
+ await client.voices.delete(
848
+ id="id",
849
+ )
850
+
851
+
852
+ asyncio.run(main())
853
+ """
854
+ _response = await self._client_wrapper.httpx_client.request(
855
+ f"voices/{jsonable_encoder(id)}",
856
+ method="DELETE",
857
+ request_options=request_options,
858
+ )
859
+ try:
860
+ if 200 <= _response.status_code < 300:
861
+ return
862
+ _response_json = _response.json()
863
+ except JSONDecodeError:
864
+ raise ApiError(status_code=_response.status_code, body=_response.text)
865
+ raise ApiError(status_code=_response.status_code, body=_response_json)
866
+
867
+ async def update(
868
+ self, id: VoiceId, *, name: str, description: str, request_options: typing.Optional[RequestOptions] = None
869
+ ) -> Voice:
870
+ """
871
+ Parameters
872
+ ----------
873
+ id : VoiceId
874
+
875
+ name : str
876
+ The name of the voice.
877
+
878
+ description : str
879
+ The description of the voice.
880
+
881
+ request_options : typing.Optional[RequestOptions]
882
+ Request-specific configuration.
883
+
884
+ Returns
885
+ -------
886
+ Voice
887
+
888
+ Examples
889
+ --------
890
+ import asyncio
891
+
892
+ from cartesia import AsyncCartesia
893
+
894
+ client = AsyncCartesia(
895
+ api_key="YOUR_API_KEY",
896
+ )
897
+
898
+
899
+ async def main() -> None:
900
+ await client.voices.update(
901
+ id="id",
902
+ name="name",
903
+ description="description",
904
+ )
905
+
906
+
907
+ asyncio.run(main())
908
+ """
909
+ _response = await self._client_wrapper.httpx_client.request(
910
+ f"voices/{jsonable_encoder(id)}",
911
+ method="PATCH",
912
+ json={
913
+ "name": name,
914
+ "description": description,
915
+ },
916
+ request_options=request_options,
917
+ omit=OMIT,
918
+ )
919
+ try:
920
+ if 200 <= _response.status_code < 300:
921
+ return typing.cast(
922
+ Voice,
923
+ parse_obj_as(
924
+ type_=Voice, # type: ignore
925
+ object_=_response.json(),
926
+ ),
927
+ )
928
+ _response_json = _response.json()
929
+ except JSONDecodeError:
930
+ raise ApiError(status_code=_response.status_code, body=_response.text)
931
+ raise ApiError(status_code=_response.status_code, body=_response_json)
932
+
933
+ async def get(self, id: VoiceId, *, request_options: typing.Optional[RequestOptions] = None) -> Voice:
934
+ """
935
+ Parameters
936
+ ----------
937
+ id : VoiceId
938
+
939
+ request_options : typing.Optional[RequestOptions]
940
+ Request-specific configuration.
941
+
942
+ Returns
943
+ -------
944
+ Voice
945
+
946
+ Examples
947
+ --------
948
+ import asyncio
949
+
950
+ from cartesia import AsyncCartesia
951
+
952
+ client = AsyncCartesia(
953
+ api_key="YOUR_API_KEY",
954
+ )
955
+
956
+
957
+ async def main() -> None:
958
+ await client.voices.get(
959
+ id="id",
960
+ )
961
+
962
+
963
+ asyncio.run(main())
964
+ """
965
+ _response = await self._client_wrapper.httpx_client.request(
966
+ f"voices/{jsonable_encoder(id)}",
967
+ method="GET",
968
+ request_options=request_options,
969
+ )
970
+ try:
971
+ if 200 <= _response.status_code < 300:
972
+ return typing.cast(
973
+ Voice,
974
+ parse_obj_as(
975
+ type_=Voice, # type: ignore
976
+ object_=_response.json(),
977
+ ),
978
+ )
979
+ _response_json = _response.json()
980
+ except JSONDecodeError:
981
+ raise ApiError(status_code=_response.status_code, body=_response.text)
982
+ raise ApiError(status_code=_response.status_code, body=_response_json)
983
+
984
+ async def localize(
985
+ self,
986
+ *,
987
+ voice_id: str,
988
+ name: str,
989
+ description: str,
990
+ language: LocalizeTargetLanguage,
991
+ original_speaker_gender: Gender,
992
+ dialect: typing.Optional[LocalizeDialectParams] = OMIT,
993
+ request_options: typing.Optional[RequestOptions] = None,
994
+ ) -> VoiceMetadata:
995
+ """
996
+ Create a new voice from an existing voice localized to a new language and dialect.
997
+
998
+ Parameters
999
+ ----------
1000
+ voice_id : str
1001
+ The ID of the voice to localize.
1002
+
1003
+ name : str
1004
+ The name of the new localized voice.
1005
+
1006
+ description : str
1007
+ The description of the new localized voice.
1008
+
1009
+ language : LocalizeTargetLanguage
1010
+
1011
+ original_speaker_gender : Gender
1012
+
1013
+ dialect : typing.Optional[LocalizeDialectParams]
1014
+
1015
+ request_options : typing.Optional[RequestOptions]
1016
+ Request-specific configuration.
1017
+
1018
+ Returns
1019
+ -------
1020
+ VoiceMetadata
1021
+
1022
+ Examples
1023
+ --------
1024
+ import asyncio
1025
+
1026
+ from cartesia import AsyncCartesia
1027
+
1028
+ client = AsyncCartesia(
1029
+ api_key="YOUR_API_KEY",
1030
+ )
1031
+
1032
+
1033
+ async def main() -> None:
1034
+ await client.voices.localize(
1035
+ voice_id="694f9389-aac1-45b6-b726-9d9369183238",
1036
+ name="Sarah Peninsular Spanish",
1037
+ description="Sarah Voice in Peninsular Spanish",
1038
+ language="es",
1039
+ original_speaker_gender="female",
1040
+ dialect="pe",
1041
+ )
1042
+
1043
+
1044
+ asyncio.run(main())
1045
+ """
1046
+ _response = await self._client_wrapper.httpx_client.request(
1047
+ "voices/localize",
1048
+ method="POST",
1049
+ json={
1050
+ "voice_id": voice_id,
1051
+ "name": name,
1052
+ "description": description,
1053
+ "language": language,
1054
+ "original_speaker_gender": original_speaker_gender,
1055
+ "dialect": convert_and_respect_annotation_metadata(
1056
+ object_=dialect, annotation=LocalizeDialectParams, direction="write"
1057
+ ),
1058
+ },
1059
+ request_options=request_options,
1060
+ omit=OMIT,
1061
+ )
1062
+ try:
1063
+ if 200 <= _response.status_code < 300:
1064
+ return typing.cast(
1065
+ VoiceMetadata,
1066
+ parse_obj_as(
1067
+ type_=VoiceMetadata, # type: ignore
1068
+ object_=_response.json(),
1069
+ ),
1070
+ )
1071
+ _response_json = _response.json()
1072
+ except JSONDecodeError:
1073
+ raise ApiError(status_code=_response.status_code, body=_response.text)
1074
+ raise ApiError(status_code=_response.status_code, body=_response_json)
1075
+
1076
+ async def mix(
1077
+ self,
1078
+ *,
1079
+ voices: typing.Sequence[MixVoiceSpecifierParams],
1080
+ request_options: typing.Optional[RequestOptions] = None,
1081
+ ) -> EmbeddingResponse:
1082
+ """
1083
+ Parameters
1084
+ ----------
1085
+ voices : typing.Sequence[MixVoiceSpecifierParams]
1086
+
1087
+ request_options : typing.Optional[RequestOptions]
1088
+ Request-specific configuration.
1089
+
1090
+ Returns
1091
+ -------
1092
+ EmbeddingResponse
1093
+
1094
+ Examples
1095
+ --------
1096
+ import asyncio
1097
+
1098
+ from cartesia import AsyncCartesia
1099
+
1100
+ client = AsyncCartesia(
1101
+ api_key="YOUR_API_KEY",
1102
+ )
1103
+
1104
+
1105
+ async def main() -> None:
1106
+ await client.voices.mix(
1107
+ voices=[{"id": "id", "weight": 1.1}, {"id": "id", "weight": 1.1}],
1108
+ )
1109
+
1110
+
1111
+ asyncio.run(main())
1112
+ """
1113
+ _response = await self._client_wrapper.httpx_client.request(
1114
+ "voices/mix",
1115
+ method="POST",
1116
+ json={
1117
+ "voices": convert_and_respect_annotation_metadata(
1118
+ object_=voices, annotation=typing.Sequence[MixVoiceSpecifierParams], direction="write"
1119
+ ),
1120
+ },
1121
+ request_options=request_options,
1122
+ omit=OMIT,
1123
+ )
1124
+ try:
1125
+ if 200 <= _response.status_code < 300:
1126
+ return typing.cast(
1127
+ EmbeddingResponse,
1128
+ parse_obj_as(
1129
+ type_=EmbeddingResponse, # type: ignore
1130
+ object_=_response.json(),
1131
+ ),
1132
+ )
1133
+ _response_json = _response.json()
1134
+ except JSONDecodeError:
1135
+ raise ApiError(status_code=_response.status_code, body=_response.text)
1136
+ raise ApiError(status_code=_response.status_code, body=_response_json)
1137
+
1138
+ async def create(
1139
+ self,
1140
+ *,
1141
+ name: str,
1142
+ description: str,
1143
+ embedding: Embedding,
1144
+ language: typing.Optional[SupportedLanguage] = OMIT,
1145
+ base_voice_id: typing.Optional[BaseVoiceId] = OMIT,
1146
+ request_options: typing.Optional[RequestOptions] = None,
1147
+ ) -> Voice:
1148
+ """
1149
+ Create voice from raw features. If you'd like to clone a voice from an audio file, please use Clone Voice instead.
1150
+
1151
+ Parameters
1152
+ ----------
1153
+ name : str
1154
+ The name of the voice.
1155
+
1156
+ description : str
1157
+ The description of the voice.
1158
+
1159
+ embedding : Embedding
1160
+
1161
+ language : typing.Optional[SupportedLanguage]
1162
+
1163
+ base_voice_id : typing.Optional[BaseVoiceId]
1164
+
1165
+ request_options : typing.Optional[RequestOptions]
1166
+ Request-specific configuration.
1167
+
1168
+ Returns
1169
+ -------
1170
+ Voice
1171
+
1172
+ Examples
1173
+ --------
1174
+ import asyncio
1175
+
1176
+ from cartesia import AsyncCartesia
1177
+
1178
+ client = AsyncCartesia(
1179
+ api_key="YOUR_API_KEY",
1180
+ )
1181
+
1182
+
1183
+ async def main() -> None:
1184
+ await client.voices.create(
1185
+ name="name",
1186
+ description="description",
1187
+ embedding=[1.1, 1.1],
1188
+ )
1189
+
1190
+
1191
+ asyncio.run(main())
1192
+ """
1193
+ _response = await self._client_wrapper.httpx_client.request(
1194
+ "voices/",
1195
+ method="POST",
1196
+ json={
1197
+ "name": name,
1198
+ "description": description,
1199
+ "embedding": embedding,
1200
+ "language": language,
1201
+ "base_voice_id": base_voice_id,
1202
+ },
1203
+ request_options=request_options,
1204
+ omit=OMIT,
1205
+ )
1206
+ try:
1207
+ if 200 <= _response.status_code < 300:
1208
+ return typing.cast(
1209
+ Voice,
1210
+ parse_obj_as(
1211
+ type_=Voice, # type: ignore
1212
+ object_=_response.json(),
1213
+ ),
1214
+ )
1215
+ _response_json = _response.json()
1216
+ except JSONDecodeError:
1217
+ raise ApiError(status_code=_response.status_code, body=_response.text)
1218
+ raise ApiError(status_code=_response.status_code, body=_response_json)