cartesia 1.4.0__py3-none-any.whl → 2.0.0a2__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 (176) hide show
  1. cartesia/__init__.py +292 -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 +160 -0
  9. cartesia/client.py +163 -40
  10. cartesia/core/__init__.py +47 -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/pydantic_utilities.py +296 -0
  18. cartesia/core/query_encoder.py +58 -0
  19. cartesia/core/remove_none_from_dict.py +11 -0
  20. cartesia/core/request_options.py +35 -0
  21. cartesia/core/serialization.py +272 -0
  22. cartesia/datasets/__init__.py +24 -0
  23. cartesia/datasets/client.py +392 -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} +159 -84
  45. cartesia/tts/_websocket.py +430 -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 +53 -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 +8 -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 +69 -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 +24 -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 +29 -0
  81. cartesia/tts/types/flush_id.py +3 -0
  82. cartesia/tts/types/generation_request.py +66 -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 +20 -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 +124 -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 +27 -0
  109. cartesia/tts/types/web_socket_tts_request.py +36 -0
  110. cartesia/tts/types/word_timestamps.py +21 -0
  111. cartesia/tts/utils/tts.py +64 -0
  112. cartesia/tts/utils/types.py +70 -0
  113. cartesia/version.py +3 -1
  114. cartesia/voice_changer/__init__.py +27 -0
  115. cartesia/voice_changer/client.py +395 -0
  116. cartesia/voice_changer/requests/__init__.py +15 -0
  117. cartesia/voice_changer/requests/streaming_response.py +36 -0
  118. cartesia/voice_changer/types/__init__.py +17 -0
  119. cartesia/voice_changer/types/output_format_container.py +5 -0
  120. cartesia/voice_changer/types/streaming_response.py +62 -0
  121. cartesia/voices/__init__.py +71 -0
  122. cartesia/voices/client.py +1053 -0
  123. cartesia/voices/requests/__init__.py +27 -0
  124. cartesia/voices/requests/create_voice_request.py +23 -0
  125. cartesia/voices/requests/embedding_response.py +8 -0
  126. cartesia/voices/requests/embedding_specifier.py +10 -0
  127. cartesia/voices/requests/id_specifier.py +10 -0
  128. cartesia/voices/requests/localize_dialect.py +8 -0
  129. cartesia/voices/requests/localize_voice_request.py +15 -0
  130. cartesia/voices/requests/mix_voice_specifier.py +7 -0
  131. cartesia/voices/requests/mix_voices_request.py +9 -0
  132. cartesia/voices/requests/update_voice_request.py +15 -0
  133. cartesia/voices/requests/voice.py +39 -0
  134. cartesia/voices/requests/voice_metadata.py +36 -0
  135. cartesia/voices/types/__init__.py +45 -0
  136. cartesia/voices/types/base_voice_id.py +5 -0
  137. cartesia/voices/types/clone_mode.py +5 -0
  138. cartesia/voices/types/create_voice_request.py +34 -0
  139. cartesia/voices/types/embedding_response.py +20 -0
  140. cartesia/voices/types/embedding_specifier.py +22 -0
  141. cartesia/voices/types/gender.py +5 -0
  142. cartesia/voices/types/id_specifier.py +22 -0
  143. cartesia/voices/types/localize_dialect.py +8 -0
  144. cartesia/voices/types/localize_english_dialect.py +5 -0
  145. cartesia/voices/types/localize_portuguese_dialect.py +5 -0
  146. cartesia/voices/types/localize_spanish_dialect.py +5 -0
  147. cartesia/voices/types/localize_target_language.py +7 -0
  148. cartesia/voices/types/localize_voice_request.py +26 -0
  149. cartesia/voices/types/mix_voice_specifier.py +7 -0
  150. cartesia/voices/types/mix_voices_request.py +20 -0
  151. cartesia/voices/types/update_voice_request.py +27 -0
  152. cartesia/voices/types/voice.py +50 -0
  153. cartesia/voices/types/voice_id.py +3 -0
  154. cartesia/voices/types/voice_metadata.py +48 -0
  155. cartesia/voices/types/weight.py +3 -0
  156. cartesia-2.0.0a2.dist-info/METADATA +307 -0
  157. cartesia-2.0.0a2.dist-info/RECORD +160 -0
  158. {cartesia-1.4.0.dist-info → cartesia-2.0.0a2.dist-info}/WHEEL +1 -1
  159. cartesia/_async_sse.py +0 -95
  160. cartesia/_logger.py +0 -3
  161. cartesia/_sse.py +0 -143
  162. cartesia/_types.py +0 -70
  163. cartesia/_websocket.py +0 -358
  164. cartesia/async_client.py +0 -82
  165. cartesia/async_tts.py +0 -176
  166. cartesia/resource.py +0 -44
  167. cartesia/tts.py +0 -292
  168. cartesia/utils/deprecated.py +0 -55
  169. cartesia/utils/retry.py +0 -87
  170. cartesia/utils/tts.py +0 -78
  171. cartesia/voices.py +0 -204
  172. cartesia-1.4.0.dist-info/METADATA +0 -663
  173. cartesia-1.4.0.dist-info/RECORD +0 -23
  174. cartesia-1.4.0.dist-info/licenses/LICENSE.md +0 -21
  175. /cartesia/{utils/__init__.py → py.typed} +0 -0
  176. /cartesia/{_constants.py → tts/utils/constants.py} +0 -0
@@ -0,0 +1,1053 @@
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 ..core.request_options import RequestOptions
6
+ from .types.voice import Voice
7
+ from ..core.pydantic_utilities import parse_obj_as
8
+ from json.decoder import JSONDecodeError
9
+ from ..core.api_error import ApiError
10
+ from .. import core
11
+ from ..tts.types.supported_language import SupportedLanguage
12
+ from .types.clone_mode import CloneMode
13
+ from .types.voice_metadata import VoiceMetadata
14
+ from .types.voice_id import VoiceId
15
+ from ..core.jsonable_encoder import jsonable_encoder
16
+ from ..embedding.types.embedding import Embedding
17
+ from .types.localize_target_language import LocalizeTargetLanguage
18
+ from .types.gender import Gender
19
+ from .requests.localize_dialect import LocalizeDialectParams
20
+ from .types.embedding_response import EmbeddingResponse
21
+ from ..core.serialization import convert_and_respect_annotation_metadata
22
+ from .requests.mix_voice_specifier import MixVoiceSpecifierParams
23
+ from .types.base_voice_id import BaseVoiceId
24
+ from ..core.client_wrapper import AsyncClientWrapper
25
+
26
+ # this is used as the default value for optional parameters
27
+ OMIT = typing.cast(typing.Any, ...)
28
+
29
+
30
+ class VoicesClient:
31
+ def __init__(self, *, client_wrapper: SyncClientWrapper):
32
+ self._client_wrapper = client_wrapper
33
+
34
+ def list(self, *, request_options: typing.Optional[RequestOptions] = None) -> typing.List[Voice]:
35
+ """
36
+ Parameters
37
+ ----------
38
+ request_options : typing.Optional[RequestOptions]
39
+ Request-specific configuration.
40
+
41
+ Returns
42
+ -------
43
+ typing.List[Voice]
44
+
45
+ Examples
46
+ --------
47
+ from cartesia import Cartesia
48
+
49
+ client = Cartesia(
50
+ api_key="YOUR_API_KEY",
51
+ )
52
+ client.voices.list()
53
+ """
54
+ _response = self._client_wrapper.httpx_client.request(
55
+ "voices/",
56
+ method="GET",
57
+ request_options=request_options,
58
+ )
59
+ try:
60
+ if 200 <= _response.status_code < 300:
61
+ return typing.cast(
62
+ typing.List[Voice],
63
+ parse_obj_as(
64
+ type_=typing.List[Voice], # type: ignore
65
+ object_=_response.json(),
66
+ ),
67
+ )
68
+ _response_json = _response.json()
69
+ except JSONDecodeError:
70
+ raise ApiError(status_code=_response.status_code, body=_response.text)
71
+ raise ApiError(status_code=_response.status_code, body=_response_json)
72
+
73
+ def clone(
74
+ self,
75
+ *,
76
+ clip: core.File,
77
+ name: str,
78
+ language: SupportedLanguage,
79
+ mode: CloneMode,
80
+ enhance: bool,
81
+ description: typing.Optional[str] = OMIT,
82
+ transcript: typing.Optional[str] = OMIT,
83
+ request_options: typing.Optional[RequestOptions] = None,
84
+ ) -> VoiceMetadata:
85
+ """
86
+ Clone a voice from an audio clip. This endpoint has two modes, stability and similarity.
87
+
88
+ 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.
89
+
90
+ 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.
91
+
92
+ Parameters
93
+ ----------
94
+ clip : core.File
95
+ See core.File for more documentation
96
+
97
+ name : str
98
+ The name of the voice.
99
+
100
+
101
+ language : SupportedLanguage
102
+ The language of the voice.
103
+
104
+
105
+ mode : CloneMode
106
+ 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.
107
+
108
+
109
+ enhance : bool
110
+ Whether to enhance the clip to improve its quality before cloning. Useful if the clip has background noise.
111
+
112
+
113
+ description : typing.Optional[str]
114
+ A description for the voice.
115
+
116
+
117
+ transcript : typing.Optional[str]
118
+ Optional transcript of the words spoken in the audio clip. Only used for similarity mode.
119
+
120
+
121
+ request_options : typing.Optional[RequestOptions]
122
+ Request-specific configuration.
123
+
124
+ Returns
125
+ -------
126
+ VoiceMetadata
127
+
128
+ Examples
129
+ --------
130
+ from cartesia import Cartesia
131
+
132
+ client = Cartesia(
133
+ api_key="YOUR_API_KEY",
134
+ )
135
+ client.voices.clone(
136
+ name="A high-stability cloned voice",
137
+ description="Copied from Cartesia docs",
138
+ mode="stability",
139
+ language="en",
140
+ enhance=True,
141
+ )
142
+ """
143
+ _response = self._client_wrapper.httpx_client.request(
144
+ "voices/clone",
145
+ method="POST",
146
+ data={
147
+ "name": name,
148
+ "description": description,
149
+ "language": language,
150
+ "mode": mode,
151
+ "enhance": enhance,
152
+ "transcript": transcript,
153
+ },
154
+ files={
155
+ "clip": clip,
156
+ },
157
+ request_options=request_options,
158
+ omit=OMIT,
159
+ )
160
+ try:
161
+ if 200 <= _response.status_code < 300:
162
+ return typing.cast(
163
+ VoiceMetadata,
164
+ parse_obj_as(
165
+ type_=VoiceMetadata, # type: ignore
166
+ object_=_response.json(),
167
+ ),
168
+ )
169
+ _response_json = _response.json()
170
+ except JSONDecodeError:
171
+ raise ApiError(status_code=_response.status_code, body=_response.text)
172
+ raise ApiError(status_code=_response.status_code, body=_response_json)
173
+
174
+ def delete(self, id: VoiceId, *, request_options: typing.Optional[RequestOptions] = None) -> None:
175
+ """
176
+ Parameters
177
+ ----------
178
+ id : VoiceId
179
+
180
+ request_options : typing.Optional[RequestOptions]
181
+ Request-specific configuration.
182
+
183
+ Returns
184
+ -------
185
+ None
186
+
187
+ Examples
188
+ --------
189
+ from cartesia import Cartesia
190
+
191
+ client = Cartesia(
192
+ api_key="YOUR_API_KEY",
193
+ )
194
+ client.voices.delete(
195
+ id="id",
196
+ )
197
+ """
198
+ _response = self._client_wrapper.httpx_client.request(
199
+ f"voices/{jsonable_encoder(id)}",
200
+ method="DELETE",
201
+ request_options=request_options,
202
+ )
203
+ try:
204
+ if 200 <= _response.status_code < 300:
205
+ return
206
+ _response_json = _response.json()
207
+ except JSONDecodeError:
208
+ raise ApiError(status_code=_response.status_code, body=_response.text)
209
+ raise ApiError(status_code=_response.status_code, body=_response_json)
210
+
211
+ def update(
212
+ self, id: VoiceId, *, name: str, description: str, request_options: typing.Optional[RequestOptions] = None
213
+ ) -> Voice:
214
+ """
215
+ Parameters
216
+ ----------
217
+ id : VoiceId
218
+
219
+ name : str
220
+ The name of the voice.
221
+
222
+ description : str
223
+ The description of the voice.
224
+
225
+ request_options : typing.Optional[RequestOptions]
226
+ Request-specific configuration.
227
+
228
+ Returns
229
+ -------
230
+ Voice
231
+
232
+ Examples
233
+ --------
234
+ from cartesia import Cartesia
235
+
236
+ client = Cartesia(
237
+ api_key="YOUR_API_KEY",
238
+ )
239
+ client.voices.update(
240
+ id="id",
241
+ name="name",
242
+ description="description",
243
+ )
244
+ """
245
+ _response = self._client_wrapper.httpx_client.request(
246
+ f"voices/{jsonable_encoder(id)}",
247
+ method="PATCH",
248
+ json={
249
+ "name": name,
250
+ "description": description,
251
+ },
252
+ request_options=request_options,
253
+ omit=OMIT,
254
+ )
255
+ try:
256
+ if 200 <= _response.status_code < 300:
257
+ return typing.cast(
258
+ Voice,
259
+ parse_obj_as(
260
+ type_=Voice, # type: ignore
261
+ object_=_response.json(),
262
+ ),
263
+ )
264
+ _response_json = _response.json()
265
+ except JSONDecodeError:
266
+ raise ApiError(status_code=_response.status_code, body=_response.text)
267
+ raise ApiError(status_code=_response.status_code, body=_response_json)
268
+
269
+ def get(self, id: VoiceId, *, request_options: typing.Optional[RequestOptions] = None) -> Voice:
270
+ """
271
+ Parameters
272
+ ----------
273
+ id : VoiceId
274
+
275
+ request_options : typing.Optional[RequestOptions]
276
+ Request-specific configuration.
277
+
278
+ Returns
279
+ -------
280
+ Voice
281
+
282
+ Examples
283
+ --------
284
+ from cartesia import Cartesia
285
+
286
+ client = Cartesia(
287
+ api_key="YOUR_API_KEY",
288
+ )
289
+ client.voices.get(
290
+ id="id",
291
+ )
292
+ """
293
+ _response = self._client_wrapper.httpx_client.request(
294
+ f"voices/{jsonable_encoder(id)}",
295
+ method="GET",
296
+ request_options=request_options,
297
+ )
298
+ try:
299
+ if 200 <= _response.status_code < 300:
300
+ return typing.cast(
301
+ Voice,
302
+ parse_obj_as(
303
+ type_=Voice, # type: ignore
304
+ object_=_response.json(),
305
+ ),
306
+ )
307
+ _response_json = _response.json()
308
+ except JSONDecodeError:
309
+ raise ApiError(status_code=_response.status_code, body=_response.text)
310
+ raise ApiError(status_code=_response.status_code, body=_response_json)
311
+
312
+ def localize(
313
+ self,
314
+ *,
315
+ embedding: Embedding,
316
+ language: LocalizeTargetLanguage,
317
+ original_speaker_gender: Gender,
318
+ dialect: typing.Optional[LocalizeDialectParams] = OMIT,
319
+ request_options: typing.Optional[RequestOptions] = None,
320
+ ) -> EmbeddingResponse:
321
+ """
322
+ Parameters
323
+ ----------
324
+ embedding : Embedding
325
+
326
+ language : LocalizeTargetLanguage
327
+
328
+ original_speaker_gender : Gender
329
+
330
+ dialect : typing.Optional[LocalizeDialectParams]
331
+
332
+ request_options : typing.Optional[RequestOptions]
333
+ Request-specific configuration.
334
+
335
+ Returns
336
+ -------
337
+ EmbeddingResponse
338
+
339
+ Examples
340
+ --------
341
+ from cartesia import Cartesia
342
+
343
+ client = Cartesia(
344
+ api_key="YOUR_API_KEY",
345
+ )
346
+ client.voices.localize(
347
+ embedding=[1.1, 1.1],
348
+ language="en",
349
+ original_speaker_gender="male",
350
+ )
351
+ """
352
+ _response = self._client_wrapper.httpx_client.request(
353
+ "voices/localize",
354
+ method="POST",
355
+ json={
356
+ "embedding": embedding,
357
+ "language": language,
358
+ "original_speaker_gender": original_speaker_gender,
359
+ "dialect": convert_and_respect_annotation_metadata(
360
+ object_=dialect, annotation=LocalizeDialectParams, direction="write"
361
+ ),
362
+ },
363
+ request_options=request_options,
364
+ omit=OMIT,
365
+ )
366
+ try:
367
+ if 200 <= _response.status_code < 300:
368
+ return typing.cast(
369
+ EmbeddingResponse,
370
+ parse_obj_as(
371
+ type_=EmbeddingResponse, # type: ignore
372
+ object_=_response.json(),
373
+ ),
374
+ )
375
+ _response_json = _response.json()
376
+ except JSONDecodeError:
377
+ raise ApiError(status_code=_response.status_code, body=_response.text)
378
+ raise ApiError(status_code=_response.status_code, body=_response_json)
379
+
380
+ def mix(
381
+ self,
382
+ *,
383
+ voices: typing.Sequence[MixVoiceSpecifierParams],
384
+ request_options: typing.Optional[RequestOptions] = None,
385
+ ) -> EmbeddingResponse:
386
+ """
387
+ Parameters
388
+ ----------
389
+ voices : typing.Sequence[MixVoiceSpecifierParams]
390
+
391
+ request_options : typing.Optional[RequestOptions]
392
+ Request-specific configuration.
393
+
394
+ Returns
395
+ -------
396
+ EmbeddingResponse
397
+
398
+ Examples
399
+ --------
400
+ from cartesia import Cartesia
401
+
402
+ client = Cartesia(
403
+ api_key="YOUR_API_KEY",
404
+ )
405
+ client.voices.mix(
406
+ voices=[{"id": "id", "weight": 1.1}, {"id": "id", "weight": 1.1}],
407
+ )
408
+ """
409
+ _response = self._client_wrapper.httpx_client.request(
410
+ "voices/mix",
411
+ method="POST",
412
+ json={
413
+ "voices": convert_and_respect_annotation_metadata(
414
+ object_=voices, annotation=typing.Sequence[MixVoiceSpecifierParams], direction="write"
415
+ ),
416
+ },
417
+ request_options=request_options,
418
+ omit=OMIT,
419
+ )
420
+ try:
421
+ if 200 <= _response.status_code < 300:
422
+ return typing.cast(
423
+ EmbeddingResponse,
424
+ parse_obj_as(
425
+ type_=EmbeddingResponse, # type: ignore
426
+ object_=_response.json(),
427
+ ),
428
+ )
429
+ _response_json = _response.json()
430
+ except JSONDecodeError:
431
+ raise ApiError(status_code=_response.status_code, body=_response.text)
432
+ raise ApiError(status_code=_response.status_code, body=_response_json)
433
+
434
+ def create(
435
+ self,
436
+ *,
437
+ name: str,
438
+ description: str,
439
+ embedding: Embedding,
440
+ language: typing.Optional[SupportedLanguage] = OMIT,
441
+ base_voice_id: typing.Optional[BaseVoiceId] = OMIT,
442
+ request_options: typing.Optional[RequestOptions] = None,
443
+ ) -> Voice:
444
+ """
445
+ Create voice from raw features. If you'd like to clone a voice from an audio file, please use Clone Voice instead.
446
+
447
+ Parameters
448
+ ----------
449
+ name : str
450
+ The name of the voice.
451
+
452
+ description : str
453
+ The description of the voice.
454
+
455
+ embedding : Embedding
456
+
457
+ language : typing.Optional[SupportedLanguage]
458
+
459
+ base_voice_id : typing.Optional[BaseVoiceId]
460
+
461
+ request_options : typing.Optional[RequestOptions]
462
+ Request-specific configuration.
463
+
464
+ Returns
465
+ -------
466
+ Voice
467
+
468
+ Examples
469
+ --------
470
+ from cartesia import Cartesia
471
+
472
+ client = Cartesia(
473
+ api_key="YOUR_API_KEY",
474
+ )
475
+ client.voices.create(
476
+ name="My Custom Voice",
477
+ description="A custom voice created through the API",
478
+ embedding=[],
479
+ language="en",
480
+ base_voice_id="123e4567-e89b-12d3-a456-426614174000",
481
+ )
482
+ """
483
+ _response = self._client_wrapper.httpx_client.request(
484
+ "voices/",
485
+ method="POST",
486
+ json={
487
+ "name": name,
488
+ "description": description,
489
+ "embedding": embedding,
490
+ "language": language,
491
+ "base_voice_id": base_voice_id,
492
+ },
493
+ request_options=request_options,
494
+ omit=OMIT,
495
+ )
496
+ try:
497
+ if 200 <= _response.status_code < 300:
498
+ return typing.cast(
499
+ Voice,
500
+ parse_obj_as(
501
+ type_=Voice, # type: ignore
502
+ object_=_response.json(),
503
+ ),
504
+ )
505
+ _response_json = _response.json()
506
+ except JSONDecodeError:
507
+ raise ApiError(status_code=_response.status_code, body=_response.text)
508
+ raise ApiError(status_code=_response.status_code, body=_response_json)
509
+
510
+
511
+ class AsyncVoicesClient:
512
+ def __init__(self, *, client_wrapper: AsyncClientWrapper):
513
+ self._client_wrapper = client_wrapper
514
+
515
+ async def list(self, *, request_options: typing.Optional[RequestOptions] = None) -> typing.List[Voice]:
516
+ """
517
+ Parameters
518
+ ----------
519
+ request_options : typing.Optional[RequestOptions]
520
+ Request-specific configuration.
521
+
522
+ Returns
523
+ -------
524
+ typing.List[Voice]
525
+
526
+ Examples
527
+ --------
528
+ import asyncio
529
+
530
+ from cartesia import AsyncCartesia
531
+
532
+ client = AsyncCartesia(
533
+ api_key="YOUR_API_KEY",
534
+ )
535
+
536
+
537
+ async def main() -> None:
538
+ await client.voices.list()
539
+
540
+
541
+ asyncio.run(main())
542
+ """
543
+ _response = await self._client_wrapper.httpx_client.request(
544
+ "voices/",
545
+ method="GET",
546
+ request_options=request_options,
547
+ )
548
+ try:
549
+ if 200 <= _response.status_code < 300:
550
+ return typing.cast(
551
+ typing.List[Voice],
552
+ parse_obj_as(
553
+ type_=typing.List[Voice], # type: ignore
554
+ object_=_response.json(),
555
+ ),
556
+ )
557
+ _response_json = _response.json()
558
+ except JSONDecodeError:
559
+ raise ApiError(status_code=_response.status_code, body=_response.text)
560
+ raise ApiError(status_code=_response.status_code, body=_response_json)
561
+
562
+ async def clone(
563
+ self,
564
+ *,
565
+ clip: core.File,
566
+ name: str,
567
+ language: SupportedLanguage,
568
+ mode: CloneMode,
569
+ enhance: bool,
570
+ description: typing.Optional[str] = OMIT,
571
+ transcript: typing.Optional[str] = OMIT,
572
+ request_options: typing.Optional[RequestOptions] = None,
573
+ ) -> VoiceMetadata:
574
+ """
575
+ Clone a voice from an audio clip. This endpoint has two modes, stability and similarity.
576
+
577
+ 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.
578
+
579
+ 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.
580
+
581
+ Parameters
582
+ ----------
583
+ clip : core.File
584
+ See core.File for more documentation
585
+
586
+ name : str
587
+ The name of the voice.
588
+
589
+
590
+ language : SupportedLanguage
591
+ The language of the voice.
592
+
593
+
594
+ mode : CloneMode
595
+ 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.
596
+
597
+
598
+ enhance : bool
599
+ Whether to enhance the clip to improve its quality before cloning. Useful if the clip has background noise.
600
+
601
+
602
+ description : typing.Optional[str]
603
+ A description for the voice.
604
+
605
+
606
+ transcript : typing.Optional[str]
607
+ Optional transcript of the words spoken in the audio clip. Only used for similarity mode.
608
+
609
+
610
+ request_options : typing.Optional[RequestOptions]
611
+ Request-specific configuration.
612
+
613
+ Returns
614
+ -------
615
+ VoiceMetadata
616
+
617
+ Examples
618
+ --------
619
+ import asyncio
620
+
621
+ from cartesia import AsyncCartesia
622
+
623
+ client = AsyncCartesia(
624
+ api_key="YOUR_API_KEY",
625
+ )
626
+
627
+
628
+ async def main() -> None:
629
+ await client.voices.clone(
630
+ name="A high-stability cloned voice",
631
+ description="Copied from Cartesia docs",
632
+ mode="stability",
633
+ language="en",
634
+ enhance=True,
635
+ )
636
+
637
+
638
+ asyncio.run(main())
639
+ """
640
+ _response = await self._client_wrapper.httpx_client.request(
641
+ "voices/clone",
642
+ method="POST",
643
+ data={
644
+ "name": name,
645
+ "description": description,
646
+ "language": language,
647
+ "mode": mode,
648
+ "enhance": enhance,
649
+ "transcript": transcript,
650
+ },
651
+ files={
652
+ "clip": clip,
653
+ },
654
+ request_options=request_options,
655
+ omit=OMIT,
656
+ )
657
+ try:
658
+ if 200 <= _response.status_code < 300:
659
+ return typing.cast(
660
+ VoiceMetadata,
661
+ parse_obj_as(
662
+ type_=VoiceMetadata, # type: ignore
663
+ object_=_response.json(),
664
+ ),
665
+ )
666
+ _response_json = _response.json()
667
+ except JSONDecodeError:
668
+ raise ApiError(status_code=_response.status_code, body=_response.text)
669
+ raise ApiError(status_code=_response.status_code, body=_response_json)
670
+
671
+ async def delete(self, id: VoiceId, *, request_options: typing.Optional[RequestOptions] = None) -> None:
672
+ """
673
+ Parameters
674
+ ----------
675
+ id : VoiceId
676
+
677
+ request_options : typing.Optional[RequestOptions]
678
+ Request-specific configuration.
679
+
680
+ Returns
681
+ -------
682
+ None
683
+
684
+ Examples
685
+ --------
686
+ import asyncio
687
+
688
+ from cartesia import AsyncCartesia
689
+
690
+ client = AsyncCartesia(
691
+ api_key="YOUR_API_KEY",
692
+ )
693
+
694
+
695
+ async def main() -> None:
696
+ await client.voices.delete(
697
+ id="id",
698
+ )
699
+
700
+
701
+ asyncio.run(main())
702
+ """
703
+ _response = await self._client_wrapper.httpx_client.request(
704
+ f"voices/{jsonable_encoder(id)}",
705
+ method="DELETE",
706
+ request_options=request_options,
707
+ )
708
+ try:
709
+ if 200 <= _response.status_code < 300:
710
+ return
711
+ _response_json = _response.json()
712
+ except JSONDecodeError:
713
+ raise ApiError(status_code=_response.status_code, body=_response.text)
714
+ raise ApiError(status_code=_response.status_code, body=_response_json)
715
+
716
+ async def update(
717
+ self, id: VoiceId, *, name: str, description: str, request_options: typing.Optional[RequestOptions] = None
718
+ ) -> Voice:
719
+ """
720
+ Parameters
721
+ ----------
722
+ id : VoiceId
723
+
724
+ name : str
725
+ The name of the voice.
726
+
727
+ description : str
728
+ The description of the voice.
729
+
730
+ request_options : typing.Optional[RequestOptions]
731
+ Request-specific configuration.
732
+
733
+ Returns
734
+ -------
735
+ Voice
736
+
737
+ Examples
738
+ --------
739
+ import asyncio
740
+
741
+ from cartesia import AsyncCartesia
742
+
743
+ client = AsyncCartesia(
744
+ api_key="YOUR_API_KEY",
745
+ )
746
+
747
+
748
+ async def main() -> None:
749
+ await client.voices.update(
750
+ id="id",
751
+ name="name",
752
+ description="description",
753
+ )
754
+
755
+
756
+ asyncio.run(main())
757
+ """
758
+ _response = await self._client_wrapper.httpx_client.request(
759
+ f"voices/{jsonable_encoder(id)}",
760
+ method="PATCH",
761
+ json={
762
+ "name": name,
763
+ "description": description,
764
+ },
765
+ request_options=request_options,
766
+ omit=OMIT,
767
+ )
768
+ try:
769
+ if 200 <= _response.status_code < 300:
770
+ return typing.cast(
771
+ Voice,
772
+ parse_obj_as(
773
+ type_=Voice, # type: ignore
774
+ object_=_response.json(),
775
+ ),
776
+ )
777
+ _response_json = _response.json()
778
+ except JSONDecodeError:
779
+ raise ApiError(status_code=_response.status_code, body=_response.text)
780
+ raise ApiError(status_code=_response.status_code, body=_response_json)
781
+
782
+ async def get(self, id: VoiceId, *, request_options: typing.Optional[RequestOptions] = None) -> Voice:
783
+ """
784
+ Parameters
785
+ ----------
786
+ id : VoiceId
787
+
788
+ request_options : typing.Optional[RequestOptions]
789
+ Request-specific configuration.
790
+
791
+ Returns
792
+ -------
793
+ Voice
794
+
795
+ Examples
796
+ --------
797
+ import asyncio
798
+
799
+ from cartesia import AsyncCartesia
800
+
801
+ client = AsyncCartesia(
802
+ api_key="YOUR_API_KEY",
803
+ )
804
+
805
+
806
+ async def main() -> None:
807
+ await client.voices.get(
808
+ id="id",
809
+ )
810
+
811
+
812
+ asyncio.run(main())
813
+ """
814
+ _response = await self._client_wrapper.httpx_client.request(
815
+ f"voices/{jsonable_encoder(id)}",
816
+ method="GET",
817
+ request_options=request_options,
818
+ )
819
+ try:
820
+ if 200 <= _response.status_code < 300:
821
+ return typing.cast(
822
+ Voice,
823
+ parse_obj_as(
824
+ type_=Voice, # type: ignore
825
+ object_=_response.json(),
826
+ ),
827
+ )
828
+ _response_json = _response.json()
829
+ except JSONDecodeError:
830
+ raise ApiError(status_code=_response.status_code, body=_response.text)
831
+ raise ApiError(status_code=_response.status_code, body=_response_json)
832
+
833
+ async def localize(
834
+ self,
835
+ *,
836
+ embedding: Embedding,
837
+ language: LocalizeTargetLanguage,
838
+ original_speaker_gender: Gender,
839
+ dialect: typing.Optional[LocalizeDialectParams] = OMIT,
840
+ request_options: typing.Optional[RequestOptions] = None,
841
+ ) -> EmbeddingResponse:
842
+ """
843
+ Parameters
844
+ ----------
845
+ embedding : Embedding
846
+
847
+ language : LocalizeTargetLanguage
848
+
849
+ original_speaker_gender : Gender
850
+
851
+ dialect : typing.Optional[LocalizeDialectParams]
852
+
853
+ request_options : typing.Optional[RequestOptions]
854
+ Request-specific configuration.
855
+
856
+ Returns
857
+ -------
858
+ EmbeddingResponse
859
+
860
+ Examples
861
+ --------
862
+ import asyncio
863
+
864
+ from cartesia import AsyncCartesia
865
+
866
+ client = AsyncCartesia(
867
+ api_key="YOUR_API_KEY",
868
+ )
869
+
870
+
871
+ async def main() -> None:
872
+ await client.voices.localize(
873
+ embedding=[1.1, 1.1],
874
+ language="en",
875
+ original_speaker_gender="male",
876
+ )
877
+
878
+
879
+ asyncio.run(main())
880
+ """
881
+ _response = await self._client_wrapper.httpx_client.request(
882
+ "voices/localize",
883
+ method="POST",
884
+ json={
885
+ "embedding": embedding,
886
+ "language": language,
887
+ "original_speaker_gender": original_speaker_gender,
888
+ "dialect": convert_and_respect_annotation_metadata(
889
+ object_=dialect, annotation=LocalizeDialectParams, direction="write"
890
+ ),
891
+ },
892
+ request_options=request_options,
893
+ omit=OMIT,
894
+ )
895
+ try:
896
+ if 200 <= _response.status_code < 300:
897
+ return typing.cast(
898
+ EmbeddingResponse,
899
+ parse_obj_as(
900
+ type_=EmbeddingResponse, # type: ignore
901
+ object_=_response.json(),
902
+ ),
903
+ )
904
+ _response_json = _response.json()
905
+ except JSONDecodeError:
906
+ raise ApiError(status_code=_response.status_code, body=_response.text)
907
+ raise ApiError(status_code=_response.status_code, body=_response_json)
908
+
909
+ async def mix(
910
+ self,
911
+ *,
912
+ voices: typing.Sequence[MixVoiceSpecifierParams],
913
+ request_options: typing.Optional[RequestOptions] = None,
914
+ ) -> EmbeddingResponse:
915
+ """
916
+ Parameters
917
+ ----------
918
+ voices : typing.Sequence[MixVoiceSpecifierParams]
919
+
920
+ request_options : typing.Optional[RequestOptions]
921
+ Request-specific configuration.
922
+
923
+ Returns
924
+ -------
925
+ EmbeddingResponse
926
+
927
+ Examples
928
+ --------
929
+ import asyncio
930
+
931
+ from cartesia import AsyncCartesia
932
+
933
+ client = AsyncCartesia(
934
+ api_key="YOUR_API_KEY",
935
+ )
936
+
937
+
938
+ async def main() -> None:
939
+ await client.voices.mix(
940
+ voices=[{"id": "id", "weight": 1.1}, {"id": "id", "weight": 1.1}],
941
+ )
942
+
943
+
944
+ asyncio.run(main())
945
+ """
946
+ _response = await self._client_wrapper.httpx_client.request(
947
+ "voices/mix",
948
+ method="POST",
949
+ json={
950
+ "voices": convert_and_respect_annotation_metadata(
951
+ object_=voices, annotation=typing.Sequence[MixVoiceSpecifierParams], direction="write"
952
+ ),
953
+ },
954
+ request_options=request_options,
955
+ omit=OMIT,
956
+ )
957
+ try:
958
+ if 200 <= _response.status_code < 300:
959
+ return typing.cast(
960
+ EmbeddingResponse,
961
+ parse_obj_as(
962
+ type_=EmbeddingResponse, # type: ignore
963
+ object_=_response.json(),
964
+ ),
965
+ )
966
+ _response_json = _response.json()
967
+ except JSONDecodeError:
968
+ raise ApiError(status_code=_response.status_code, body=_response.text)
969
+ raise ApiError(status_code=_response.status_code, body=_response_json)
970
+
971
+ async def create(
972
+ self,
973
+ *,
974
+ name: str,
975
+ description: str,
976
+ embedding: Embedding,
977
+ language: typing.Optional[SupportedLanguage] = OMIT,
978
+ base_voice_id: typing.Optional[BaseVoiceId] = OMIT,
979
+ request_options: typing.Optional[RequestOptions] = None,
980
+ ) -> Voice:
981
+ """
982
+ Create voice from raw features. If you'd like to clone a voice from an audio file, please use Clone Voice instead.
983
+
984
+ Parameters
985
+ ----------
986
+ name : str
987
+ The name of the voice.
988
+
989
+ description : str
990
+ The description of the voice.
991
+
992
+ embedding : Embedding
993
+
994
+ language : typing.Optional[SupportedLanguage]
995
+
996
+ base_voice_id : typing.Optional[BaseVoiceId]
997
+
998
+ request_options : typing.Optional[RequestOptions]
999
+ Request-specific configuration.
1000
+
1001
+ Returns
1002
+ -------
1003
+ Voice
1004
+
1005
+ Examples
1006
+ --------
1007
+ import asyncio
1008
+
1009
+ from cartesia import AsyncCartesia
1010
+
1011
+ client = AsyncCartesia(
1012
+ api_key="YOUR_API_KEY",
1013
+ )
1014
+
1015
+
1016
+ async def main() -> None:
1017
+ await client.voices.create(
1018
+ name="My Custom Voice",
1019
+ description="A custom voice created through the API",
1020
+ embedding=[],
1021
+ language="en",
1022
+ base_voice_id="123e4567-e89b-12d3-a456-426614174000",
1023
+ )
1024
+
1025
+
1026
+ asyncio.run(main())
1027
+ """
1028
+ _response = await self._client_wrapper.httpx_client.request(
1029
+ "voices/",
1030
+ method="POST",
1031
+ json={
1032
+ "name": name,
1033
+ "description": description,
1034
+ "embedding": embedding,
1035
+ "language": language,
1036
+ "base_voice_id": base_voice_id,
1037
+ },
1038
+ request_options=request_options,
1039
+ omit=OMIT,
1040
+ )
1041
+ try:
1042
+ if 200 <= _response.status_code < 300:
1043
+ return typing.cast(
1044
+ Voice,
1045
+ parse_obj_as(
1046
+ type_=Voice, # type: ignore
1047
+ object_=_response.json(),
1048
+ ),
1049
+ )
1050
+ _response_json = _response.json()
1051
+ except JSONDecodeError:
1052
+ raise ApiError(status_code=_response.status_code, body=_response.text)
1053
+ raise ApiError(status_code=_response.status_code, body=_response_json)