together 1.5.28__tar.gz → 1.5.30__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.
- {together-1.5.28 → together-1.5.30}/PKG-INFO +2 -1
- {together-1.5.28 → together-1.5.30}/pyproject.toml +2 -1
- {together-1.5.28 → together-1.5.30}/src/together/abstract/api_requestor.py +44 -3
- {together-1.5.28 → together-1.5.30}/src/together/cli/api/endpoints.py +49 -2
- {together-1.5.28 → together-1.5.30}/src/together/resources/audio/__init__.py +9 -0
- {together-1.5.28 → together-1.5.30}/src/together/resources/audio/speech.py +8 -2
- {together-1.5.28 → together-1.5.30}/src/together/resources/audio/transcriptions.py +20 -2
- together-1.5.30/src/together/resources/audio/voices.py +65 -0
- {together-1.5.28 → together-1.5.30}/src/together/resources/endpoints.py +98 -7
- {together-1.5.28 → together-1.5.30}/src/together/resources/images.py +4 -10
- {together-1.5.28 → together-1.5.30}/src/together/types/__init__.py +4 -0
- together-1.5.30/src/together/types/audio_speech.py +311 -0
- {together-1.5.28 → together-1.5.30}/src/together/types/images.py +0 -2
- {together-1.5.28 → together-1.5.30}/src/together/utils/files.py +175 -52
- together-1.5.28/src/together/types/audio_speech.py +0 -198
- {together-1.5.28 → together-1.5.30}/LICENSE +0 -0
- {together-1.5.28 → together-1.5.30}/README.md +0 -0
- {together-1.5.28 → together-1.5.30}/src/together/__init__.py +0 -0
- {together-1.5.28 → together-1.5.30}/src/together/abstract/__init__.py +0 -0
- {together-1.5.28 → together-1.5.30}/src/together/cli/__init__.py +0 -0
- {together-1.5.28 → together-1.5.30}/src/together/cli/api/__init__.py +0 -0
- {together-1.5.28 → together-1.5.30}/src/together/cli/api/chat.py +0 -0
- {together-1.5.28 → together-1.5.30}/src/together/cli/api/completions.py +0 -0
- {together-1.5.28 → together-1.5.30}/src/together/cli/api/evaluation.py +0 -0
- {together-1.5.28 → together-1.5.30}/src/together/cli/api/files.py +0 -0
- {together-1.5.28 → together-1.5.30}/src/together/cli/api/finetune.py +0 -0
- {together-1.5.28 → together-1.5.30}/src/together/cli/api/images.py +0 -0
- {together-1.5.28 → together-1.5.30}/src/together/cli/api/models.py +0 -0
- {together-1.5.28 → together-1.5.30}/src/together/cli/api/utils.py +0 -0
- {together-1.5.28 → together-1.5.30}/src/together/cli/cli.py +0 -0
- {together-1.5.28 → together-1.5.30}/src/together/client.py +0 -0
- {together-1.5.28 → together-1.5.30}/src/together/constants.py +0 -0
- {together-1.5.28 → together-1.5.30}/src/together/error.py +0 -0
- {together-1.5.28 → together-1.5.30}/src/together/filemanager.py +0 -0
- {together-1.5.28 → together-1.5.30}/src/together/legacy/__init__.py +0 -0
- {together-1.5.28 → together-1.5.30}/src/together/legacy/base.py +0 -0
- {together-1.5.28 → together-1.5.30}/src/together/legacy/complete.py +0 -0
- {together-1.5.28 → together-1.5.30}/src/together/legacy/embeddings.py +0 -0
- {together-1.5.28 → together-1.5.30}/src/together/legacy/files.py +0 -0
- {together-1.5.28 → together-1.5.30}/src/together/legacy/finetune.py +0 -0
- {together-1.5.28 → together-1.5.30}/src/together/legacy/images.py +0 -0
- {together-1.5.28 → together-1.5.30}/src/together/legacy/models.py +0 -0
- {together-1.5.28 → together-1.5.30}/src/together/resources/__init__.py +0 -0
- {together-1.5.28 → together-1.5.30}/src/together/resources/audio/translations.py +0 -0
- {together-1.5.28 → together-1.5.30}/src/together/resources/batch.py +0 -0
- {together-1.5.28 → together-1.5.30}/src/together/resources/chat/__init__.py +0 -0
- {together-1.5.28 → together-1.5.30}/src/together/resources/chat/completions.py +0 -0
- {together-1.5.28 → together-1.5.30}/src/together/resources/code_interpreter.py +0 -0
- {together-1.5.28 → together-1.5.30}/src/together/resources/completions.py +0 -0
- {together-1.5.28 → together-1.5.30}/src/together/resources/embeddings.py +0 -0
- {together-1.5.28 → together-1.5.30}/src/together/resources/evaluation.py +0 -0
- {together-1.5.28 → together-1.5.30}/src/together/resources/files.py +0 -0
- {together-1.5.28 → together-1.5.30}/src/together/resources/finetune.py +0 -0
- {together-1.5.28 → together-1.5.30}/src/together/resources/models.py +0 -0
- {together-1.5.28 → together-1.5.30}/src/together/resources/rerank.py +0 -0
- {together-1.5.28 → together-1.5.30}/src/together/resources/videos.py +0 -0
- {together-1.5.28 → together-1.5.30}/src/together/together_response.py +0 -0
- {together-1.5.28 → together-1.5.30}/src/together/types/abstract.py +0 -0
- {together-1.5.28 → together-1.5.30}/src/together/types/batch.py +0 -0
- {together-1.5.28 → together-1.5.30}/src/together/types/chat_completions.py +0 -0
- {together-1.5.28 → together-1.5.30}/src/together/types/code_interpreter.py +0 -0
- {together-1.5.28 → together-1.5.30}/src/together/types/common.py +0 -0
- {together-1.5.28 → together-1.5.30}/src/together/types/completions.py +0 -0
- {together-1.5.28 → together-1.5.30}/src/together/types/embeddings.py +0 -0
- {together-1.5.28 → together-1.5.30}/src/together/types/endpoints.py +0 -0
- {together-1.5.28 → together-1.5.30}/src/together/types/error.py +0 -0
- {together-1.5.28 → together-1.5.30}/src/together/types/evaluation.py +0 -0
- {together-1.5.28 → together-1.5.30}/src/together/types/files.py +0 -0
- {together-1.5.28 → together-1.5.30}/src/together/types/finetune.py +0 -0
- {together-1.5.28 → together-1.5.30}/src/together/types/models.py +0 -0
- {together-1.5.28 → together-1.5.30}/src/together/types/rerank.py +0 -0
- {together-1.5.28 → together-1.5.30}/src/together/types/videos.py +0 -0
- {together-1.5.28 → together-1.5.30}/src/together/utils/__init__.py +0 -0
- {together-1.5.28 → together-1.5.30}/src/together/utils/_log.py +0 -0
- {together-1.5.28 → together-1.5.30}/src/together/utils/api_helpers.py +0 -0
- {together-1.5.28 → together-1.5.30}/src/together/utils/tools.py +0 -0
- {together-1.5.28 → together-1.5.30}/src/together/version.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: together
|
|
3
|
-
Version: 1.5.
|
|
3
|
+
Version: 1.5.30
|
|
4
4
|
Summary: Python client for Together's Cloud Platform!
|
|
5
5
|
License: Apache-2.0
|
|
6
6
|
License-File: LICENSE
|
|
@@ -17,6 +17,7 @@ Classifier: Programming Language :: Python :: 3.13
|
|
|
17
17
|
Classifier: Programming Language :: Python :: 3.14
|
|
18
18
|
Provides-Extra: pyarrow
|
|
19
19
|
Requires-Dist: aiohttp (>=3.9.3,<4.0.0)
|
|
20
|
+
Requires-Dist: black (>=25.9.0,<26.0.0)
|
|
20
21
|
Requires-Dist: click (>=8.1.7,<9.0.0)
|
|
21
22
|
Requires-Dist: eval-type-backport (>=0.1.3,<0.3.0)
|
|
22
23
|
Requires-Dist: filelock (>=3.13.1,<4.0.0)
|
|
@@ -12,7 +12,7 @@ build-backend = "poetry.masonry.api"
|
|
|
12
12
|
|
|
13
13
|
[tool.poetry]
|
|
14
14
|
name = "together"
|
|
15
|
-
version = "1.5.
|
|
15
|
+
version = "1.5.30"
|
|
16
16
|
authors = ["Together AI <support@together.ai>"]
|
|
17
17
|
description = "Python client for Together's Cloud Platform!"
|
|
18
18
|
readme = "README.md"
|
|
@@ -43,6 +43,7 @@ numpy = [
|
|
|
43
43
|
{ version = ">=1.26.0", python = ">=3.12" },
|
|
44
44
|
]
|
|
45
45
|
pillow = "^11.1.0"
|
|
46
|
+
black = "^25.9.0"
|
|
46
47
|
|
|
47
48
|
[tool.poetry.extras]
|
|
48
49
|
pyarrow = ["pyarrow"]
|
|
@@ -619,14 +619,29 @@ class APIRequestor:
|
|
|
619
619
|
) -> Tuple[TogetherResponse | Iterator[TogetherResponse], bool]:
|
|
620
620
|
"""Returns the response(s) and a bool indicating whether it is a stream."""
|
|
621
621
|
content_type = result.headers.get("Content-Type", "")
|
|
622
|
+
|
|
622
623
|
if stream and "text/event-stream" in content_type:
|
|
624
|
+
# SSE format streaming
|
|
623
625
|
return (
|
|
624
626
|
self._interpret_response_line(
|
|
625
627
|
line, result.status_code, result.headers, stream=True
|
|
626
628
|
)
|
|
627
629
|
for line in parse_stream(result.iter_lines())
|
|
628
630
|
), True
|
|
631
|
+
elif stream and content_type in [
|
|
632
|
+
"audio/wav",
|
|
633
|
+
"audio/mpeg",
|
|
634
|
+
"application/octet-stream",
|
|
635
|
+
]:
|
|
636
|
+
# Binary audio streaming - return chunks as binary data
|
|
637
|
+
def binary_stream_generator() -> Iterator[TogetherResponse]:
|
|
638
|
+
for chunk in result.iter_content(chunk_size=8192):
|
|
639
|
+
if chunk: # Skip empty chunks
|
|
640
|
+
yield TogetherResponse(chunk, dict(result.headers))
|
|
641
|
+
|
|
642
|
+
return binary_stream_generator(), True
|
|
629
643
|
else:
|
|
644
|
+
# Non-streaming response
|
|
630
645
|
if content_type in ["application/octet-stream", "audio/wav", "audio/mpeg"]:
|
|
631
646
|
content = result.content
|
|
632
647
|
else:
|
|
@@ -648,23 +663,49 @@ class APIRequestor:
|
|
|
648
663
|
| tuple[TogetherResponse, bool]
|
|
649
664
|
):
|
|
650
665
|
"""Returns the response(s) and a bool indicating whether it is a stream."""
|
|
651
|
-
|
|
666
|
+
content_type = result.headers.get("Content-Type", "")
|
|
667
|
+
|
|
668
|
+
if stream and "text/event-stream" in content_type:
|
|
669
|
+
# SSE format streaming
|
|
652
670
|
return (
|
|
653
671
|
self._interpret_response_line(
|
|
654
672
|
line, result.status, result.headers, stream=True
|
|
655
673
|
)
|
|
656
674
|
async for line in parse_stream_async(result.content)
|
|
657
675
|
), True
|
|
676
|
+
elif stream and content_type in [
|
|
677
|
+
"audio/wav",
|
|
678
|
+
"audio/mpeg",
|
|
679
|
+
"application/octet-stream",
|
|
680
|
+
]:
|
|
681
|
+
# Binary audio streaming - return chunks as binary data
|
|
682
|
+
async def binary_stream_generator() -> (
|
|
683
|
+
AsyncGenerator[TogetherResponse, None]
|
|
684
|
+
):
|
|
685
|
+
async for chunk in result.content.iter_chunked(8192):
|
|
686
|
+
if chunk: # Skip empty chunks
|
|
687
|
+
yield TogetherResponse(chunk, dict(result.headers))
|
|
688
|
+
|
|
689
|
+
return binary_stream_generator(), True
|
|
658
690
|
else:
|
|
691
|
+
# Non-streaming response
|
|
659
692
|
try:
|
|
660
|
-
await result.read()
|
|
693
|
+
content = await result.read()
|
|
661
694
|
except (aiohttp.ServerTimeoutError, asyncio.TimeoutError) as e:
|
|
662
695
|
raise error.Timeout("Request timed out") from e
|
|
663
696
|
except aiohttp.ClientError as e:
|
|
664
697
|
utils.log_warn(e, body=result.content)
|
|
698
|
+
|
|
699
|
+
if content_type in ["application/octet-stream", "audio/wav", "audio/mpeg"]:
|
|
700
|
+
# Binary content - keep as bytes
|
|
701
|
+
response_content: str | bytes = content
|
|
702
|
+
else:
|
|
703
|
+
# Text content - decode to string
|
|
704
|
+
response_content = content.decode("utf-8")
|
|
705
|
+
|
|
665
706
|
return (
|
|
666
707
|
self._interpret_response_line(
|
|
667
|
-
|
|
708
|
+
response_content,
|
|
668
709
|
result.status,
|
|
669
710
|
result.headers,
|
|
670
711
|
stream=False,
|
|
@@ -132,6 +132,10 @@ def endpoints(ctx: click.Context) -> None:
|
|
|
132
132
|
type=int,
|
|
133
133
|
help="Number of minutes of inactivity after which the endpoint will be automatically stopped. Set to 0 to disable.",
|
|
134
134
|
)
|
|
135
|
+
@click.option(
|
|
136
|
+
"--availability-zone",
|
|
137
|
+
help="Start endpoint in specified availability zone (e.g., us-central-4b)",
|
|
138
|
+
)
|
|
135
139
|
@click.option(
|
|
136
140
|
"--wait",
|
|
137
141
|
is_flag=True,
|
|
@@ -152,6 +156,7 @@ def create(
|
|
|
152
156
|
no_speculative_decoding: bool,
|
|
153
157
|
no_auto_start: bool,
|
|
154
158
|
inactive_timeout: int | None,
|
|
159
|
+
availability_zone: str | None,
|
|
155
160
|
wait: bool,
|
|
156
161
|
) -> None:
|
|
157
162
|
"""Create a new dedicated inference endpoint."""
|
|
@@ -177,6 +182,7 @@ def create(
|
|
|
177
182
|
disable_speculative_decoding=no_speculative_decoding,
|
|
178
183
|
state="STOPPED" if no_auto_start else "STARTED",
|
|
179
184
|
inactive_timeout=inactive_timeout,
|
|
185
|
+
availability_zone=availability_zone,
|
|
180
186
|
)
|
|
181
187
|
except InvalidRequestError as e:
|
|
182
188
|
print_api_error(e)
|
|
@@ -203,6 +209,8 @@ def create(
|
|
|
203
209
|
click.echo(" Auto-start: disabled", err=True)
|
|
204
210
|
if inactive_timeout is not None:
|
|
205
211
|
click.echo(f" Inactive timeout: {inactive_timeout} minutes", err=True)
|
|
212
|
+
if availability_zone:
|
|
213
|
+
click.echo(f" Availability zone: {availability_zone}", err=True)
|
|
206
214
|
|
|
207
215
|
click.echo(f"Endpoint created successfully, id: {response.id}", err=True)
|
|
208
216
|
|
|
@@ -337,13 +345,30 @@ def delete(client: Together, endpoint_id: str) -> None:
|
|
|
337
345
|
type=click.Choice(["dedicated", "serverless"]),
|
|
338
346
|
help="Filter by endpoint type",
|
|
339
347
|
)
|
|
348
|
+
@click.option(
|
|
349
|
+
"--mine",
|
|
350
|
+
type=click.BOOL,
|
|
351
|
+
default=None,
|
|
352
|
+
help="true (only mine), default=all",
|
|
353
|
+
)
|
|
354
|
+
@click.option(
|
|
355
|
+
"--usage-type",
|
|
356
|
+
type=click.Choice(["on-demand", "reserved"]),
|
|
357
|
+
help="Filter by endpoint usage type",
|
|
358
|
+
)
|
|
340
359
|
@click.pass_obj
|
|
341
360
|
@handle_api_errors
|
|
342
361
|
def list(
|
|
343
|
-
client: Together,
|
|
362
|
+
client: Together,
|
|
363
|
+
json: bool,
|
|
364
|
+
type: Literal["dedicated", "serverless"] | None,
|
|
365
|
+
usage_type: Literal["on-demand", "reserved"] | None,
|
|
366
|
+
mine: bool | None,
|
|
344
367
|
) -> None:
|
|
345
368
|
"""List all inference endpoints (includes both dedicated and serverless endpoints)."""
|
|
346
|
-
endpoints: List[ListEndpoint] = client.endpoints.list(
|
|
369
|
+
endpoints: List[ListEndpoint] = client.endpoints.list(
|
|
370
|
+
type=type, usage_type=usage_type, mine=mine
|
|
371
|
+
)
|
|
347
372
|
|
|
348
373
|
if not endpoints:
|
|
349
374
|
click.echo("No dedicated endpoints found", err=True)
|
|
@@ -432,3 +457,25 @@ def update(
|
|
|
432
457
|
|
|
433
458
|
click.echo("Successfully updated endpoint", err=True)
|
|
434
459
|
click.echo(endpoint_id)
|
|
460
|
+
|
|
461
|
+
|
|
462
|
+
@endpoints.command()
|
|
463
|
+
@click.option("--json", is_flag=True, help="Print output in JSON format")
|
|
464
|
+
@click.pass_obj
|
|
465
|
+
@handle_api_errors
|
|
466
|
+
def availability_zones(client: Together, json: bool) -> None:
|
|
467
|
+
"""List all availability zones."""
|
|
468
|
+
avzones = client.endpoints.list_avzones()
|
|
469
|
+
|
|
470
|
+
if not avzones:
|
|
471
|
+
click.echo("No availability zones found", err=True)
|
|
472
|
+
return
|
|
473
|
+
|
|
474
|
+
if json:
|
|
475
|
+
import json as json_lib
|
|
476
|
+
|
|
477
|
+
click.echo(json_lib.dumps({"avzones": avzones}, indent=2))
|
|
478
|
+
else:
|
|
479
|
+
click.echo("Available zones:", err=True)
|
|
480
|
+
for availability_zone in sorted(avzones):
|
|
481
|
+
click.echo(f" {availability_zone}")
|
|
@@ -3,6 +3,7 @@ from functools import cached_property
|
|
|
3
3
|
from together.resources.audio.speech import AsyncSpeech, Speech
|
|
4
4
|
from together.resources.audio.transcriptions import AsyncTranscriptions, Transcriptions
|
|
5
5
|
from together.resources.audio.translations import AsyncTranslations, Translations
|
|
6
|
+
from together.resources.audio.voices import AsyncVoices, Voices
|
|
6
7
|
from together.types import (
|
|
7
8
|
TogetherClient,
|
|
8
9
|
)
|
|
@@ -24,6 +25,10 @@ class Audio:
|
|
|
24
25
|
def translations(self) -> Translations:
|
|
25
26
|
return Translations(self._client)
|
|
26
27
|
|
|
28
|
+
@cached_property
|
|
29
|
+
def voices(self) -> Voices:
|
|
30
|
+
return Voices(self._client)
|
|
31
|
+
|
|
27
32
|
|
|
28
33
|
class AsyncAudio:
|
|
29
34
|
def __init__(self, client: TogetherClient) -> None:
|
|
@@ -40,3 +45,7 @@ class AsyncAudio:
|
|
|
40
45
|
@cached_property
|
|
41
46
|
def translations(self) -> AsyncTranslations:
|
|
42
47
|
return AsyncTranslations(self._client)
|
|
48
|
+
|
|
49
|
+
@cached_property
|
|
50
|
+
def voices(self) -> AsyncVoices:
|
|
51
|
+
return AsyncVoices(self._client)
|
|
@@ -30,7 +30,7 @@ class Speech:
|
|
|
30
30
|
response_format: str = "wav",
|
|
31
31
|
language: str = "en",
|
|
32
32
|
response_encoding: str = "pcm_f32le",
|
|
33
|
-
sample_rate: int =
|
|
33
|
+
sample_rate: int | None = None,
|
|
34
34
|
stream: bool = False,
|
|
35
35
|
**kwargs: Any,
|
|
36
36
|
) -> AudioSpeechStreamResponse:
|
|
@@ -49,7 +49,7 @@ class Speech:
|
|
|
49
49
|
response_encoding (str, optional): Audio encoding of response.
|
|
50
50
|
Defaults to "pcm_f32le".
|
|
51
51
|
sample_rate (int, optional): Sampling rate to use for the output audio.
|
|
52
|
-
Defaults to
|
|
52
|
+
Defaults to None. If not provided, the default sampling rate for the model will be used.
|
|
53
53
|
stream (bool, optional): If true, output is streamed for several characters at a time.
|
|
54
54
|
Defaults to False.
|
|
55
55
|
|
|
@@ -57,6 +57,12 @@ class Speech:
|
|
|
57
57
|
Union[bytes, Iterator[AudioSpeechStreamChunk]]: The generated audio as bytes or an iterator over audio stream chunks.
|
|
58
58
|
"""
|
|
59
59
|
|
|
60
|
+
if sample_rate is None:
|
|
61
|
+
if "cartesia" in model:
|
|
62
|
+
sample_rate = 44100
|
|
63
|
+
else:
|
|
64
|
+
sample_rate = 24000
|
|
65
|
+
|
|
60
66
|
requestor = api_requestor.APIRequestor(
|
|
61
67
|
client=self._client,
|
|
62
68
|
)
|
|
@@ -30,6 +30,7 @@ class Transcriptions:
|
|
|
30
30
|
timestamp_granularities: Optional[
|
|
31
31
|
Union[str, AudioTimestampGranularities]
|
|
32
32
|
] = None,
|
|
33
|
+
diarize: bool = False,
|
|
33
34
|
**kwargs: Any,
|
|
34
35
|
) -> Union[AudioTranscriptionResponse, AudioTranscriptionVerboseResponse]:
|
|
35
36
|
"""
|
|
@@ -52,7 +53,11 @@ class Transcriptions:
|
|
|
52
53
|
timestamp_granularities: The timestamp granularities to populate for this
|
|
53
54
|
transcription. response_format must be set verbose_json to use timestamp
|
|
54
55
|
granularities. Either or both of these options are supported: word, or segment.
|
|
55
|
-
|
|
56
|
+
diarize: Whether to enable speaker diarization. When enabled, you will get the speaker id for each word in the transcription.
|
|
57
|
+
In the response, in the words array, you will get the speaker id for each word.
|
|
58
|
+
In addition, we also return the speaker_segments array which contains the speaker id for each speaker segment along with the start and end time of the segment along with all the words in the segment.
|
|
59
|
+
You can use the speaker_id to group the words by speaker.
|
|
60
|
+
You can use the speaker_segments to get the start and end time of each speaker segment.
|
|
56
61
|
Returns:
|
|
57
62
|
The transcribed text in the requested format.
|
|
58
63
|
"""
|
|
@@ -103,6 +108,9 @@ class Transcriptions:
|
|
|
103
108
|
else timestamp_granularities
|
|
104
109
|
)
|
|
105
110
|
|
|
111
|
+
if diarize:
|
|
112
|
+
params_data["diarize"] = diarize
|
|
113
|
+
|
|
106
114
|
# Add any additional kwargs
|
|
107
115
|
# Convert boolean values to lowercase strings for proper form encoding
|
|
108
116
|
for key, value in kwargs.items():
|
|
@@ -135,6 +143,7 @@ class Transcriptions:
|
|
|
135
143
|
if (
|
|
136
144
|
response_format == "verbose_json"
|
|
137
145
|
or response_format == AudioTranscriptionResponseFormat.VERBOSE_JSON
|
|
146
|
+
or diarize
|
|
138
147
|
):
|
|
139
148
|
# Create response with model validation that preserves extra fields
|
|
140
149
|
return AudioTranscriptionVerboseResponse.model_validate(response.data)
|
|
@@ -158,6 +167,7 @@ class AsyncTranscriptions:
|
|
|
158
167
|
timestamp_granularities: Optional[
|
|
159
168
|
Union[str, AudioTimestampGranularities]
|
|
160
169
|
] = None,
|
|
170
|
+
diarize: bool = False,
|
|
161
171
|
**kwargs: Any,
|
|
162
172
|
) -> Union[AudioTranscriptionResponse, AudioTranscriptionVerboseResponse]:
|
|
163
173
|
"""
|
|
@@ -180,7 +190,11 @@ class AsyncTranscriptions:
|
|
|
180
190
|
timestamp_granularities: The timestamp granularities to populate for this
|
|
181
191
|
transcription. response_format must be set verbose_json to use timestamp
|
|
182
192
|
granularities. Either or both of these options are supported: word, or segment.
|
|
183
|
-
|
|
193
|
+
diarize: Whether to enable speaker diarization. When enabled, you will get the speaker id for each word in the transcription.
|
|
194
|
+
In the response, in the words array, you will get the speaker id for each word.
|
|
195
|
+
In addition, we also return the speaker_segments array which contains the speaker id for each speaker segment along with the start and end time of the segment along with all the words in the segment.
|
|
196
|
+
You can use the speaker_id to group the words by speaker.
|
|
197
|
+
You can use the speaker_segments to get the start and end time of each speaker segment.
|
|
184
198
|
Returns:
|
|
185
199
|
The transcribed text in the requested format.
|
|
186
200
|
"""
|
|
@@ -239,6 +253,9 @@ class AsyncTranscriptions:
|
|
|
239
253
|
)
|
|
240
254
|
)
|
|
241
255
|
|
|
256
|
+
if diarize:
|
|
257
|
+
params_data["diarize"] = diarize
|
|
258
|
+
|
|
242
259
|
# Add any additional kwargs
|
|
243
260
|
# Convert boolean values to lowercase strings for proper form encoding
|
|
244
261
|
for key, value in kwargs.items():
|
|
@@ -271,6 +288,7 @@ class AsyncTranscriptions:
|
|
|
271
288
|
if (
|
|
272
289
|
response_format == "verbose_json"
|
|
273
290
|
or response_format == AudioTranscriptionResponseFormat.VERBOSE_JSON
|
|
291
|
+
or diarize
|
|
274
292
|
):
|
|
275
293
|
# Create response with model validation that preserves extra fields
|
|
276
294
|
return AudioTranscriptionVerboseResponse.model_validate(response.data)
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from together.abstract import api_requestor
|
|
4
|
+
from together.together_response import TogetherResponse
|
|
5
|
+
from together.types import (
|
|
6
|
+
TogetherClient,
|
|
7
|
+
TogetherRequest,
|
|
8
|
+
VoiceListResponse,
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class Voices:
|
|
13
|
+
def __init__(self, client: TogetherClient) -> None:
|
|
14
|
+
self._client = client
|
|
15
|
+
|
|
16
|
+
def list(self) -> VoiceListResponse:
|
|
17
|
+
"""
|
|
18
|
+
Method to return list of available voices on the API
|
|
19
|
+
|
|
20
|
+
Returns:
|
|
21
|
+
VoiceListResponse: Response containing models and their available voices
|
|
22
|
+
"""
|
|
23
|
+
requestor = api_requestor.APIRequestor(
|
|
24
|
+
client=self._client,
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
response, _, _ = requestor.request(
|
|
28
|
+
options=TogetherRequest(
|
|
29
|
+
method="GET",
|
|
30
|
+
url="voices",
|
|
31
|
+
),
|
|
32
|
+
stream=False,
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
assert isinstance(response, TogetherResponse)
|
|
36
|
+
|
|
37
|
+
return VoiceListResponse(**response.data)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class AsyncVoices:
|
|
41
|
+
def __init__(self, client: TogetherClient) -> None:
|
|
42
|
+
self._client = client
|
|
43
|
+
|
|
44
|
+
async def list(self) -> VoiceListResponse:
|
|
45
|
+
"""
|
|
46
|
+
Async method to return list of available voices on the API
|
|
47
|
+
|
|
48
|
+
Returns:
|
|
49
|
+
VoiceListResponse: Response containing models and their available voices
|
|
50
|
+
"""
|
|
51
|
+
requestor = api_requestor.APIRequestor(
|
|
52
|
+
client=self._client,
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
response, _, _ = await requestor.arequest(
|
|
56
|
+
options=TogetherRequest(
|
|
57
|
+
method="GET",
|
|
58
|
+
url="voices",
|
|
59
|
+
),
|
|
60
|
+
stream=False,
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
assert isinstance(response, TogetherResponse)
|
|
64
|
+
|
|
65
|
+
return VoiceListResponse(**response.data)
|
|
@@ -13,13 +13,18 @@ class Endpoints:
|
|
|
13
13
|
self._client = client
|
|
14
14
|
|
|
15
15
|
def list(
|
|
16
|
-
self,
|
|
16
|
+
self,
|
|
17
|
+
type: Optional[Literal["dedicated", "serverless"]] = None,
|
|
18
|
+
usage_type: Optional[Literal["on-demand", "reserved"]] = None,
|
|
19
|
+
mine: Optional[bool] = None,
|
|
17
20
|
) -> List[ListEndpoint]:
|
|
18
21
|
"""
|
|
19
|
-
List all endpoints, can be filtered by type.
|
|
22
|
+
List all endpoints, can be filtered by endpoint type and ownership.
|
|
20
23
|
|
|
21
24
|
Args:
|
|
22
|
-
type (str, optional): Filter endpoints by type ("dedicated" or "serverless"). Defaults to None.
|
|
25
|
+
type (str, optional): Filter endpoints by endpoint type ("dedicated" or "serverless"). Defaults to None.
|
|
26
|
+
usage_type (str, optional): Filter endpoints by usage type ("on-demand" or "reserved"). Defaults to None.
|
|
27
|
+
mine (bool, optional): If True, return only endpoints owned by the caller. Defaults to None.
|
|
23
28
|
|
|
24
29
|
Returns:
|
|
25
30
|
List[ListEndpoint]: List of endpoint objects
|
|
@@ -28,9 +33,20 @@ class Endpoints:
|
|
|
28
33
|
client=self._client,
|
|
29
34
|
)
|
|
30
35
|
|
|
31
|
-
params
|
|
36
|
+
params: Dict[
|
|
37
|
+
str,
|
|
38
|
+
Union[
|
|
39
|
+
Literal["dedicated", "serverless"],
|
|
40
|
+
Literal["on-demand", "reserved"],
|
|
41
|
+
bool,
|
|
42
|
+
],
|
|
43
|
+
] = {}
|
|
32
44
|
if type is not None:
|
|
33
45
|
params["type"] = type
|
|
46
|
+
if usage_type is not None:
|
|
47
|
+
params["usage_type"] = usage_type
|
|
48
|
+
if mine is not None:
|
|
49
|
+
params["mine"] = mine
|
|
34
50
|
|
|
35
51
|
response, _, _ = requestor.request(
|
|
36
52
|
options=TogetherRequest(
|
|
@@ -60,6 +76,7 @@ class Endpoints:
|
|
|
60
76
|
disable_speculative_decoding: bool = True,
|
|
61
77
|
state: Literal["STARTED", "STOPPED"] = "STARTED",
|
|
62
78
|
inactive_timeout: Optional[int] = None,
|
|
79
|
+
availability_zone: Optional[str] = None,
|
|
63
80
|
) -> DedicatedEndpoint:
|
|
64
81
|
"""
|
|
65
82
|
Create a new dedicated endpoint.
|
|
@@ -74,6 +91,7 @@ class Endpoints:
|
|
|
74
91
|
disable_speculative_decoding (bool, optional): Whether to disable speculative decoding. Defaults to False.
|
|
75
92
|
state (str, optional): The desired state of the endpoint. Defaults to "STARTED".
|
|
76
93
|
inactive_timeout (int, optional): The number of minutes of inactivity after which the endpoint will be automatically stopped. Set to 0 to disable automatic timeout.
|
|
94
|
+
availability_zone (str, optional): Start endpoint in specified availability zone (e.g., us-central-4b).
|
|
77
95
|
|
|
78
96
|
Returns:
|
|
79
97
|
DedicatedEndpoint: Object containing endpoint information
|
|
@@ -100,6 +118,9 @@ class Endpoints:
|
|
|
100
118
|
if inactive_timeout is not None:
|
|
101
119
|
data["inactive_timeout"] = inactive_timeout
|
|
102
120
|
|
|
121
|
+
if availability_zone is not None:
|
|
122
|
+
data["availability_zone"] = availability_zone
|
|
123
|
+
|
|
103
124
|
response, _, _ = requestor.request(
|
|
104
125
|
options=TogetherRequest(
|
|
105
126
|
method="POST",
|
|
@@ -257,19 +278,49 @@ class Endpoints:
|
|
|
257
278
|
|
|
258
279
|
return [HardwareWithStatus(**item) for item in response.data["data"]]
|
|
259
280
|
|
|
281
|
+
def list_avzones(self) -> List[str]:
|
|
282
|
+
"""
|
|
283
|
+
List all available availability zones.
|
|
284
|
+
|
|
285
|
+
Returns:
|
|
286
|
+
List[str]: List of unique availability zones
|
|
287
|
+
"""
|
|
288
|
+
requestor = api_requestor.APIRequestor(
|
|
289
|
+
client=self._client,
|
|
290
|
+
)
|
|
291
|
+
|
|
292
|
+
response, _, _ = requestor.request(
|
|
293
|
+
options=TogetherRequest(
|
|
294
|
+
method="GET",
|
|
295
|
+
url="clusters/availability-zones",
|
|
296
|
+
),
|
|
297
|
+
stream=False,
|
|
298
|
+
)
|
|
299
|
+
|
|
300
|
+
assert isinstance(response, TogetherResponse)
|
|
301
|
+
assert isinstance(response.data, dict)
|
|
302
|
+
assert isinstance(response.data["avzones"], list)
|
|
303
|
+
|
|
304
|
+
return response.data["avzones"]
|
|
305
|
+
|
|
260
306
|
|
|
261
307
|
class AsyncEndpoints:
|
|
262
308
|
def __init__(self, client: TogetherClient) -> None:
|
|
263
309
|
self._client = client
|
|
264
310
|
|
|
265
311
|
async def list(
|
|
266
|
-
self,
|
|
312
|
+
self,
|
|
313
|
+
type: Optional[Literal["dedicated", "serverless"]] = None,
|
|
314
|
+
usage_type: Optional[Literal["on-demand", "reserved"]] = None,
|
|
315
|
+
mine: Optional[bool] = None,
|
|
267
316
|
) -> List[ListEndpoint]:
|
|
268
317
|
"""
|
|
269
|
-
List all endpoints, can be filtered by type.
|
|
318
|
+
List all endpoints, can be filtered by type and ownership.
|
|
270
319
|
|
|
271
320
|
Args:
|
|
272
321
|
type (str, optional): Filter endpoints by type ("dedicated" or "serverless"). Defaults to None.
|
|
322
|
+
usage_type (str, optional): Filter endpoints by usage type ("on-demand" or "reserved"). Defaults to None.
|
|
323
|
+
mine (bool, optional): If True, return only endpoints owned by the caller. Defaults to None.
|
|
273
324
|
|
|
274
325
|
Returns:
|
|
275
326
|
List[ListEndpoint]: List of endpoint objects
|
|
@@ -278,9 +329,20 @@ class AsyncEndpoints:
|
|
|
278
329
|
client=self._client,
|
|
279
330
|
)
|
|
280
331
|
|
|
281
|
-
params
|
|
332
|
+
params: Dict[
|
|
333
|
+
str,
|
|
334
|
+
Union[
|
|
335
|
+
Literal["dedicated", "serverless"],
|
|
336
|
+
Literal["on-demand", "reserved"],
|
|
337
|
+
bool,
|
|
338
|
+
],
|
|
339
|
+
] = {}
|
|
282
340
|
if type is not None:
|
|
283
341
|
params["type"] = type
|
|
342
|
+
if usage_type is not None:
|
|
343
|
+
params["usage_type"] = usage_type
|
|
344
|
+
if mine is not None:
|
|
345
|
+
params["mine"] = mine
|
|
284
346
|
|
|
285
347
|
response, _, _ = await requestor.arequest(
|
|
286
348
|
options=TogetherRequest(
|
|
@@ -308,6 +370,7 @@ class AsyncEndpoints:
|
|
|
308
370
|
disable_speculative_decoding: bool = True,
|
|
309
371
|
state: Literal["STARTED", "STOPPED"] = "STARTED",
|
|
310
372
|
inactive_timeout: Optional[int] = None,
|
|
373
|
+
availability_zone: Optional[str] = None,
|
|
311
374
|
) -> DedicatedEndpoint:
|
|
312
375
|
"""
|
|
313
376
|
Create a new dedicated endpoint.
|
|
@@ -348,6 +411,9 @@ class AsyncEndpoints:
|
|
|
348
411
|
if inactive_timeout is not None:
|
|
349
412
|
data["inactive_timeout"] = inactive_timeout
|
|
350
413
|
|
|
414
|
+
if availability_zone is not None:
|
|
415
|
+
data["availability_zone"] = availability_zone
|
|
416
|
+
|
|
351
417
|
response, _, _ = await requestor.arequest(
|
|
352
418
|
options=TogetherRequest(
|
|
353
419
|
method="POST",
|
|
@@ -506,3 +572,28 @@ class AsyncEndpoints:
|
|
|
506
572
|
assert isinstance(response.data["data"], list)
|
|
507
573
|
|
|
508
574
|
return [HardwareWithStatus(**item) for item in response.data["data"]]
|
|
575
|
+
|
|
576
|
+
async def list_avzones(self) -> List[str]:
|
|
577
|
+
"""
|
|
578
|
+
List all availability zones.
|
|
579
|
+
|
|
580
|
+
Returns:
|
|
581
|
+
List[str]: List of unique availability zones
|
|
582
|
+
"""
|
|
583
|
+
requestor = api_requestor.APIRequestor(
|
|
584
|
+
client=self._client,
|
|
585
|
+
)
|
|
586
|
+
|
|
587
|
+
response, _, _ = await requestor.arequest(
|
|
588
|
+
options=TogetherRequest(
|
|
589
|
+
method="GET",
|
|
590
|
+
url="clusters/availability-zones",
|
|
591
|
+
),
|
|
592
|
+
stream=False,
|
|
593
|
+
)
|
|
594
|
+
|
|
595
|
+
assert isinstance(response, TogetherResponse)
|
|
596
|
+
assert isinstance(response.data, dict)
|
|
597
|
+
assert isinstance(response.data["avzones"], list)
|
|
598
|
+
|
|
599
|
+
return response.data["avzones"]
|
|
@@ -21,7 +21,6 @@ class Images:
|
|
|
21
21
|
*,
|
|
22
22
|
prompt: str,
|
|
23
23
|
model: str,
|
|
24
|
-
steps: int | None = 20,
|
|
25
24
|
seed: int | None = None,
|
|
26
25
|
n: int | None = 1,
|
|
27
26
|
height: int | None = 1024,
|
|
@@ -37,8 +36,6 @@ class Images:
|
|
|
37
36
|
|
|
38
37
|
model (str, optional): The model to use for image generation.
|
|
39
38
|
|
|
40
|
-
steps (int, optional): Number of generation steps. Defaults to 20
|
|
41
|
-
|
|
42
39
|
seed (int, optional): Seed used for generation. Can be used to reproduce image generations.
|
|
43
40
|
Defaults to None.
|
|
44
41
|
|
|
@@ -51,7 +48,8 @@ class Images:
|
|
|
51
48
|
negative_prompt (str, optional): The prompt or prompts not to guide the image generation.
|
|
52
49
|
Defaults to None
|
|
53
50
|
|
|
54
|
-
|
|
51
|
+
**kwargs: Additional parameters like steps (int, optional): Number of generation steps,
|
|
52
|
+
image_base64 (str, optional): Reference image used for generation, etc.
|
|
55
53
|
|
|
56
54
|
Returns:
|
|
57
55
|
ImageResponse: Object containing image data
|
|
@@ -64,7 +62,6 @@ class Images:
|
|
|
64
62
|
parameter_payload = ImageRequest(
|
|
65
63
|
prompt=prompt,
|
|
66
64
|
model=model,
|
|
67
|
-
steps=steps,
|
|
68
65
|
seed=seed,
|
|
69
66
|
n=n,
|
|
70
67
|
height=height,
|
|
@@ -96,7 +93,6 @@ class AsyncImages:
|
|
|
96
93
|
*,
|
|
97
94
|
prompt: str,
|
|
98
95
|
model: str,
|
|
99
|
-
steps: int | None = 20,
|
|
100
96
|
seed: int | None = None,
|
|
101
97
|
n: int | None = 1,
|
|
102
98
|
height: int | None = 1024,
|
|
@@ -112,8 +108,6 @@ class AsyncImages:
|
|
|
112
108
|
|
|
113
109
|
model (str, optional): The model to use for image generation.
|
|
114
110
|
|
|
115
|
-
steps (int, optional): Number of generation steps. Defaults to 20
|
|
116
|
-
|
|
117
111
|
seed (int, optional): Seed used for generation. Can be used to reproduce image generations.
|
|
118
112
|
Defaults to None.
|
|
119
113
|
|
|
@@ -126,7 +120,8 @@ class AsyncImages:
|
|
|
126
120
|
negative_prompt (str, optional): The prompt or prompts not to guide the image generation.
|
|
127
121
|
Defaults to None
|
|
128
122
|
|
|
129
|
-
|
|
123
|
+
**kwargs: Additional parameters like steps (int, optional): Number of generation steps,
|
|
124
|
+
image_base64 (str, optional): Reference image used for generation, etc.
|
|
130
125
|
|
|
131
126
|
Returns:
|
|
132
127
|
ImageResponse: Object containing image data
|
|
@@ -139,7 +134,6 @@ class AsyncImages:
|
|
|
139
134
|
parameter_payload = ImageRequest(
|
|
140
135
|
prompt=prompt,
|
|
141
136
|
model=model,
|
|
142
|
-
steps=steps,
|
|
143
137
|
seed=seed,
|
|
144
138
|
n=n,
|
|
145
139
|
height=height,
|
|
@@ -15,6 +15,8 @@ from together.types.audio_speech import (
|
|
|
15
15
|
AudioTranslationVerboseResponse,
|
|
16
16
|
AudioTranscriptionResponseFormat,
|
|
17
17
|
AudioTimestampGranularities,
|
|
18
|
+
ModelVoices,
|
|
19
|
+
VoiceListResponse,
|
|
18
20
|
)
|
|
19
21
|
from together.types.chat_completions import (
|
|
20
22
|
ChatCompletionChunk,
|
|
@@ -140,6 +142,8 @@ __all__ = [
|
|
|
140
142
|
"AudioTranslationVerboseResponse",
|
|
141
143
|
"AudioTranscriptionResponseFormat",
|
|
142
144
|
"AudioTimestampGranularities",
|
|
145
|
+
"ModelVoices",
|
|
146
|
+
"VoiceListResponse",
|
|
143
147
|
"DedicatedEndpoint",
|
|
144
148
|
"ListEndpoint",
|
|
145
149
|
"Autoscaling",
|