cartesia 1.0.8__tar.gz → 1.0.10__tar.gz

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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: cartesia
3
- Version: 1.0.8
3
+ Version: 1.0.10
4
4
  Summary: The official Python library for the Cartesia API.
5
5
  Home-page:
6
6
  Author: Cartesia, Inc.
@@ -0,0 +1,3 @@
1
+ from cartesia.client import AsyncCartesia, Cartesia
2
+
3
+ __all__ = ["Cartesia", "AsyncCartesia"]
@@ -1,4 +1,5 @@
1
- from typing import List, TypedDict
1
+ from typing import List, TypedDict, Union
2
+
2
3
  from cartesia.utils.deprecated import deprecated
3
4
 
4
5
 
@@ -85,7 +86,7 @@ class VoiceControls(TypedDict):
85
86
  This is an experimental class and is subject to rapid change in future versions.
86
87
  """
87
88
 
88
- speed: str = ""
89
+ speed: Union[str, float] = ""
89
90
  emotion: List[str] = []
90
91
 
91
92
 
@@ -1,46 +1,48 @@
1
1
  import asyncio
2
2
  import base64
3
- from collections import defaultdict
4
3
  import json
4
+ import logging
5
5
  import os
6
6
  import uuid
7
+ from collections import defaultdict
7
8
  from types import TracebackType
8
9
  from typing import (
9
10
  Any,
10
11
  AsyncGenerator,
11
- Iterator,
12
+ Callable,
12
13
  Dict,
13
14
  Generator,
15
+ Iterator,
14
16
  List,
15
17
  Optional,
18
+ Set,
16
19
  Tuple,
17
20
  Union,
18
- Callable,
19
- Set,
20
21
  )
21
22
 
22
23
  import aiohttp
23
24
  import httpx
24
- import logging
25
25
  import requests
26
+
26
27
  try:
27
28
  from websockets.sync.client import connect
29
+
28
30
  IS_WEBSOCKET_SYNC_AVAILABLE = True
29
31
  except ImportError:
30
32
  IS_WEBSOCKET_SYNC_AVAILABLE = False
31
33
 
32
34
  from iterators import TimeoutIterator
35
+ from websockets.sync.client import connect
33
36
 
34
- from cartesia.utils.retry import retry_on_connection_error, retry_on_connection_error_async
35
37
  from cartesia._types import (
38
+ DeprecatedOutputFormatMapping,
36
39
  EventType,
37
40
  OutputFormat,
38
41
  OutputFormatMapping,
39
- DeprecatedOutputFormatMapping,
40
42
  VoiceControls,
41
43
  VoiceMetadata,
42
44
  )
43
-
45
+ from cartesia.utils.retry import retry_on_connection_error, retry_on_connection_error_async
44
46
 
45
47
  DEFAULT_MODEL_ID = "sonic-english" # latest default model
46
48
  MULTILINGUAL_MODEL_ID = "sonic-multilingual" # latest multilingual model
@@ -212,21 +214,22 @@ class Voices(Resource):
212
214
 
213
215
  return response.json()
214
216
 
215
- def clone(self, filepath: Optional[str] = None, link: Optional[str] = None) -> List[float]:
217
+ def clone(self, filepath: Optional[str] = None, enhance: str = True) -> List[float]:
216
218
  """Clone a voice from a clip.
217
219
 
218
220
  Args:
219
221
  filepath: The path to the clip file.
222
+ enhance: Whether to enhance the clip before cloning the voice (highly recommended). Defaults to True.
220
223
 
221
224
  Returns:
222
225
  The embedding of the cloned voice as a list of floats.
223
226
  """
224
- # TODO: Python has a bytes object, use that instead of a filepath
225
227
  if not filepath:
226
228
  raise ValueError("Filepath must be specified.")
227
229
  url = f"{self._http_url()}/voices/clone/clip"
228
230
  with open(filepath, "rb") as file:
229
231
  files = {"clip": file}
232
+ files["enhance"] = str(enhance).lower()
230
233
  headers = self.headers.copy()
231
234
  headers.pop("Content-Type", None)
232
235
  response = httpx.post(url, headers=headers, files=files, timeout=self.timeout)
@@ -0,0 +1 @@
1
+ __version__ = "1.0.10"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: cartesia
3
- Version: 1.0.8
3
+ Version: 1.0.10
4
4
  Summary: The official Python library for the Cartesia API.
5
5
  Home-page:
6
6
  Author: Cartesia, Inc.
@@ -1,6 +1,6 @@
1
1
  [tool.ruff]
2
2
  # Add more rule codes as needed
3
- extend-select = [
3
+ lint.extend-select = [
4
4
  "D", # pydocstyle - to replace docformatter
5
5
  ]
6
6
 
@@ -43,14 +43,14 @@ line-length = 100
43
43
  # Enable the count of violations
44
44
  output-format = "full"
45
45
 
46
- [tool.ruff.isort]
47
- force-wrap-aliases = true
48
- combine-as-imports = true
49
- force-sort-within-sections = true
50
- known-first-party = []
51
- known-third-party = []
52
- known-local-folder = []
53
- lines-after-imports = 2
54
-
55
- [tool.ruff.pydocstyle]
46
+ [tool.ruff.lint.pydocstyle]
56
47
  convention = "google"
48
+
49
+ [tool.isort]
50
+ profile = "black"
51
+ multi_line_output = 3
52
+ include_trailing_comma = true
53
+ force_grid_wrap = 0
54
+ use_parentheses = true
55
+ ensure_newline_before_comments = true
56
+ line_length = 100
@@ -1,8 +1,7 @@
1
1
  from packaging.version import Version
2
2
 
3
- import cartesia as Cartesia
4
- from cartesia.utils.deprecated import _DEPRECATED_FUNCTION_STATS
5
3
  import cartesia.version as version
4
+ from cartesia.utils.deprecated import _DEPRECATED_FUNCTION_STATS
6
5
 
7
6
 
8
7
  def test_deprecated_to_remove_by_version():
@@ -5,17 +5,19 @@ different results. Therefore, we cannot test for complete correctness but rather
5
5
  general correctness.
6
6
  """
7
7
 
8
+ import asyncio
8
9
  import logging
9
10
  import os
10
11
  import sys
11
- from cartesia import AsyncCartesia, Cartesia
12
- from cartesia.client import DEFAULT_MODEL_ID, MULTILINGUAL_MODEL_ID
13
- from cartesia._types import VoiceControls, VoiceMetadata
12
+ import uuid
14
13
  from typing import AsyncGenerator, Generator, List
14
+
15
15
  import numpy as np
16
16
  import pytest
17
- import uuid
18
- import asyncio
17
+
18
+ from cartesia import AsyncCartesia, Cartesia
19
+ from cartesia._types import VoiceControls, VoiceMetadata
20
+ from cartesia.client import DEFAULT_MODEL_ID, MULTILINGUAL_MODEL_ID
19
21
 
20
22
  THISDIR = os.path.dirname(__file__)
21
23
  sys.path.insert(0, os.path.dirname(THISDIR))
@@ -24,6 +26,7 @@ RESOURCES_DIR = os.path.join(THISDIR, "resources")
24
26
  SAMPLE_VOICE = "Newsman"
25
27
  SAMPLE_VOICE_ID = "d46abd1d-2d02-43e8-819f-51fb652c1c61"
26
28
  EXPERIMENTAL_VOICE_CONTROLS = {"emotion": ["anger:high", "positivity:low"], "speed": "fastest"}
29
+ EXPERIMENTAL_VOICE_CONTROLS_2 = {"speed": 0.4}
27
30
 
28
31
  logger = logging.getLogger(__name__)
29
32
 
@@ -84,6 +87,12 @@ def test_clone_voice_with_file(client: Cartesia):
84
87
  output = client.voices.clone(filepath=os.path.join(RESOURCES_DIR, "sample-speech-4s.wav"))
85
88
  assert isinstance(output, list)
86
89
 
90
+ @pytest.mark.parametrize("enhance", [True, False])
91
+ def test_clone_voice_with_file_enhance(client: Cartesia, enhance: bool):
92
+ logger.info("Testing voices.clone with file")
93
+ output = client.voices.clone(filepath=os.path.join(RESOURCES_DIR, "sample-speech-4s.wav"), enhance=enhance)
94
+ assert isinstance(output, list)
95
+
87
96
  def test_create_voice(client: Cartesia):
88
97
  logger.info("Testing voices.create")
89
98
  embedding = np.ones(192).tolist()
@@ -95,7 +104,7 @@ def test_create_voice(client: Cartesia):
95
104
  assert voice in voices
96
105
 
97
106
  @pytest.mark.parametrize("stream", [True, False])
98
- @pytest.mark.parametrize("_experimental_voice_controls", [None, EXPERIMENTAL_VOICE_CONTROLS])
107
+ @pytest.mark.parametrize("_experimental_voice_controls", [None, EXPERIMENTAL_VOICE_CONTROLS, EXPERIMENTAL_VOICE_CONTROLS_2])
99
108
  def test_sse_send(resources: _Resources, stream: bool, _experimental_voice_controls: VoiceControls):
100
109
  logger.info("Testing SSE send")
101
110
  client = resources.client
@@ -132,7 +141,7 @@ def test_sse_send_with_model_id(resources: _Resources, stream: bool):
132
141
  assert isinstance(out["audio"], bytes)
133
142
 
134
143
  @pytest.mark.parametrize("stream", [True, False])
135
- @pytest.mark.parametrize("_experimental_voice_controls", [None, EXPERIMENTAL_VOICE_CONTROLS])
144
+ @pytest.mark.parametrize("_experimental_voice_controls", [None, EXPERIMENTAL_VOICE_CONTROLS, EXPERIMENTAL_VOICE_CONTROLS_2])
136
145
  def test_websocket_send(resources: _Resources, stream: bool, _experimental_voice_controls: VoiceControls):
137
146
  logger.info("Testing WebSocket send")
138
147
  client = resources.client
@@ -182,7 +191,7 @@ def test_websocket_send_timestamps(resources: _Resources, stream: bool):
182
191
  ws.close()
183
192
 
184
193
 
185
- @pytest.mark.parametrize("_experimental_voice_controls", [None, EXPERIMENTAL_VOICE_CONTROLS])
194
+ @pytest.mark.parametrize("_experimental_voice_controls", [None, EXPERIMENTAL_VOICE_CONTROLS, EXPERIMENTAL_VOICE_CONTROLS_2])
186
195
  def test_sse_send_context_manager(resources: _Resources, _experimental_voice_controls: VoiceControls):
187
196
  logger.info("Testing SSE send context manager")
188
197
  transcript = "Hello, world! I'\''m generating audio on Cartesia."
@@ -248,7 +257,7 @@ def test_websocket_send_context_manage_err(resources: _Resources):
248
257
  pass
249
258
 
250
259
  @pytest.mark.asyncio
251
- @pytest.mark.parametrize("_experimental_voice_controls", [None, EXPERIMENTAL_VOICE_CONTROLS])
260
+ @pytest.mark.parametrize("_experimental_voice_controls", [None, EXPERIMENTAL_VOICE_CONTROLS, EXPERIMENTAL_VOICE_CONTROLS_2])
252
261
  async def test_async_sse_send( resources: _Resources, _experimental_voice_controls: VoiceControls):
253
262
  logger.info("Testing async SSE send")
254
263
  transcript = "Hello, world! I'\''m generating audio on Cartesia."
@@ -269,7 +278,7 @@ async def test_async_sse_send( resources: _Resources, _experimental_voice_contro
269
278
  await async_client.close()
270
279
 
271
280
  @pytest.mark.asyncio
272
- @pytest.mark.parametrize("_experimental_voice_controls", [None, EXPERIMENTAL_VOICE_CONTROLS])
281
+ @pytest.mark.parametrize("_experimental_voice_controls", [None, EXPERIMENTAL_VOICE_CONTROLS, EXPERIMENTAL_VOICE_CONTROLS_2])
273
282
  async def test_async_websocket_send(resources: _Resources, _experimental_voice_controls: VoiceControls):
274
283
  logger.info("Testing async WebSocket send")
275
284
  transcript = "Hello, world! I'\''m generating audio on Cartesia."
@@ -1,3 +0,0 @@
1
- from cartesia.client import Cartesia, AsyncCartesia
2
-
3
- __all__ = ["Cartesia", "AsyncCartesia"]
@@ -1 +0,0 @@
1
- __version__ = "1.0.8"
File without changes
File without changes
@@ -1,9 +1,9 @@
1
- import time
2
-
3
- from aiohttp.client_exceptions import ServerDisconnectedError
4
1
  import asyncio
2
+ import time
5
3
  from functools import wraps
6
4
  from http.client import RemoteDisconnected
5
+
6
+ from aiohttp.client_exceptions import ServerDisconnectedError
7
7
  from httpx import TimeoutException
8
8
  from requests.exceptions import ConnectionError
9
9
 
File without changes
File without changes