cartesia 1.1.0.dev0__py3-none-any.whl → 1.3.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.
@@ -6,7 +6,7 @@ from typing import Any, AsyncGenerator, Callable, Dict, List, Optional, Union
6
6
 
7
7
  import aiohttp
8
8
 
9
- from cartesia._constants import DEFAULT_MODEL_ID, DEFAULT_VOICE_EMBEDDING
9
+ from cartesia._constants import DEFAULT_MODEL_ID, DEFAULT_OUTPUT_FORMAT, DEFAULT_VOICE_EMBEDDING
10
10
  from cartesia._types import OutputFormat, VoiceControls
11
11
  from cartesia._websocket import _WebSocket
12
12
  from cartesia.tts import TTS
@@ -45,6 +45,7 @@ class _AsyncTTSContext:
45
45
  voice_embedding: Optional[List[float]] = None,
46
46
  context_id: Optional[str] = None,
47
47
  continue_: bool = False,
48
+ flush: bool = False,
48
49
  duration: Optional[int] = None,
49
50
  language: Optional[str] = None,
50
51
  add_timestamps: bool = False,
@@ -60,6 +61,7 @@ class _AsyncTTSContext:
60
61
  voice_embedding: The embedding of the voice to use for generating audio.
61
62
  context_id: The context ID to use for the request. If not specified, a random context ID will be generated.
62
63
  continue_: Whether to continue the audio generation from the previous transcript or not.
64
+ flush: Whether to trigger a manual flush for the current context's generation.
63
65
  duration: The duration of the audio in seconds.
64
66
  language: The language code for the audio request. This can only be used with `model_id = sonic-multilingual`.
65
67
  add_timestamps: Whether to return word-level timestamps.
@@ -71,7 +73,7 @@ class _AsyncTTSContext:
71
73
  """
72
74
  if context_id is not None and context_id != self._context_id:
73
75
  raise ValueError("Context ID does not match the context ID of the current context.")
74
- if continue_ and transcript == "":
76
+ if continue_ and transcript == "" and not flush:
75
77
  raise ValueError("Transcript cannot be empty when continue_ is True.")
76
78
 
77
79
  await self._websocket.connect()
@@ -87,6 +89,7 @@ class _AsyncTTSContext:
87
89
  context_id=self._context_id,
88
90
  add_timestamps=add_timestamps,
89
91
  continue_=continue_,
92
+ flush=flush,
90
93
  _experimental_voice_controls=_experimental_voice_controls,
91
94
  )
92
95
 
@@ -100,12 +103,49 @@ class _AsyncTTSContext:
100
103
  await self.send(
101
104
  model_id=DEFAULT_MODEL_ID,
102
105
  transcript="",
103
- output_format=TTS.get_output_format("raw_pcm_f32le_44100"),
106
+ output_format=TTS.get_output_format(DEFAULT_OUTPUT_FORMAT),
104
107
  voice_embedding=DEFAULT_VOICE_EMBEDDING, # Default voice embedding since it's a required input for now.
105
108
  context_id=self._context_id,
106
109
  continue_=False,
107
110
  )
108
111
 
112
+ async def flush(self) -> Callable[[], AsyncGenerator[Dict[str, Any], None]]:
113
+ """Trigger a manual flush for the current context's generation. This method returns a generator that yields the audio prior to the flush."""
114
+ await self.send(
115
+ model_id=DEFAULT_MODEL_ID,
116
+ transcript="",
117
+ output_format=TTS.get_output_format(DEFAULT_OUTPUT_FORMAT),
118
+ voice_embedding=DEFAULT_VOICE_EMBEDDING, # Default voice embedding since it's a required input for now.
119
+ context_id=self._context_id,
120
+ continue_=True,
121
+ flush=True,
122
+ )
123
+
124
+ # Save the old flush ID
125
+ flush_id = len(self._websocket._context_queues[self._context_id]) - 1
126
+
127
+ # Create a new Async Queue to store the responses for the new flush ID
128
+ self._websocket._context_queues[self._context_id].append(asyncio.Queue())
129
+
130
+ # Return the generator for the old flush ID
131
+ async def generator():
132
+ try:
133
+ while True:
134
+ response = await self._websocket._get_message(
135
+ self._context_id, timeout=self.timeout, flush_id=flush_id
136
+ )
137
+ if "error" in response:
138
+ raise RuntimeError(f"Error generating audio:\n{response['error']}")
139
+ if response.get("flush_done") or response["done"]:
140
+ break
141
+ yield self._websocket._convert_response(response, include_context_id=True)
142
+ except Exception as e:
143
+ if isinstance(e, asyncio.TimeoutError):
144
+ raise RuntimeError("Timeout while waiting for audio chunk")
145
+ raise RuntimeError(f"Failed to generate audio:\n{e}")
146
+
147
+ return generator
148
+
109
149
  async def receive(self) -> AsyncGenerator[Dict[str, Any], None]:
110
150
  """Receive the audio chunks from the WebSocket. This method is a generator that yields audio chunks.
111
151
 
@@ -175,7 +215,7 @@ class _AsyncWebSocket(_WebSocket):
175
215
  self.timeout = timeout
176
216
  self._get_session = get_session
177
217
  self.websocket = None
178
- self._context_queues: Dict[str, asyncio.Queue] = {}
218
+ self._context_queues: Dict[str, List[asyncio.Queue]] = {}
179
219
  self._processing_task: asyncio.Task = None
180
220
 
181
221
  def __del__(self):
@@ -213,7 +253,7 @@ class _AsyncWebSocket(_WebSocket):
213
253
  except asyncio.CancelledError:
214
254
  pass
215
255
  except TypeError as e:
216
- # Ignore the error if the task is already cancelled
256
+ # Ignore the error if the task is already canceled.
217
257
  # For some reason we are getting None responses
218
258
  # TODO: This needs to be fixed - we need to think about why we are getting None responses.
219
259
  if "Received message 256:None" not in str(e):
@@ -284,16 +324,23 @@ class _AsyncWebSocket(_WebSocket):
284
324
  response = await self.websocket.receive_json()
285
325
  if response["context_id"]:
286
326
  context_id = response["context_id"]
327
+ flush_id = response.get("flush_id", -1)
287
328
  if context_id in self._context_queues:
288
- await self._context_queues[context_id].put(response)
329
+ await self._context_queues[context_id][flush_id].put(response)
289
330
  except Exception as e:
290
331
  self._error = e
291
332
  raise e
292
333
 
293
- async def _get_message(self, context_id: str, timeout: float) -> Dict[str, Any]:
334
+ async def _get_message(
335
+ self, context_id: str, timeout: float, flush_id: Optional[int] = -1
336
+ ) -> Dict[str, Any]:
294
337
  if context_id not in self._context_queues:
295
338
  raise ValueError(f"Context ID {context_id} not found.")
296
- return await asyncio.wait_for(self._context_queues[context_id].get(), timeout=timeout)
339
+ if len(self._context_queues[context_id]) <= flush_id:
340
+ raise ValueError(f"Flush ID {flush_id} not found for context ID {context_id}.")
341
+ return await asyncio.wait_for(
342
+ self._context_queues[context_id][flush_id].get(), timeout=timeout
343
+ )
297
344
 
298
345
  def _remove_context(self, context_id: str):
299
346
  if context_id in self._context_queues:
@@ -309,5 +356,5 @@ class _AsyncWebSocket(_WebSocket):
309
356
  if context_id is None:
310
357
  context_id = str(uuid.uuid4())
311
358
  if context_id not in self._context_queues:
312
- self._context_queues[context_id] = asyncio.Queue()
359
+ self._context_queues[context_id] = [asyncio.Queue()]
313
360
  return _AsyncTTSContext(context_id, self, self.timeout)
cartesia/_constants.py CHANGED
@@ -2,6 +2,7 @@ DEFAULT_MODEL_ID = "sonic-english" # latest default model
2
2
  MULTILINGUAL_MODEL_ID = "sonic-multilingual" # latest multilingual model
3
3
  DEFAULT_BASE_URL = "api.cartesia.ai"
4
4
  DEFAULT_CARTESIA_VERSION = "2024-06-10" # latest version
5
+ DEFAULT_OUTPUT_FORMAT = "raw_pcm_f32le_44100"
5
6
  DEFAULT_TIMEOUT = 30 # seconds
6
7
  DEFAULT_NUM_CONNECTIONS = 10 # connections per client
7
8
  DEFAULT_VOICE_EMBEDDING = [1.0] * 192
cartesia/_types.py CHANGED
@@ -27,39 +27,6 @@ class OutputFormatMapping:
27
27
  raise ValueError(f"Unsupported format: {format_name}")
28
28
 
29
29
 
30
- class DeprecatedOutputFormatMapping:
31
- """Deprecated formats as of v1.0.1. These will be removed in v1.2.0. Use :class:`OutputFormatMapping` instead."""
32
-
33
- _format_mapping = {
34
- "fp32": {"container": "raw", "encoding": "pcm_f32le", "sample_rate": 44100},
35
- "pcm": {"container": "raw", "encoding": "pcm_s16le", "sample_rate": 44100},
36
- "fp32_8000": {"container": "raw", "encoding": "pcm_f32le", "sample_rate": 8000},
37
- "fp32_16000": {"container": "raw", "encoding": "pcm_f32le", "sample_rate": 16000},
38
- "fp32_22050": {"container": "raw", "encoding": "pcm_f32le", "sample_rate": 22050},
39
- "fp32_24000": {"container": "raw", "encoding": "pcm_f32le", "sample_rate": 24000},
40
- "fp32_44100": {"container": "raw", "encoding": "pcm_f32le", "sample_rate": 44100},
41
- "pcm_8000": {"container": "raw", "encoding": "pcm_s16le", "sample_rate": 8000},
42
- "pcm_16000": {"container": "raw", "encoding": "pcm_s16le", "sample_rate": 16000},
43
- "pcm_22050": {"container": "raw", "encoding": "pcm_s16le", "sample_rate": 22050},
44
- "pcm_24000": {"container": "raw", "encoding": "pcm_s16le", "sample_rate": 24000},
45
- "pcm_44100": {"container": "raw", "encoding": "pcm_s16le", "sample_rate": 44100},
46
- "mulaw_8000": {"container": "raw", "encoding": "pcm_mulaw", "sample_rate": 8000},
47
- "alaw_8000": {"container": "raw", "encoding": "pcm_alaw", "sample_rate": 8000},
48
- }
49
-
50
- @classmethod
51
- @deprecated(
52
- vdeprecated="1.0.1",
53
- vremove="1.2.0",
54
- reason="Old output format names are being deprecated in favor of names aligned with the Cartesia API. Use names from `OutputFormatMapping` instead.",
55
- )
56
- def get_format_deprecated(cls, format_name):
57
- if format_name in cls._format_mapping:
58
- return cls._format_mapping[format_name]
59
- else:
60
- raise ValueError(f"Unsupported format: {format_name}")
61
-
62
-
63
30
  class VoiceMetadata(TypedDict):
64
31
  id: str
65
32
  name: str
cartesia/_websocket.py CHANGED
@@ -239,7 +239,7 @@ class _WebSocket:
239
239
  self._contexts.clear()
240
240
 
241
241
  def _convert_response(
242
- self, response: Dict[str, any], include_context_id: bool
242
+ self, response: Dict[str, any], include_context_id: bool, include_flush_id: bool = False
243
243
  ) -> Dict[str, Any]:
244
244
  out = {}
245
245
  if response["type"] == EventType.AUDIO:
@@ -250,6 +250,9 @@ class _WebSocket:
250
250
  if include_context_id:
251
251
  out["context_id"] = response["context_id"]
252
252
 
253
+ if include_flush_id and "flush_id" in response:
254
+ out["flush_id"] = response["flush_id"]
255
+
253
256
  return out
254
257
 
255
258
  def send(
cartesia/tts.py CHANGED
@@ -4,7 +4,6 @@ import httpx
4
4
 
5
5
  from cartesia._sse import _SSE
6
6
  from cartesia._types import (
7
- DeprecatedOutputFormatMapping,
8
7
  OutputFormat,
9
8
  OutputFormatMapping,
10
9
  VoiceControls,
@@ -86,10 +85,6 @@ class TTS(Resource):
86
85
  """
87
86
  if output_format_name in OutputFormatMapping._format_mapping:
88
87
  output_format_obj = OutputFormatMapping.get_format(output_format_name)
89
- elif output_format_name in DeprecatedOutputFormatMapping._format_mapping:
90
- output_format_obj = DeprecatedOutputFormatMapping.get_format_deprecated(
91
- output_format_name
92
- )
93
88
  else:
94
89
  raise ValueError(f"Unsupported format: {output_format_name}")
95
90
 
@@ -114,10 +109,6 @@ class TTS(Resource):
114
109
  """
115
110
  if output_format_name in OutputFormatMapping._format_mapping:
116
111
  output_format_obj = OutputFormatMapping.get_format(output_format_name)
117
- elif output_format_name in DeprecatedOutputFormatMapping._format_mapping:
118
- output_format_obj = DeprecatedOutputFormatMapping.get_format_deprecated(
119
- output_format_name
120
- )
121
112
  else:
122
113
  raise ValueError(f"Unsupported format: {output_format_name}")
123
114
 
cartesia/utils/tts.py CHANGED
@@ -37,6 +37,7 @@ def _construct_tts_request(
37
37
  add_timestamps: bool = False,
38
38
  context_id: Optional[str] = None,
39
39
  continue_: bool = False,
40
+ flush: bool = False,
40
41
  _experimental_voice_controls: Optional[VoiceControls] = None,
41
42
  ):
42
43
  tts_request = {
@@ -71,4 +72,7 @@ def _construct_tts_request(
71
72
  if continue_:
72
73
  tts_request["continue"] = continue_
73
74
 
75
+ if flush:
76
+ tts_request["flush"] = flush
77
+
74
78
  return tts_request
cartesia/version.py CHANGED
@@ -1 +1 @@
1
- __version__ = "1.1.0-dev0"
1
+ __version__ = "1.3.0"
cartesia/voices.py CHANGED
@@ -58,29 +58,65 @@ class Voices(Resource):
58
58
 
59
59
  return response.json()
60
60
 
61
- def clone(self, filepath: Optional[str] = None, enhance: str = True) -> List[float]:
61
+ def clone(
62
+ self,
63
+ filepath: Optional[str] = None,
64
+ enhance: str = True,
65
+ mode: str = "clip",
66
+ language: str = "en",
67
+ name: Optional[str] = None,
68
+ description: Optional[str] = None,
69
+ transcript: Optional[str] = None,
70
+ ) -> Union[List[float], VoiceMetadata]:
62
71
  """Clone a voice from a clip.
63
72
 
64
73
  Args:
65
74
  filepath: The path to the clip file.
66
75
  enhance: Whether to enhance the clip before cloning the voice (highly recommended). Defaults to True.
76
+ mode: The mode to use for cloning. Either "similarity" or "stability".
77
+ language: The language code of the language spoken in the clip. Defaults to "en".
78
+ name: The name of the cloned voice.
79
+ description: The description of the cloned voice.
80
+ transcript: The transcript of the clip. Only used if mode is "similarity".
67
81
 
68
82
  Returns:
69
83
  The embedding of the cloned voice as a list of floats.
70
84
  """
71
85
  if not filepath:
72
86
  raise ValueError("Filepath must be specified.")
73
- url = f"{self._http_url()}/voices/clone/clip"
87
+ headers = self.headers.copy()
88
+ headers.pop("Content-Type", None)
89
+
74
90
  with open(filepath, "rb") as file:
75
91
  files = {"clip": file}
76
- files["enhance"] = str(enhance).lower()
77
- headers = self.headers.copy()
78
- headers.pop("Content-Type", None)
79
- response = httpx.post(url, headers=headers, files=files, timeout=self.timeout)
80
- if not response.is_success:
81
- raise ValueError(f"Failed to clone voice from clip. Error: {response.text}")
82
-
83
- return response.json()["embedding"]
92
+ data = {
93
+ "enhance": str(enhance).lower(),
94
+ "mode": mode,
95
+ }
96
+ if mode == "clip":
97
+ url = f"{self._http_url()}/voices/clone/clip"
98
+ response = httpx.post(
99
+ url, headers=headers, files=files, data=data, timeout=self.timeout
100
+ )
101
+ if not response.is_success:
102
+ raise ValueError(f"Failed to clone voice from clip. Error: {response.text}")
103
+ return response.json()["embedding"]
104
+ else:
105
+ data["name"] = name
106
+ data["description"] = description
107
+ data["language"] = language
108
+ if mode == "similarity" and transcript:
109
+ data["transcript"] = transcript
110
+ url = f"{self._http_url()}/voices/clone"
111
+ response = httpx.post(
112
+ url, headers=headers, files=files, data=data, timeout=self.timeout
113
+ )
114
+ if not response.is_success:
115
+ raise ValueError(
116
+ f"Failed to clone voice. Status Code: {response.status_code}\n"
117
+ f"Error: {response.text}"
118
+ )
119
+ return response.json()
84
120
 
85
121
  def create(
86
122
  self,
@@ -88,6 +124,7 @@ class Voices(Resource):
88
124
  description: str,
89
125
  embedding: List[float],
90
126
  base_voice_id: Optional[str] = None,
127
+ language: str = "en",
91
128
  ) -> VoiceMetadata:
92
129
  """Create a new voice.
93
130
 
@@ -108,6 +145,7 @@ class Voices(Resource):
108
145
  "description": description,
109
146
  "embedding": embedding,
110
147
  "base_voice_id": base_voice_id,
148
+ "language": language,
111
149
  },
112
150
  timeout=self.timeout,
113
151
  )
@@ -1,15 +1,14 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.3
2
2
  Name: cartesia
3
- Version: 1.1.0.dev0
3
+ Version: 1.3.0
4
4
  Summary: The official Python library for the Cartesia API.
5
5
  Requires-Python: >=3.9
6
+ Requires-Dist: aiohttp>=3.10.10
7
+ Requires-Dist: httpx>=0.27.2
8
+ Requires-Dist: iterators>=0.2.0
9
+ Requires-Dist: requests>=2.32.3
10
+ Requires-Dist: websockets>=10.4
6
11
  Description-Content-Type: text/markdown
7
- License-File: LICENSE.md
8
- Requires-Dist: aiohttp >=3.10.10
9
- Requires-Dist: httpx >=0.27.2
10
- Requires-Dist: iterators >=0.2.0
11
- Requires-Dist: requests >=2.32.3
12
- Requires-Dist: websockets >=13.1
13
12
 
14
13
  # Cartesia Python API Library
15
14
 
@@ -642,8 +641,6 @@ display(audio)
642
641
 
643
642
  You can use the `client.tts.get_output_format` method to convert string-based output format names into the `output_format` dictionary which is expected by the `output_format` parameter. You can see the `OutputFormatMapping` class in `cartesia._types` for the currently supported output format names. You can also view the currently supported `output_format`s in our [API Reference](https://docs.cartesia.ai/reference/api-reference/rest/stream-speech-server-sent-events).
644
643
 
645
- The previously used `output_format` strings are now deprecated and will be removed in v1.2.0. These are listed in the `DeprecatedOutputFormatMapping` class in `cartesia._types`.
646
-
647
644
  ```python
648
645
  # Get the output format dictionary from string name
649
646
  output_format = client.tts.get_output_format("raw_pcm_f32le_44100")
@@ -0,0 +1,23 @@
1
+ cartesia/__init__.py,sha256=rS7jIg4iqT0VgnwjzYK25JXxnF5hjZGE_-PGynAqHFo,126
2
+ cartesia/_async_sse.py,sha256=76oIvstzVcWZCbcD8Ps419k1FEHF6lOB5qoHwawvj9k,3327
3
+ cartesia/_async_websocket.py,sha256=y9YL9fU8eLENZZECJUwRBVTfEx4ZMl96Y5zHaRY2BiI,14787
4
+ cartesia/_constants.py,sha256=khGNVpiQVDmv1oZU7pKTd9C1AHjiaM8zQ2He9d5zI_c,435
5
+ cartesia/_logger.py,sha256=vU7QiGSy_AJuJFmClUocqIJ-Ltku_8C24ZU8L6fLJR0,53
6
+ cartesia/_sse.py,sha256=CugabGUAUM-N2BruxNFxDB20HyxDlRdbN-J_yAzvBMY,5667
7
+ cartesia/_types.py,sha256=gixQbKbX-H8xbD7jxHmc02KXLyjEaup19lh_57_YBl8,2570
8
+ cartesia/_websocket.py,sha256=nRCq9xB0T9yYHoLqtn0GsJmcap-OAlJdSIrzTl40qMI,14875
9
+ cartesia/async_client.py,sha256=y_K_Yuv0weA4k9ZYD0M9bNM3x3frsq07tqkg7R9h0-o,2714
10
+ cartesia/async_tts.py,sha256=IbWVRKklNClXASR6ylHaukcMRR304LUguqc4yMopbDU,2076
11
+ cartesia/client.py,sha256=OS1ORUSlR8Jg-em1imeTAFfwkC85AQFnw8PYtTdUuC8,2364
12
+ cartesia/resource.py,sha256=wpnB3IPcTdxYSp0vxSkpntp4NSvqvnwUWF-0ZpgWV9o,1585
13
+ cartesia/tts.py,sha256=kWvqce9K3gZ4QrWD-ciYdK29n49SNkxhd2A7ueTOwMY,4878
14
+ cartesia/version.py,sha256=F5mW07pSyGrqDNY2Ehr-UpDzpBtN-FsYU0QGZWf6PJE,22
15
+ cartesia/voices.py,sha256=bDYbs0KoikAROJlmbnLdo4TrW0YwzjMvp70uKG6Alp0,7180
16
+ cartesia/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
17
+ cartesia/utils/deprecated.py,sha256=2cXvGtrxhPeUZA5LWy2n_U5OFLDv7SHeFtzqhjSJGyk,1674
18
+ cartesia/utils/retry.py,sha256=O6fyVWpH9Su8c0Fwupl57xMt6JrwJ52txBwP3faUL7k,3339
19
+ cartesia/utils/tts.py,sha256=TbvBZqHR6LxPim6s5RyGiURi4hIfqWt3KUk5QYOOhfc,2177
20
+ cartesia-1.3.0.dist-info/METADATA,sha256=eedG5B4V6MxvDuPUMdYwp6UHrX6yQ6dJTMRRZxq1-UA,20976
21
+ cartesia-1.3.0.dist-info/WHEEL,sha256=C2FUgwZgiLbznR-k0b_5k3Ai_1aASOXDss3lzCUsUug,87
22
+ cartesia-1.3.0.dist-info/licenses/LICENSE.md,sha256=PT2YG5wEtEX1TNDn5sXkUXqbn-neyr7cZenTxd40ql4,1074
23
+ cartesia-1.3.0.dist-info/RECORD,,
@@ -1,5 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.2.0)
2
+ Generator: hatchling 1.26.3
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
-
@@ -1,24 +0,0 @@
1
- cartesia/__init__.py,sha256=rS7jIg4iqT0VgnwjzYK25JXxnF5hjZGE_-PGynAqHFo,126
2
- cartesia/_async_sse.py,sha256=76oIvstzVcWZCbcD8Ps419k1FEHF6lOB5qoHwawvj9k,3327
3
- cartesia/_async_websocket.py,sha256=Gy0nK3g2HKIBwh-PP1AunEBj83kgFpTGCvrq6tnwg9c,12515
4
- cartesia/_constants.py,sha256=lquaYIg7IThdmC1fCklnWC8EM7stbSeVCDwRqCzPq-U,389
5
- cartesia/_logger.py,sha256=vU7QiGSy_AJuJFmClUocqIJ-Ltku_8C24ZU8L6fLJR0,53
6
- cartesia/_sse.py,sha256=CugabGUAUM-N2BruxNFxDB20HyxDlRdbN-J_yAzvBMY,5667
7
- cartesia/_types.py,sha256=2fTSCwjL9lJ3jsdbs0P9fHsjkhejyrrYt6oqIXGk1y4,4488
8
- cartesia/_websocket.py,sha256=CpqkShdl4qBjCGMR8s6dEBHK0LJxkrG-FjbPLhjOP-U,14735
9
- cartesia/async_client.py,sha256=y_K_Yuv0weA4k9ZYD0M9bNM3x3frsq07tqkg7R9h0-o,2714
10
- cartesia/async_tts.py,sha256=IbWVRKklNClXASR6ylHaukcMRR304LUguqc4yMopbDU,2076
11
- cartesia/client.py,sha256=OS1ORUSlR8Jg-em1imeTAFfwkC85AQFnw8PYtTdUuC8,2364
12
- cartesia/resource.py,sha256=wpnB3IPcTdxYSp0vxSkpntp4NSvqvnwUWF-0ZpgWV9o,1585
13
- cartesia/tts.py,sha256=RiADE9wjukfq595DrtgBZY8OKoTaFBzef0wCG93yvFM,5345
14
- cartesia/version.py,sha256=7mgCxmrH_BGK1I131E6uUNAUW91B4b9YhDrULqohQi0,27
15
- cartesia/voices.py,sha256=DB4tEiSJp7jfnQM0HoiSFS09ZY2oAFbOwMlKe6pofTs,5606
16
- cartesia/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
17
- cartesia/utils/deprecated.py,sha256=2cXvGtrxhPeUZA5LWy2n_U5OFLDv7SHeFtzqhjSJGyk,1674
18
- cartesia/utils/retry.py,sha256=O6fyVWpH9Su8c0Fwupl57xMt6JrwJ52txBwP3faUL7k,3339
19
- cartesia/utils/tts.py,sha256=7tJmdyOYwe2QIav5d1UZxhpbcHaYqf7A77bBOlb4U_g,2100
20
- cartesia-1.1.0.dev0.dist-info/LICENSE.md,sha256=PT2YG5wEtEX1TNDn5sXkUXqbn-neyr7cZenTxd40ql4,1074
21
- cartesia-1.1.0.dev0.dist-info/METADATA,sha256=TORvxC_g0KM3OdvEpJaGSEwJ2ZawfMM_m4J58MI8ZYU,21190
22
- cartesia-1.1.0.dev0.dist-info/WHEEL,sha256=OVMc5UfuAQiSplgO0_WdW7vXVGAt9Hdd6qtN4HotdyA,91
23
- cartesia-1.1.0.dev0.dist-info/top_level.txt,sha256=rTX4HnnCegMxl1FK9czpVC7GAvf3SwDzPG65qP-BS4w,9
24
- cartesia-1.1.0.dev0.dist-info/RECORD,,
@@ -1 +0,0 @@
1
- cartesia