together 1.3.13__py3-none-any.whl → 1.4.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.
@@ -78,7 +78,7 @@ def parse_stream_helper(line: bytes) -> str | None:
78
78
  line = line[len(b"data: ") :]
79
79
  else:
80
80
  line = line[len(b"data:") :]
81
- if line.strip() == b"[DONE]":
81
+ if line.strip().upper() == b"[DONE]":
82
82
  # return here will cause GeneratorExit exception in urllib3
83
83
  # and it will close http connection with TCP Reset
84
84
  return None
@@ -620,7 +620,8 @@ class APIRequestor:
620
620
  self, result: requests.Response, stream: bool
621
621
  ) -> Tuple[TogetherResponse | Iterator[TogetherResponse], bool]:
622
622
  """Returns the response(s) and a bool indicating whether it is a stream."""
623
- if stream and "text/event-stream" in result.headers.get("Content-Type", ""):
623
+ content_type = result.headers.get("Content-Type", "")
624
+ if stream and "text/event-stream" in content_type:
624
625
  return (
625
626
  self._interpret_response_line(
626
627
  line, result.status_code, result.headers, stream=True
@@ -628,9 +629,13 @@ class APIRequestor:
628
629
  for line in parse_stream(result.iter_lines())
629
630
  ), True
630
631
  else:
632
+ if content_type in ["application/octet-stream", "audio/wav", "audio/mpeg"]:
633
+ content = result.content
634
+ else:
635
+ content = result.content.decode("utf-8")
631
636
  return (
632
637
  self._interpret_response_line(
633
- result.content.decode("utf-8"),
638
+ content,
634
639
  result.status_code,
635
640
  result.headers,
636
641
  stream=False,
@@ -670,7 +675,7 @@ class APIRequestor:
670
675
  )
671
676
 
672
677
  def _interpret_response_line(
673
- self, rbody: str, rcode: int, rheaders: Any, stream: bool
678
+ self, rbody: str | bytes, rcode: int, rheaders: Any, stream: bool
674
679
  ) -> TogetherResponse:
675
680
  # HTTP 204 response code does not have any content in the body.
676
681
  if rcode == 204:
@@ -684,13 +689,16 @@ class APIRequestor:
684
689
  )
685
690
 
686
691
  try:
687
- if "text/plain" in rheaders.get("Content-Type", ""):
688
- data: Dict[str, Any] = {"message": rbody}
692
+ content_type = rheaders.get("Content-Type", "")
693
+ if isinstance(rbody, bytes):
694
+ data: Dict[str, Any] | bytes = rbody
695
+ elif "text/plain" in content_type:
696
+ data = {"message": rbody}
689
697
  else:
690
698
  data = json.loads(rbody)
691
699
  except (JSONDecodeError, UnicodeDecodeError) as e:
692
700
  raise error.APIError(
693
- f"Error code: {rcode} -{rbody}",
701
+ f"Error code: {rcode} -{rbody if isinstance(rbody, str) else rbody.decode()}",
694
702
  http_status=rcode,
695
703
  headers=rheaders,
696
704
  ) from e
together/client.py CHANGED
@@ -19,6 +19,7 @@ class Together:
19
19
  models: resources.Models
20
20
  fine_tuning: resources.FineTuning
21
21
  rerank: resources.Rerank
22
+ audio: resources.Audio
22
23
 
23
24
  # client options
24
25
  client: TogetherClient
@@ -79,6 +80,7 @@ class Together:
79
80
  self.models = resources.Models(self.client)
80
81
  self.fine_tuning = resources.FineTuning(self.client)
81
82
  self.rerank = resources.Rerank(self.client)
83
+ self.audio = resources.Audio(self.client)
82
84
 
83
85
 
84
86
  class AsyncTogether:
@@ -6,6 +6,7 @@ from together.resources.finetune import AsyncFineTuning, FineTuning
6
6
  from together.resources.images import AsyncImages, Images
7
7
  from together.resources.models import AsyncModels, Models
8
8
  from together.resources.rerank import AsyncRerank, Rerank
9
+ from together.resources.audio import AsyncAudio, Audio
9
10
 
10
11
 
11
12
  __all__ = [
@@ -25,4 +26,6 @@ __all__ = [
25
26
  "Models",
26
27
  "AsyncRerank",
27
28
  "Rerank",
29
+ "AsyncAudio",
30
+ "Audio",
28
31
  ]
@@ -0,0 +1,24 @@
1
+ from functools import cached_property
2
+
3
+ from together.resources.audio.speech import AsyncSpeech, Speech
4
+ from together.types import (
5
+ TogetherClient,
6
+ )
7
+
8
+
9
+ class Audio:
10
+ def __init__(self, client: TogetherClient) -> None:
11
+ self._client = client
12
+
13
+ @cached_property
14
+ def speech(self) -> Speech:
15
+ return Speech(self._client)
16
+
17
+
18
+ class AsyncAudio:
19
+ def __init__(self, client: TogetherClient) -> None:
20
+ self._client = client
21
+
22
+ @cached_property
23
+ def speech(self) -> AsyncSpeech:
24
+ return AsyncSpeech(self._client)
@@ -0,0 +1,153 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Any, AsyncGenerator, Dict, Iterator, List, Union
4
+
5
+ from together.abstract import api_requestor
6
+ from together.together_response import TogetherResponse
7
+ from together.types import (
8
+ AudioSpeechRequest,
9
+ AudioResponseFormat,
10
+ AudioLanguage,
11
+ AudioResponseEncoding,
12
+ AudioSpeechStreamChunk,
13
+ AudioSpeechStreamEvent,
14
+ AudioSpeechStreamResponse,
15
+ TogetherClient,
16
+ TogetherRequest,
17
+ )
18
+
19
+
20
+ class Speech:
21
+ def __init__(self, client: TogetherClient) -> None:
22
+ self._client = client
23
+
24
+ def create(
25
+ self,
26
+ *,
27
+ model: str,
28
+ input: str,
29
+ voice: str | None = None,
30
+ response_format: str = "wav",
31
+ language: str = "en",
32
+ response_encoding: str = "pcm_f32le",
33
+ sample_rate: int = 44100,
34
+ stream: bool = False,
35
+ **kwargs: Any,
36
+ ) -> AudioSpeechStreamResponse:
37
+ """
38
+ Method to generate audio from input text using a specified model.
39
+
40
+ Args:
41
+ model (str): The name of the model to query.
42
+ input (str): Input text to generate the audio for.
43
+ voice (str, optional): The voice to use for generating the audio.
44
+ Defaults to None.
45
+ response_format (str, optional): The format of audio output.
46
+ Defaults to "wav".
47
+ language (str, optional): Language of input text.
48
+ Defaults to "en".
49
+ response_encoding (str, optional): Audio encoding of response.
50
+ Defaults to "pcm_f32le".
51
+ sample_rate (int, optional): Sampling rate to use for the output audio.
52
+ Defaults to 44100.
53
+ stream (bool, optional): If true, output is streamed for several characters at a time.
54
+ Defaults to False.
55
+
56
+ Returns:
57
+ Union[bytes, Iterator[AudioSpeechStreamChunk]]: The generated audio as bytes or an iterator over audio stream chunks.
58
+ """
59
+
60
+ requestor = api_requestor.APIRequestor(
61
+ client=self._client,
62
+ )
63
+
64
+ parameter_payload = AudioSpeechRequest(
65
+ model=model,
66
+ input=input,
67
+ voice=voice,
68
+ response_format=AudioResponseFormat(response_format),
69
+ language=AudioLanguage(language),
70
+ response_encoding=AudioResponseEncoding(response_encoding),
71
+ sample_rate=sample_rate,
72
+ stream=stream,
73
+ **kwargs,
74
+ ).model_dump(exclude_none=True)
75
+
76
+ response, streamed, _ = requestor.request(
77
+ options=TogetherRequest(
78
+ method="POST",
79
+ url="audio/speech",
80
+ params=parameter_payload,
81
+ ),
82
+ stream=stream,
83
+ )
84
+
85
+ return AudioSpeechStreamResponse(response=response)
86
+
87
+
88
+ class AsyncSpeech:
89
+ def __init__(self, client: TogetherClient) -> None:
90
+ self._client = client
91
+
92
+ async def create(
93
+ self,
94
+ *,
95
+ model: str,
96
+ input: str,
97
+ voice: str | None = None,
98
+ response_format: str = "wav",
99
+ language: str = "en",
100
+ response_encoding: str = "pcm_f32le",
101
+ sample_rate: int = 44100,
102
+ stream: bool = False,
103
+ **kwargs: Any,
104
+ ) -> AudioSpeechStreamResponse:
105
+ """
106
+ Async method to generate audio from input text using a specified model.
107
+
108
+ Args:
109
+ model (str): The name of the model to query.
110
+ input (str): Input text to generate the audio for.
111
+ voice (str, optional): The voice to use for generating the audio.
112
+ Defaults to None.
113
+ response_format (str, optional): The format of audio output.
114
+ Defaults to "wav".
115
+ language (str, optional): Language of input text.
116
+ Defaults to "en".
117
+ response_encoding (str, optional): Audio encoding of response.
118
+ Defaults to "pcm_f32le".
119
+ sample_rate (int, optional): Sampling rate to use for the output audio.
120
+ Defaults to 44100.
121
+ stream (bool, optional): If true, output is streamed for several characters at a time.
122
+ Defaults to False.
123
+
124
+ Returns:
125
+ Union[bytes, AsyncGenerator[AudioSpeechStreamChunk, None]]: The generated audio as bytes or an async generator over audio stream chunks.
126
+ """
127
+
128
+ requestor = api_requestor.APIRequestor(
129
+ client=self._client,
130
+ )
131
+
132
+ parameter_payload = AudioSpeechRequest(
133
+ model=model,
134
+ input=input,
135
+ voice=voice,
136
+ response_format=AudioResponseFormat(response_format),
137
+ language=AudioLanguage(language),
138
+ response_encoding=AudioResponseEncoding(response_encoding),
139
+ sample_rate=sample_rate,
140
+ stream=stream,
141
+ **kwargs,
142
+ ).model_dump(exclude_none=True)
143
+
144
+ response, _, _ = await requestor.arequest(
145
+ options=TogetherRequest(
146
+ method="POST",
147
+ url="audio/speech",
148
+ params=parameter_payload,
149
+ ),
150
+ stream=stream,
151
+ )
152
+
153
+ return AudioSpeechStreamResponse(response=response)
@@ -8,7 +8,7 @@ class TogetherResponse:
8
8
  API Response class. Stores headers and response data.
9
9
  """
10
10
 
11
- def __init__(self, data: Dict[str, Any], headers: Dict[str, Any]):
11
+ def __init__(self, data: Any, headers: Dict[str, Any]):
12
12
  self._headers = headers
13
13
  self.data = data
14
14
 
@@ -42,6 +42,15 @@ from together.types.rerank import (
42
42
  RerankRequest,
43
43
  RerankResponse,
44
44
  )
45
+ from together.types.audio_speech import (
46
+ AudioSpeechRequest,
47
+ AudioResponseFormat,
48
+ AudioLanguage,
49
+ AudioResponseEncoding,
50
+ AudioSpeechStreamChunk,
51
+ AudioSpeechStreamEvent,
52
+ AudioSpeechStreamResponse,
53
+ )
45
54
 
46
55
  __all__ = [
47
56
  "TogetherClient",
@@ -77,4 +86,11 @@ __all__ = [
77
86
  "RerankRequest",
78
87
  "RerankResponse",
79
88
  "FinetuneTrainingLimits",
89
+ "AudioSpeechRequest",
90
+ "AudioResponseFormat",
91
+ "AudioLanguage",
92
+ "AudioResponseEncoding",
93
+ "AudioSpeechStreamChunk",
94
+ "AudioSpeechStreamEvent",
95
+ "AudioSpeechStreamResponse",
80
96
  ]
@@ -0,0 +1,110 @@
1
+ from __future__ import annotations
2
+
3
+ from enum import Enum
4
+ from typing import Iterator
5
+ import threading
6
+
7
+ from pydantic import BaseModel, ConfigDict
8
+
9
+ from together.together_response import TogetherResponse
10
+ import base64
11
+
12
+
13
+ class AudioResponseFormat(str, Enum):
14
+ MP3 = "mp3"
15
+ WAV = "wav"
16
+ RAW = "raw"
17
+
18
+
19
+ class AudioLanguage(str, Enum):
20
+ EN = "en"
21
+ DE = "de"
22
+ FR = "fr"
23
+ ES = "es"
24
+ HI = "hi"
25
+ IT = "it"
26
+ JA = "ja"
27
+ KO = "ko"
28
+ NL = "nl"
29
+ PL = "pl"
30
+ PT = "pt"
31
+ RU = "ru"
32
+ SV = "sv"
33
+ TR = "tr"
34
+ ZH = "zh"
35
+
36
+
37
+ class AudioResponseEncoding(str, Enum):
38
+ PCM_F32LE = "pcm_f32le"
39
+ PCM_S16LE = "pcm_s16le"
40
+ PCM_MULAW = "pcm_mulaw"
41
+ PCM_ALAW = "pcm_alaw"
42
+
43
+
44
+ class AudioObjectType(str, Enum):
45
+ AUDIO_TTS_CHUNK = "audio.tts.chunk"
46
+
47
+
48
+ class StreamSentinelType(str, Enum):
49
+ DONE = "[DONE]"
50
+
51
+
52
+ class AudioSpeechRequest(BaseModel):
53
+ model: str
54
+ input: str
55
+ voice: str | None = None
56
+ response_format: AudioResponseFormat = AudioResponseFormat.MP3
57
+ language: AudioLanguage = AudioLanguage.EN
58
+ response_encoding: AudioResponseEncoding = AudioResponseEncoding.PCM_F32LE
59
+ sample_rate: int = 44100
60
+ stream: bool = False
61
+
62
+
63
+ class AudioSpeechStreamChunk(BaseModel):
64
+ object: AudioObjectType = AudioObjectType.AUDIO_TTS_CHUNK
65
+ model: str
66
+ b64: str
67
+
68
+
69
+ class AudioSpeechStreamEvent(BaseModel):
70
+ data: AudioSpeechStreamChunk
71
+
72
+
73
+ class StreamSentinel(BaseModel):
74
+ data: StreamSentinelType = StreamSentinelType.DONE
75
+
76
+
77
+ class AudioSpeechStreamEventResponse(BaseModel):
78
+ response: AudioSpeechStreamEvent | StreamSentinel
79
+
80
+
81
+ class AudioSpeechStreamResponse(BaseModel):
82
+
83
+ response: TogetherResponse | Iterator[TogetherResponse]
84
+
85
+ model_config = ConfigDict(arbitrary_types_allowed=True)
86
+
87
+ def stream_to_file(self, file_path: str) -> None:
88
+
89
+ if isinstance(self.response, TogetherResponse):
90
+ # save response to file
91
+ with open(file_path, "wb") as f:
92
+ f.write(self.response.data)
93
+
94
+ elif isinstance(self.response, Iterator):
95
+
96
+ with open(file_path, "wb") as f:
97
+ for chunk in self.response:
98
+
99
+ # Try to parse as stream chunk
100
+ stream_event_response = AudioSpeechStreamEventResponse(
101
+ response={"data": chunk.data}
102
+ )
103
+
104
+ if isinstance(stream_event_response.response, StreamSentinel):
105
+ break
106
+
107
+ # decode base64
108
+ audio = base64.b64decode(stream_event_response.response.data.b64)
109
+
110
+ f.write(audio)
@@ -1,15 +1,14 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: together
3
- Version: 1.3.13
3
+ Version: 1.4.0
4
4
  Summary: Python client for Together's Cloud Platform!
5
5
  License: Apache-2.0
6
6
  Author: Together AI
7
7
  Author-email: support@together.ai
8
- Requires-Python: >=3.8,<4.0
8
+ Requires-Python: >=3.9,<4.0
9
9
  Classifier: License :: OSI Approved :: Apache Software License
10
10
  Classifier: Operating System :: POSIX :: Linux
11
11
  Classifier: Programming Language :: Python :: 3
12
- Classifier: Programming Language :: Python :: 3.8
13
12
  Classifier: Programming Language :: Python :: 3.9
14
13
  Classifier: Programming Language :: Python :: 3.10
15
14
  Classifier: Programming Language :: Python :: 3.11
@@ -21,7 +20,7 @@ Requires-Dist: eval-type-backport (>=0.1.3,<0.3.0)
21
20
  Requires-Dist: filelock (>=3.13.1,<4.0.0)
22
21
  Requires-Dist: numpy (>=1.23.5) ; python_version < "3.12"
23
22
  Requires-Dist: numpy (>=1.26.0) ; python_version >= "3.12"
24
- Requires-Dist: pillow (>=10.3.0,<11.0.0)
23
+ Requires-Dist: pillow (>=11.1.0,<12.0.0)
25
24
  Requires-Dist: pyarrow (>=10.0.1)
26
25
  Requires-Dist: pydantic (>=2.6.3,<3.0.0)
27
26
  Requires-Dist: requests (>=2.31.0,<3.0.0)
@@ -245,6 +244,29 @@ embeddings = get_embeddings(input_texts, model='togethercomputer/m2-bert-80M-8k-
245
244
  print(embeddings)
246
245
  ```
247
246
 
247
+ ### Reranking
248
+
249
+ ```python
250
+ from typing import List
251
+ from together import Together
252
+
253
+ client = Together(api_key=os.environ.get("TOGETHER_API_KEY"))
254
+
255
+ def get_reranked_documents(query: str, documents: List[str], model: str, top_n: int = 3) -> List[str]:
256
+ outputs = client.rerank.create(model=model, query=query, documents=documents, top_n=top_n)
257
+ # sort by relevance score and returns the original docs
258
+ return [documents[i] for i in [x.index for x in sorted(outputs.results, key=lambda x: x.relevance_score, reverse=True)]]
259
+
260
+ query = "What is the capital of the United States?"
261
+ documents = ["New York","Washington, D.C.", "Los Angeles"]
262
+
263
+ reranked_documents = get_reranked_documents(query, documents, model='Salesforce/Llama-Rank-V1', top_n=1)
264
+
265
+ print(reranked_documents)
266
+ ```
267
+
268
+ Read more about Reranking [here](https://docs.together.ai/docs/rerank-overview).
269
+
248
270
  ### Files
249
271
 
250
272
  The files API is used for fine-tuning and allows developers to upload data to fine-tune on. It also has several methods to list all files, retrive files, and delete files. Please refer to our fine-tuning docs [here](https://docs.together.ai/docs/fine-tuning-python).
@@ -1,6 +1,6 @@
1
1
  together/__init__.py,sha256=B8T7ybZ7D6jJNRTuFDVjOFlImCNag8tNZXpZdXz7xNM,1530
2
2
  together/abstract/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
- together/abstract/api_requestor.py,sha256=-JpkI0QQKabCm8wPRF1AxAHaAffeR3cIlph69sw-BKw,25575
3
+ together/abstract/api_requestor.py,sha256=uIIj6D0wWlicm-KXopl4osT6ycE7hiPPXFkmYTSFDqw,25974
4
4
  together/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
5
  together/cli/api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
6
  together/cli/api/chat.py,sha256=2PHRb-9T-lUEKhUJFtc7SxJv3shCVx40gq_8pzfsewM,9234
@@ -11,7 +11,7 @@ together/cli/api/images.py,sha256=GADSeaNUHUVMtWovmccGuKc28IJ9E_v4vAEwYHJhu5o,26
11
11
  together/cli/api/models.py,sha256=xWEzu8ZpxM_Pz9KEjRPRVuv_v22RayYZ4QcgiezT5tE,1126
12
12
  together/cli/api/utils.py,sha256=IuqYWPnLI38_Bqd7lj8V_SnGdYc59pRmMbQmciS4FsM,1326
13
13
  together/cli/cli.py,sha256=RC0tgapkSOFjsRPg8p-8dx9D2LDzm8YmVCHUjk_aVyQ,1977
14
- together/client.py,sha256=mOlIFjjE9eSTb0o_weaKJwm8qvWNKHDiMmp8kQ7y68I,4946
14
+ together/client.py,sha256=EBeec9J9epkAZakm0GcZHmWjchEHOzT24XYqt6KZfwI,5023
15
15
  together/constants.py,sha256=0L2R8ftvls9eywQstSsrQcpHIkYsOo473vGw0okArN4,1359
16
16
  together/error.py,sha256=emjhTSsLwiZvW0v1EmYemjacCMtcFIKAXWWK_2IdP18,5419
17
17
  together/filemanager.py,sha256=QHhBn73oVFdgUpSYXYLmJzHJ9c5wYEMJC0ur6ZgDeYo,11269
@@ -23,7 +23,9 @@ together/legacy/files.py,sha256=qmAqMiNTPWb6WvLV5Tsv6kxGRfQ31q7OkHZNFwkw8v0,4082
23
23
  together/legacy/finetune.py,sha256=LENaqegeb1PszXDbAhTNPro7T3isz6X_IICIOKH7dKE,5114
24
24
  together/legacy/images.py,sha256=bJJRs-6C7-NexPyaeyHiYlHOU51yls5-QAiqtO4xrZU,626
25
25
  together/legacy/models.py,sha256=85ZN9Ids_FjdYNDRv5k7sgrtVWPKPHqkDplORtVUGHg,1087
26
- together/resources/__init__.py,sha256=7BLdBCNUbgi5mz30EFfdkdIYiGfFCkiUbdNzMY1-igY,792
26
+ together/resources/__init__.py,sha256=FCsSApph3FrNXB8RXv3smO6Xr86l7SmqtrVcUtKtyCI,878
27
+ together/resources/audio/__init__.py,sha256=e7xp0Lkp_nMAHXcuFHS7dLXP_YqTPMMZIilW1TW_sAI,551
28
+ together/resources/audio/speech.py,sha256=81ib_gIo-Rxoaipx2Pi9ZsKnOTjeFPwSlBrcUkyX5xk,5211
27
29
  together/resources/chat/__init__.py,sha256=RsTptdP8MeGjcdIjze896-J27cRvCbUoMft0X2BVlQ8,617
28
30
  together/resources/chat/completions.py,sha256=jYiNZsWa8RyEacL0VgxWj1egJ857oU4nxIY8uqGHcaU,14459
29
31
  together/resources/completions.py,sha256=5Wa-ZjPCxRcam6CDe7KgGYlTA7yJZMmd5TrRgGCL_ug,11726
@@ -33,9 +35,10 @@ together/resources/finetune.py,sha256=0UiN2jxxV_lQ9QSFKDjAioXVgPCIzb7biIJbcQj1oq
33
35
  together/resources/images.py,sha256=LQUjKPaFxWTqOAPnyF1Pp7Rz4NLOYhmoKwshpYiprEM,4923
34
36
  together/resources/models.py,sha256=2dtHhXAqTDOOpwSbYLzWcKTC0-m2Szlb7LDYvp7Jr4w,1786
35
37
  together/resources/rerank.py,sha256=3Ju_aRSyZ1s_3zCSNZnSnEJErUVmt2xa3M8z1nvejMA,3931
36
- together/together_response.py,sha256=MhczUCPem93cjX-A1TOAUrRj3sO-o3SLcEcTsZgVzQI,1319
37
- together/types/__init__.py,sha256=jEnnepzUeeYgCNTQIi4EWKaOEsZKYp0vEqzYmP8bK5o,1863
38
+ together/together_response.py,sha256=a3dgKMPDrlfKQwxYENfNt2T4l2vSZxRWMixhHSy-q3E,1308
39
+ together/types/__init__.py,sha256=TL_bbZwAu99S1A18j0arV2vIXEbtHRP8IddmSXx1NT0,2285
38
40
  together/types/abstract.py,sha256=1lFQI_3WjsR_t1128AeKW0aTk6EiM6Gh1J3ZuyLLPao,642
41
+ together/types/audio_speech.py,sha256=jlj8BZf3dkIDARF1P11fuenVLj4try8Yx4RN-EAkhOU,2609
39
42
  together/types/chat_completions.py,sha256=tIHQzB1N1DsUl3WojsrfErqxVmcI_eweGVp_gbf6dp8,4914
40
43
  together/types/common.py,sha256=kxZ-N9xtBsGYZBmbIWnZ0rfT3Pn8PFB7sAbp3iv96pw,1525
41
44
  together/types/completions.py,sha256=o3FR5ixsTUj-a3pmOUzbSQg-hESVhpqrC9UD__VCqr4,2971
@@ -52,8 +55,8 @@ together/utils/api_helpers.py,sha256=RSF7SRhbjHzroMOSWAXscflByM1r1ta_1SpxkAT22iE
52
55
  together/utils/files.py,sha256=4SxxrTYfVoWvsD0n7O73LVjexAxYCWvXUBgmzrJY5-s,14169
53
56
  together/utils/tools.py,sha256=3-lXWP3cBCzOVSZg9tr5zOT1jaVeKAKVWxO2fcXZTh8,1788
54
57
  together/version.py,sha256=p03ivHyE0SyWU4jAnRTBi_sOwywVWoZPU4g2gzRgG-Y,126
55
- together-1.3.13.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
56
- together-1.3.13.dist-info/METADATA,sha256=Tll4ZfzcorFyzhzxE50rIhk8ZEQd3Od4QGRz7nYuFfQ,11842
57
- together-1.3.13.dist-info/WHEEL,sha256=IYZQI976HJqqOpQU6PHkJ8fb3tMNBFjg-Cn-pwAbaFM,88
58
- together-1.3.13.dist-info/entry_points.txt,sha256=G-b5NKW6lUUf1V1fH8IPTBb7jXnK7lhbX9H1zTEJXPs,50
59
- together-1.3.13.dist-info/RECORD,,
58
+ together-1.4.0.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
59
+ together-1.4.0.dist-info/METADATA,sha256=v1LquKItktOESHCPhDiIBR9eFXwCcTJQZYGNihiSJ6g,12649
60
+ together-1.4.0.dist-info/WHEEL,sha256=IYZQI976HJqqOpQU6PHkJ8fb3tMNBFjg-Cn-pwAbaFM,88
61
+ together-1.4.0.dist-info/entry_points.txt,sha256=G-b5NKW6lUUf1V1fH8IPTBb7jXnK7lhbX9H1zTEJXPs,50
62
+ together-1.4.0.dist-info/RECORD,,