Skip to content

Commit 9a04d0a

Browse files
authored
Merge pull request #44 from JigsawStack/feat/file-handling
feat/file-handling
2 parents ad59208 + 09887c1 commit 9a04d0a

File tree

8 files changed

+235
-70
lines changed

8 files changed

+235
-70
lines changed

jigsawstack/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ def __init__(
100100
api_key=api_key,
101101
api_url=api_url,
102102
disable_request_logging=disable_request_logging,
103-
).translate
103+
)
104104

105105
self.prompt_engine = PromptEngine(
106106
api_key=api_key,
@@ -209,7 +209,7 @@ def __init__(
209209
api_key=api_key,
210210
api_url=api_url,
211211
disable_request_logging=disable_request_logging,
212-
).translate
212+
)
213213

214214
self.prompt_engine = AsyncPromptEngine(
215215
api_key=api_key,

jigsawstack/audio.py

Lines changed: 58 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
from typing import Any, Dict, List, cast, Union, Optional
1+
from typing import Any, Dict, List, cast, Union, Optional, overload
22
from typing_extensions import NotRequired, TypedDict
33
from .request import Request, RequestConfig
44
from .async_request import AsyncRequest, AsyncRequestConfig
55
from ._config import ClientConfig
66
from typing import Any, Dict, List, cast
77
from typing_extensions import NotRequired, TypedDict
88
from .custom_typing import SupportedAccents
9+
from .helpers import build_path
910

1011

1112
class TextToSpeechParams(TypedDict):
@@ -29,6 +30,7 @@ class SpeechToTextParams(TypedDict):
2930
by_speaker: NotRequired[bool]
3031
webhook_url: NotRequired[str]
3132
batch_size: NotRequired[int]
33+
chunk_duration: NotRequired[int]
3234

3335

3436
class ChunkParams(TypedDict):
@@ -63,16 +65,41 @@ def __init__(
6365
disable_request_logging=disable_request_logging,
6466
)
6567

66-
def speech_to_text(self, params: SpeechToTextParams) -> SpeechToTextResponse:
67-
path = "/ai/transcribe"
68+
@overload
69+
def speech_to_text(self, params: SpeechToTextParams) -> SpeechToTextResponse: ...
70+
@overload
71+
def speech_to_text(self, file: bytes, options: Optional[SpeechToTextParams] = None) -> SpeechToTextResponse: ...
72+
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
79+
resp = Request(
80+
config=self.config,
81+
path="/ai/transcribe",
82+
params=cast(Dict[Any, Any], blob),
83+
verb="post",
84+
).perform_with_content()
85+
return resp
86+
87+
options = options or {}
88+
path = build_path(base_path="/ai/transcribe", params=options)
89+
content_type = options.get("content_type", "application/octet-stream")
90+
headers = {"Content-Type": content_type}
91+
6892
resp = Request(
6993
config=self.config,
7094
path=path,
71-
params=cast(Dict[Any, Any], params),
95+
params=options,
96+
data=blob,
97+
headers=headers,
7298
verb="post",
7399
).perform_with_content()
74100
return resp
75101

102+
76103
def text_to_speech(self, params: TextToSpeechParams) -> TextToSpeechResponse:
77104
path = "/ai/tts"
78105
resp = Request(
@@ -110,12 +137,36 @@ def __init__(
110137
disable_request_logging=disable_request_logging,
111138
)
112139

113-
async def speech_to_text(self, params: SpeechToTextParams) -> SpeechToTextResponse:
114-
path = "/ai/transcribe"
140+
@overload
141+
async def speech_to_text(self, params: SpeechToTextParams) -> SpeechToTextResponse: ...
142+
@overload
143+
async def speech_to_text(self, file: bytes, options: Optional[SpeechToTextParams] = None) -> SpeechToTextResponse: ...
144+
145+
async def speech_to_text(
146+
self,
147+
blob: Union[SpeechToTextParams, bytes],
148+
options: Optional[SpeechToTextParams] = None,
149+
) -> SpeechToTextResponse:
150+
if isinstance(blob, dict):
151+
resp = await AsyncRequest(
152+
config=self.config,
153+
path="/ai/transcribe",
154+
params=cast(Dict[Any, Any], blob),
155+
verb="post",
156+
).perform_with_content()
157+
return resp
158+
159+
options = options or {}
160+
path = build_path(base_path="/ai/transcribe", params=options)
161+
content_type = options.get("content_type", "application/octet-stream")
162+
headers = {"Content-Type": content_type}
163+
115164
resp = await AsyncRequest(
116165
config=self.config,
117166
path=path,
118-
params=cast(Dict[Any, Any], params),
167+
params=options,
168+
data=blob,
169+
headers=headers,
119170
verb="post",
120171
).perform_with_content()
121172
return resp

jigsawstack/embedding.py

Lines changed: 58 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
from typing import Any, Dict, List, Union, cast, Literal
1+
from typing import Any, Dict, List, Union, cast, Literal, overload
22
from typing_extensions import NotRequired, TypedDict
33
from .request import Request, RequestConfig
44
from .async_request import AsyncRequest
55
from typing import List, Union
66
from ._config import ClientConfig
7+
from .helpers import build_path
78

89

910
class EmbeddingParams(TypedDict):
@@ -38,12 +39,37 @@ def __init__(
3839
disable_request_logging=disable_request_logging,
3940
)
4041

41-
def execute(self, params: EmbeddingParams) -> EmbeddingResponse:
42-
path = "/embedding"
42+
@overload
43+
def execute(self, params: EmbeddingParams) -> EmbeddingResponse: ...
44+
@overload
45+
def execute(self, file: bytes, options: EmbeddingParams = None) -> EmbeddingResponse: ...
46+
47+
def execute(
48+
self,
49+
blob: Union[EmbeddingParams, bytes],
50+
options: EmbeddingParams = None,
51+
) -> EmbeddingResponse:
52+
path="/embedding"
53+
if isinstance(blob, dict):
54+
resp = Request(
55+
config=self.config,
56+
path=path,
57+
params=cast(Dict[Any, Any], blob),
58+
verb="post",
59+
).perform_with_content()
60+
return resp
61+
62+
options = options or {}
63+
path = build_path(base_path=path, params=options)
64+
content_type = options.get("content_type", "application/octet-stream")
65+
_headers = {"Content-Type": content_type}
66+
4367
resp = Request(
4468
config=self.config,
4569
path=path,
46-
params=cast(Dict[Any, Any], params),
70+
params=options,
71+
data=blob,
72+
headers=_headers,
4773
verb="post",
4874
).perform_with_content()
4975
return resp
@@ -66,12 +92,37 @@ def __init__(
6692
disable_request_logging=disable_request_logging,
6793
)
6894

69-
async def execute(self, params: EmbeddingParams) -> EmbeddingResponse:
70-
path = "/embedding"
95+
@overload
96+
async def execute(self, params: EmbeddingParams) -> EmbeddingResponse: ...
97+
@overload
98+
async def execute(self, file: bytes, options: EmbeddingParams = None) -> EmbeddingResponse: ...
99+
100+
async def execute(
101+
self,
102+
blob: Union[EmbeddingParams, bytes],
103+
options: EmbeddingParams = None,
104+
) -> EmbeddingResponse:
105+
path="/embedding"
106+
if isinstance(blob, dict):
107+
resp = await AsyncRequest(
108+
config=self.config,
109+
path=path,
110+
params=cast(Dict[Any, Any], blob),
111+
verb="post",
112+
).perform_with_content()
113+
return resp
114+
115+
options = options or {}
116+
path = build_path(base_path=path, params=options)
117+
content_type = options.get("content_type", "application/octet-stream")
118+
_headers = {"Content-Type": content_type}
119+
71120
resp = await AsyncRequest(
72121
config=self.config,
73122
path=path,
74-
params=cast(Dict[Any, Any], params),
123+
params=options,
124+
data=blob,
125+
headers=_headers,
75126
verb="post",
76127
).perform_with_content()
77128
return resp

jigsawstack/helpers.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ def build_path(base_path: str, params: Optional[Dict[str, Union[str, int, bool]]
1717
return base_path
1818

1919
#remove None values from the parameters
20-
filtered_params = {k: v for k, v in params.items() if v is not None}
20+
filtered_params = { k: str(v).lower() if isinstance(v, bool) else v for k, v in params.items() if v is not None}
2121

2222
#encode the parameters
2323
return f"{base_path}?{urlencode(filtered_params)}" if filtered_params else base_path

jigsawstack/store.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,14 @@ class FileUploadParams(TypedDict):
1212
overwrite: NotRequired[bool]
1313
key: NotRequired[str]
1414
content_type: NotRequired[str]
15+
temp_public_url: NotRequired[bool]
16+
17+
class FileUploadResponse(TypedDict):
18+
key: str
19+
url: str
20+
size: int
21+
temp_public_url: NotRequired[str] # Optional, only if temp_public_url is set to True in params
22+
1523

1624
class Store(ClientConfig):
1725

@@ -30,7 +38,7 @@ def __init__(
3038
disable_request_logging=disable_request_logging,
3139
)
3240

33-
def upload(self, file: bytes, options: Union[FileUploadParams, None] = None) -> Any:
41+
def upload(self, file: bytes, options: Union[FileUploadParams, None] = None) -> FileUploadResponse:
3442
if options is None:
3543
options = {}
3644

@@ -87,7 +95,7 @@ def __init__(
8795
)
8896

8997

90-
async def upload(self, file: bytes, options: Union[FileUploadParams, None] = None) -> Any:
98+
async def upload(self, file: bytes, options: Union[FileUploadParams, None] = None) -> FileUploadResponse:
9199
if options is None:
92100
options = {}
93101

0 commit comments

Comments
 (0)