jigsawstack 0.2.2__tar.gz → 0.2.4__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.
Files changed (46) hide show
  1. {jigsawstack-0.2.2 → jigsawstack-0.2.4}/PKG-INFO +1 -1
  2. {jigsawstack-0.2.2 → jigsawstack-0.2.4}/jigsawstack/audio.py +67 -23
  3. {jigsawstack-0.2.2 → jigsawstack-0.2.4}/jigsawstack.egg-info/PKG-INFO +1 -1
  4. {jigsawstack-0.2.2 → jigsawstack-0.2.4}/setup.py +1 -1
  5. jigsawstack-0.2.4/tests/test_audio.py +112 -0
  6. jigsawstack-0.2.2/tests/test_audio.py +0 -22
  7. {jigsawstack-0.2.2 → jigsawstack-0.2.4}/README.md +0 -0
  8. {jigsawstack-0.2.2 → jigsawstack-0.2.4}/jigsawstack/__init__.py +0 -0
  9. {jigsawstack-0.2.2 → jigsawstack-0.2.4}/jigsawstack/_client.py +0 -0
  10. {jigsawstack-0.2.2 → jigsawstack-0.2.4}/jigsawstack/_config.py +0 -0
  11. {jigsawstack-0.2.2 → jigsawstack-0.2.4}/jigsawstack/async_request.py +0 -0
  12. {jigsawstack-0.2.2 → jigsawstack-0.2.4}/jigsawstack/custom_typing.py +0 -0
  13. {jigsawstack-0.2.2 → jigsawstack-0.2.4}/jigsawstack/embedding.py +0 -0
  14. {jigsawstack-0.2.2 → jigsawstack-0.2.4}/jigsawstack/exceptions.py +0 -0
  15. {jigsawstack-0.2.2 → jigsawstack-0.2.4}/jigsawstack/geo.py +0 -0
  16. {jigsawstack-0.2.2 → jigsawstack-0.2.4}/jigsawstack/helpers.py +0 -0
  17. {jigsawstack-0.2.2 → jigsawstack-0.2.4}/jigsawstack/image_generation.py +0 -0
  18. {jigsawstack-0.2.2 → jigsawstack-0.2.4}/jigsawstack/prediction.py +0 -0
  19. {jigsawstack-0.2.2 → jigsawstack-0.2.4}/jigsawstack/prompt_engine.py +0 -0
  20. {jigsawstack-0.2.2 → jigsawstack-0.2.4}/jigsawstack/request.py +0 -0
  21. {jigsawstack-0.2.2 → jigsawstack-0.2.4}/jigsawstack/search.py +0 -0
  22. {jigsawstack-0.2.2 → jigsawstack-0.2.4}/jigsawstack/sentiment.py +0 -0
  23. {jigsawstack-0.2.2 → jigsawstack-0.2.4}/jigsawstack/sql.py +0 -0
  24. {jigsawstack-0.2.2 → jigsawstack-0.2.4}/jigsawstack/store.py +0 -0
  25. {jigsawstack-0.2.2 → jigsawstack-0.2.4}/jigsawstack/summary.py +0 -0
  26. {jigsawstack-0.2.2 → jigsawstack-0.2.4}/jigsawstack/translate.py +0 -0
  27. {jigsawstack-0.2.2 → jigsawstack-0.2.4}/jigsawstack/validate.py +0 -0
  28. {jigsawstack-0.2.2 → jigsawstack-0.2.4}/jigsawstack/version.py +0 -0
  29. {jigsawstack-0.2.2 → jigsawstack-0.2.4}/jigsawstack/vision.py +0 -0
  30. {jigsawstack-0.2.2 → jigsawstack-0.2.4}/jigsawstack/web.py +0 -0
  31. {jigsawstack-0.2.2 → jigsawstack-0.2.4}/jigsawstack.egg-info/SOURCES.txt +0 -0
  32. {jigsawstack-0.2.2 → jigsawstack-0.2.4}/jigsawstack.egg-info/dependency_links.txt +0 -0
  33. {jigsawstack-0.2.2 → jigsawstack-0.2.4}/jigsawstack.egg-info/not-zip-safe +0 -0
  34. {jigsawstack-0.2.2 → jigsawstack-0.2.4}/jigsawstack.egg-info/requires.txt +0 -0
  35. {jigsawstack-0.2.2 → jigsawstack-0.2.4}/jigsawstack.egg-info/top_level.txt +0 -0
  36. {jigsawstack-0.2.2 → jigsawstack-0.2.4}/setup.cfg +0 -0
  37. {jigsawstack-0.2.2 → jigsawstack-0.2.4}/tests/test_async_web.py +0 -0
  38. {jigsawstack-0.2.2 → jigsawstack-0.2.4}/tests/test_embedding_async.py +0 -0
  39. {jigsawstack-0.2.2 → jigsawstack-0.2.4}/tests/test_geo.py +0 -0
  40. {jigsawstack-0.2.2 → jigsawstack-0.2.4}/tests/test_prompt_engine.py +0 -0
  41. {jigsawstack-0.2.2 → jigsawstack-0.2.4}/tests/test_search.py +0 -0
  42. {jigsawstack-0.2.2 → jigsawstack-0.2.4}/tests/test_sentiment.py +0 -0
  43. {jigsawstack-0.2.2 → jigsawstack-0.2.4}/tests/test_store.py +0 -0
  44. {jigsawstack-0.2.2 → jigsawstack-0.2.4}/tests/test_validate.py +0 -0
  45. {jigsawstack-0.2.2 → jigsawstack-0.2.4}/tests/test_vision.py +0 -0
  46. {jigsawstack-0.2.2 → jigsawstack-0.2.4}/tests/test_web.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: jigsawstack
3
- Version: 0.2.2
3
+ Version: 0.2.4
4
4
  Summary: JigsawStack - The AI SDK for Python
5
5
  Home-page: https://github.com/jigsawstack/jigsawstack-python
6
6
  Author: JigsawStack
@@ -16,6 +16,17 @@ class TextToSpeechParams(TypedDict):
16
16
  speaker_clone_file_store_key: NotRequired[str]
17
17
 
18
18
 
19
+ class TTSCloneParams(TypedDict):
20
+ url: NotRequired[str]
21
+ file_store_key: NotRequired[str]
22
+ name: str
23
+
24
+
25
+ class ListTTSVoiceClonesParams(TypedDict):
26
+ limit: NotRequired[int]
27
+ page: NotRequired[int]
28
+
29
+
19
30
  class TextToSpeechResponse(TypedDict):
20
31
  success: bool
21
32
  text: str
@@ -70,12 +81,10 @@ class Audio(ClientConfig):
70
81
  @overload
71
82
  def speech_to_text(self, file: bytes, options: Optional[SpeechToTextParams] = None) -> SpeechToTextResponse: ...
72
83
 
73
- def speech_to_text(
74
- self,
75
- blob: Union[SpeechToTextParams, bytes],
76
- options: Optional[SpeechToTextParams] = None,
77
- ) -> SpeechToTextResponse:
78
- if isinstance(blob, dict): # If params is provided as a dict, we assume it's the first argument
84
+ def speech_to_text(self, blob: Union[SpeechToTextParams, bytes], options: Optional[SpeechToTextParams] = None) -> SpeechToTextResponse:
85
+ if isinstance(
86
+ blob, dict
87
+ ): # If params is provided as a dict, we assume it's the first argument
79
88
  resp = Request(
80
89
  config=self.config,
81
90
  path="/ai/transcribe",
@@ -89,17 +98,9 @@ class Audio(ClientConfig):
89
98
  content_type = options.get("content_type", "application/octet-stream")
90
99
  headers = {"Content-Type": content_type}
91
100
 
92
- resp = Request(
93
- config=self.config,
94
- path=path,
95
- params=options,
96
- data=blob,
97
- headers=headers,
98
- verb="post",
99
- ).perform_with_content()
101
+ resp = Request(config=self.config, path=path, params=options, data=blob, headers=headers, verb="post").perform_with_content()
100
102
  return resp
101
103
 
102
-
103
104
  def text_to_speech(self, params: TextToSpeechParams) -> TextToSpeechResponse:
104
105
  path = "/ai/tts"
105
106
  resp = Request(
@@ -112,12 +113,23 @@ class Audio(ClientConfig):
112
113
 
113
114
  def speaker_voice_accents(self) -> TextToSpeechResponse:
114
115
  path = "/ai/tts"
115
- resp = Request(
116
- config=self.config,
117
- path=path,
118
- params={},
119
- verb="get",
120
- ).perform_with_content()
116
+ resp = Request(config=self.config, path=path, params={}, verb="get").perform_with_content()
117
+ return resp
118
+
119
+ def create_clone(self, params: TTSCloneParams) -> TextToSpeechResponse:
120
+ path = "/ai/tts/clone"
121
+ resp = Request(config=self.config, path=path, params=cast(Dict[Any, Any], params), verb="post").perform_with_content()
122
+
123
+ return resp
124
+
125
+ def list_clones(self, params: ListTTSVoiceClonesParams) -> TextToSpeechResponse:
126
+ path = "/ai/tts/clone"
127
+ resp = Request(config=self.config, path=path, params=cast(Dict[Any, Any], params), verb="get").perform_with_content()
128
+ return resp
129
+
130
+ def delete_clone(self, voice_id: str) -> TextToSpeechResponse:
131
+ path = f"/ai/tts/clone/{voice_id}"
132
+ resp = Request(config=self.config, path=path, params={}, verb="delete").perform_with_content()
121
133
  return resp
122
134
 
123
135
 
@@ -140,7 +152,9 @@ class AsyncAudio(ClientConfig):
140
152
  @overload
141
153
  async def speech_to_text(self, params: SpeechToTextParams) -> SpeechToTextResponse: ...
142
154
  @overload
143
- async def speech_to_text(self, file: bytes, options: Optional[SpeechToTextParams] = None) -> SpeechToTextResponse: ...
155
+ async def speech_to_text(
156
+ self, file: bytes, options: Optional[SpeechToTextParams] = None
157
+ ) -> SpeechToTextResponse: ...
144
158
 
145
159
  async def speech_to_text(
146
160
  self,
@@ -155,7 +169,7 @@ class AsyncAudio(ClientConfig):
155
169
  verb="post",
156
170
  ).perform_with_content()
157
171
  return resp
158
-
172
+
159
173
  options = options or {}
160
174
  path = build_path(base_path="/ai/transcribe", params=options)
161
175
  content_type = options.get("content_type", "application/octet-stream")
@@ -190,3 +204,33 @@ class AsyncAudio(ClientConfig):
190
204
  verb="get",
191
205
  ).perform_with_content()
192
206
  return resp
207
+
208
+ async def create_clone(self, params: TTSCloneParams) -> TextToSpeechResponse:
209
+ path = "/ai/tts/clone"
210
+ resp = await AsyncRequest(
211
+ config=self.config,
212
+ path=path,
213
+ params=cast(Dict[Any, Any], params),
214
+ verb="post"
215
+ ).perform_with_content()
216
+ return resp
217
+
218
+ async def list_clones(self, params: ListTTSVoiceClonesParams) -> TextToSpeechResponse:
219
+ path = "/ai/tts/clone"
220
+ resp = await AsyncRequest(
221
+ config=self.config,
222
+ path=path,
223
+ params=cast(Dict[Any, Any], params),
224
+ verb="get"
225
+ ).perform_with_content()
226
+ return resp
227
+
228
+ async def delete_clone(self, voice_id: str) -> TextToSpeechResponse:
229
+ path = f"/ai/tts/clone/{voice_id}"
230
+ resp = await AsyncRequest(
231
+ config=self.config,
232
+ path=path,
233
+ params={},
234
+ verb="delete"
235
+ ).perform_with_content()
236
+ return resp
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: jigsawstack
3
- Version: 0.2.2
3
+ Version: 0.2.4
4
4
  Summary: JigsawStack - The AI SDK for Python
5
5
  Home-page: https://github.com/jigsawstack/jigsawstack-python
6
6
  Author: JigsawStack
@@ -6,7 +6,7 @@ install_requires = open("requirements.txt").readlines()
6
6
 
7
7
  setup(
8
8
  name="jigsawstack",
9
- version="0.2.2",
9
+ version="0.2.4",
10
10
  description="JigsawStack - The AI SDK for Python",
11
11
  long_description=open("README.md", encoding="utf8").read(),
12
12
  long_description_content_type="text/markdown",
@@ -0,0 +1,112 @@
1
+ from unittest.mock import MagicMock
2
+ import unittest
3
+ from jigsawstack.exceptions import JigsawStackError
4
+ from jigsawstack import AsyncJigsawStack
5
+ import pytest
6
+ import asyncio
7
+ import logging
8
+ from jigsawstack import AsyncJigsawStack
9
+
10
+ logging.basicConfig(level=logging.INFO)
11
+ logger = logging.getLogger(__name__)
12
+
13
+
14
+ def test_text_to_speech():
15
+ async def _test():
16
+ client = AsyncJigsawStack()
17
+
18
+ """Test converting text to speech"""
19
+ try:
20
+ response = await client.audio.text_to_speech(
21
+ {
22
+ "text": "Hello world, this is a test of the JigsawStack text to speech API."
23
+ }
24
+ )
25
+ print("Text to speech response:", response)
26
+ assert response["success"] == True
27
+
28
+ except Exception as e:
29
+ print(f"Error in text_to_speech test: {e}")
30
+
31
+ asyncio.run(_test())
32
+
33
+
34
+ def test_speaker_voice_accents():
35
+ async def _test():
36
+ client = AsyncJigsawStack()
37
+
38
+ """Test getting available voice accents"""
39
+ try:
40
+ response = await client.audio.speaker_voice_accents()
41
+ print("Speaker voice accents response:", response)
42
+ assert response["success"] == True
43
+
44
+ except Exception as e:
45
+ print(f"Error in speaker voice accents test: {e}")
46
+
47
+
48
+ def test_create_clone():
49
+ async def _test():
50
+ client = AsyncJigsawStack()
51
+
52
+ """Test creating a voice clone with URL"""
53
+ try:
54
+ audio_url = (
55
+ "https://jigsawstack.com/audio/test.mp3" # Replace with an actual URL
56
+ )
57
+ clone_response_url = await client.audio.create_clone(
58
+ {"url": audio_url, "name": "Test Voice Clone URL"}
59
+ )
60
+
61
+ assert clone_response_url["success"] == True
62
+
63
+ clone_response_file_store_key = client.audio.create_clone(
64
+ {
65
+ "file_store_key": "hello_audio",
66
+ "name": "Test Voice Clone File Store Key",
67
+ }
68
+ )
69
+
70
+ assert clone_response_file_store_key["success"] == True
71
+
72
+ except Exception as e:
73
+ print(f"Error in voice_cloning test: {e}")
74
+
75
+ asyncio.run(_test())
76
+
77
+
78
+ def test_list_clones():
79
+ async def _test():
80
+ client = AsyncJigsawStack()
81
+ """Test listing voice clones"""
82
+ try:
83
+ # List available voice clones
84
+ clones_response = await client.audio.list_clones({"limit": 10, "page": 1})
85
+
86
+ assert clones_response["success"] == True
87
+
88
+ except Exception as e:
89
+ print(f"Error in voice_cloning test: {e}")
90
+
91
+ asyncio.run(_test())
92
+
93
+
94
+ def test_delete_clone():
95
+ async def _test():
96
+ client = AsyncJigsawStack()
97
+ """Test getting a voice clone"""
98
+ try:
99
+ create_clone_response = await client.audio.create_clone(
100
+ {"name": "Test Voice Clone URL", "file_store_key": "hello_audio"}
101
+ )
102
+ clones = await client.audio.list_clones({"limit": 10, "page": 1})
103
+ print("Clones:", clones)
104
+ clone_id = clones["data"][0]["id"]
105
+ delete_clone_response = await client.audio.delete_clone(clone_id)
106
+ print("Delete clone response:", delete_clone_response)
107
+ assert delete_clone_response["success"] == True
108
+
109
+ except Exception as e:
110
+ print(f"Error in list_clones test: {e}")
111
+
112
+ asyncio.run(_test())
@@ -1,22 +0,0 @@
1
- from unittest.mock import MagicMock
2
- import unittest
3
- from jigsawstack.exceptions import JigsawStackError
4
- from jigsawstack import AsyncJigsawStack
5
- import pytest
6
- import asyncio
7
- import logging
8
-
9
- logging.basicConfig(level=logging.INFO)
10
- logger = logging.getLogger(__name__)
11
-
12
-
13
- def test_async_speaker_voice_accents_response():
14
- async def _test():
15
- client = AsyncJigsawStack()
16
- try:
17
- result = await client.audio.speaker_voice_accents()
18
- assert result["success"] == True
19
- except JigsawStackError as e:
20
- pytest.fail(f"Unexpected JigsawStackError: {e}")
21
-
22
- asyncio.run(_test())
File without changes
File without changes