together 1.4.4__py3-none-any.whl → 1.4.6__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.
- together/cli/api/endpoints.py +20 -1
- together/cli/api/models.py +20 -7
- together/client.py +9 -1
- together/resources/endpoints.py +24 -4
- together/resources/models.py +67 -8
- together/utils/api_helpers.py +40 -0
- {together-1.4.4.dist-info → together-1.4.6.dist-info}/METADATA +1 -1
- {together-1.4.4.dist-info → together-1.4.6.dist-info}/RECORD +11 -11
- {together-1.4.4.dist-info → together-1.4.6.dist-info}/LICENSE +0 -0
- {together-1.4.4.dist-info → together-1.4.6.dist-info}/WHEEL +0 -0
- {together-1.4.4.dist-info → together-1.4.6.dist-info}/entry_points.txt +0 -0
together/cli/api/endpoints.py
CHANGED
|
@@ -127,6 +127,11 @@ def endpoints(ctx: click.Context) -> None:
|
|
|
127
127
|
is_flag=True,
|
|
128
128
|
help="Create the endpoint in STOPPED state instead of auto-starting it",
|
|
129
129
|
)
|
|
130
|
+
@click.option(
|
|
131
|
+
"--inactive-timeout",
|
|
132
|
+
type=int,
|
|
133
|
+
help="Number of minutes of inactivity after which the endpoint will be automatically stopped. Set to 0 to disable.",
|
|
134
|
+
)
|
|
130
135
|
@click.option(
|
|
131
136
|
"--wait",
|
|
132
137
|
is_flag=True,
|
|
@@ -146,6 +151,7 @@ def create(
|
|
|
146
151
|
no_prompt_cache: bool,
|
|
147
152
|
no_speculative_decoding: bool,
|
|
148
153
|
no_auto_start: bool,
|
|
154
|
+
inactive_timeout: int | None,
|
|
149
155
|
wait: bool,
|
|
150
156
|
) -> None:
|
|
151
157
|
"""Create a new dedicated inference endpoint."""
|
|
@@ -170,6 +176,7 @@ def create(
|
|
|
170
176
|
disable_prompt_cache=no_prompt_cache,
|
|
171
177
|
disable_speculative_decoding=no_speculative_decoding,
|
|
172
178
|
state="STOPPED" if no_auto_start else "STARTED",
|
|
179
|
+
inactive_timeout=inactive_timeout,
|
|
173
180
|
)
|
|
174
181
|
except InvalidRequestError as e:
|
|
175
182
|
print_api_error(e)
|
|
@@ -194,6 +201,8 @@ def create(
|
|
|
194
201
|
click.echo(" Speculative decoding: disabled", err=True)
|
|
195
202
|
if no_auto_start:
|
|
196
203
|
click.echo(" Auto-start: disabled", err=True)
|
|
204
|
+
if inactive_timeout is not None:
|
|
205
|
+
click.echo(f" Inactive timeout: {inactive_timeout} minutes", err=True)
|
|
197
206
|
|
|
198
207
|
click.echo(f"Endpoint created successfully, id: {response.id}", err=True)
|
|
199
208
|
|
|
@@ -371,6 +380,11 @@ def list(
|
|
|
371
380
|
type=int,
|
|
372
381
|
help="New maximum number of replicas to scale up to",
|
|
373
382
|
)
|
|
383
|
+
@click.option(
|
|
384
|
+
"--inactive-timeout",
|
|
385
|
+
type=int,
|
|
386
|
+
help="Number of minutes of inactivity after which the endpoint will be automatically stopped. Set to 0 to disable.",
|
|
387
|
+
)
|
|
374
388
|
@click.pass_obj
|
|
375
389
|
@handle_api_errors
|
|
376
390
|
def update(
|
|
@@ -379,9 +393,10 @@ def update(
|
|
|
379
393
|
display_name: str | None,
|
|
380
394
|
min_replicas: int | None,
|
|
381
395
|
max_replicas: int | None,
|
|
396
|
+
inactive_timeout: int | None,
|
|
382
397
|
) -> None:
|
|
383
398
|
"""Update a dedicated inference endpoint's configuration."""
|
|
384
|
-
if not any([display_name, min_replicas, max_replicas]):
|
|
399
|
+
if not any([display_name, min_replicas, max_replicas, inactive_timeout]):
|
|
385
400
|
click.echo("Error: At least one update option must be specified", err=True)
|
|
386
401
|
sys.exit(1)
|
|
387
402
|
|
|
@@ -400,6 +415,8 @@ def update(
|
|
|
400
415
|
if min_replicas is not None and max_replicas is not None:
|
|
401
416
|
kwargs["min_replicas"] = min_replicas
|
|
402
417
|
kwargs["max_replicas"] = max_replicas
|
|
418
|
+
if inactive_timeout is not None:
|
|
419
|
+
kwargs["inactive_timeout"] = inactive_timeout
|
|
403
420
|
|
|
404
421
|
_response = client.endpoints.update(endpoint_id, **kwargs)
|
|
405
422
|
|
|
@@ -410,6 +427,8 @@ def update(
|
|
|
410
427
|
if min_replicas is not None and max_replicas is not None:
|
|
411
428
|
click.echo(f" Min replicas: {min_replicas}", err=True)
|
|
412
429
|
click.echo(f" Max replicas: {max_replicas}", err=True)
|
|
430
|
+
if inactive_timeout is not None:
|
|
431
|
+
click.echo(f" Inactive timeout: {inactive_timeout} minutes", err=True)
|
|
413
432
|
|
|
414
433
|
click.echo("Successfully updated endpoint", err=True)
|
|
415
434
|
click.echo(endpoint_id)
|
together/cli/api/models.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
import json as json_lib
|
|
2
2
|
|
|
3
3
|
import click
|
|
4
4
|
from tabulate import tabulate
|
|
@@ -15,12 +15,22 @@ def models(ctx: click.Context) -> None:
|
|
|
15
15
|
|
|
16
16
|
|
|
17
17
|
@models.command()
|
|
18
|
+
@click.option(
|
|
19
|
+
"--type",
|
|
20
|
+
type=click.Choice(["dedicated"]),
|
|
21
|
+
help="Filter models by type (dedicated: models that can be deployed as dedicated endpoints)",
|
|
22
|
+
)
|
|
23
|
+
@click.option(
|
|
24
|
+
"--json",
|
|
25
|
+
is_flag=True,
|
|
26
|
+
help="Output in JSON format",
|
|
27
|
+
)
|
|
18
28
|
@click.pass_context
|
|
19
|
-
def list(ctx: click.Context) -> None:
|
|
29
|
+
def list(ctx: click.Context, type: str | None, json: bool) -> None:
|
|
20
30
|
"""List models"""
|
|
21
31
|
client: Together = ctx.obj
|
|
22
32
|
|
|
23
|
-
response = client.models.list()
|
|
33
|
+
response = client.models.list(dedicated=(type == "dedicated"))
|
|
24
34
|
|
|
25
35
|
display_list = []
|
|
26
36
|
|
|
@@ -28,15 +38,18 @@ def list(ctx: click.Context) -> None:
|
|
|
28
38
|
for model in response:
|
|
29
39
|
display_list.append(
|
|
30
40
|
{
|
|
31
|
-
"ID":
|
|
32
|
-
"Name":
|
|
41
|
+
"ID": model.id,
|
|
42
|
+
"Name": model.display_name,
|
|
33
43
|
"Organization": model.organization,
|
|
34
44
|
"Type": model.type,
|
|
35
45
|
"Context Length": model.context_length,
|
|
36
|
-
"License":
|
|
46
|
+
"License": model.license,
|
|
37
47
|
"Input per 1M token": model.pricing.input,
|
|
38
48
|
"Output per 1M token": model.pricing.output,
|
|
39
49
|
}
|
|
40
50
|
)
|
|
41
51
|
|
|
42
|
-
|
|
52
|
+
if json:
|
|
53
|
+
click.echo(json_lib.dumps(display_list, indent=2))
|
|
54
|
+
else:
|
|
55
|
+
click.echo(tabulate(display_list, headers="keys", tablefmt="plain"))
|
together/client.py
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import os
|
|
4
|
-
|
|
4
|
+
import sys
|
|
5
|
+
from typing import Dict, TYPE_CHECKING
|
|
5
6
|
|
|
6
7
|
from together import resources
|
|
7
8
|
from together.constants import BASE_URL, MAX_RETRIES, TIMEOUT_SECS
|
|
8
9
|
from together.error import AuthenticationError
|
|
9
10
|
from together.types import TogetherClient
|
|
10
11
|
from together.utils import enforce_trailing_slash
|
|
12
|
+
from together.utils.api_helpers import get_google_colab_secret
|
|
11
13
|
|
|
12
14
|
|
|
13
15
|
class Together:
|
|
@@ -44,6 +46,9 @@ class Together:
|
|
|
44
46
|
if not api_key:
|
|
45
47
|
api_key = os.environ.get("TOGETHER_API_KEY")
|
|
46
48
|
|
|
49
|
+
if not api_key and "google.colab" in sys.modules:
|
|
50
|
+
api_key = get_google_colab_secret("TOGETHER_API_KEY")
|
|
51
|
+
|
|
47
52
|
if not api_key:
|
|
48
53
|
raise AuthenticationError(
|
|
49
54
|
"The api_key client option must be set either by passing api_key to the client or by setting the "
|
|
@@ -117,6 +122,9 @@ class AsyncTogether:
|
|
|
117
122
|
if not api_key:
|
|
118
123
|
api_key = os.environ.get("TOGETHER_API_KEY")
|
|
119
124
|
|
|
125
|
+
if not api_key and "google.colab" in sys.modules:
|
|
126
|
+
api_key = get_google_colab_secret("TOGETHER_API_KEY")
|
|
127
|
+
|
|
120
128
|
if not api_key:
|
|
121
129
|
raise AuthenticationError(
|
|
122
130
|
"The api_key client option must be set either by passing api_key to the client or by setting the "
|
together/resources/endpoints.py
CHANGED
|
@@ -59,6 +59,7 @@ class Endpoints:
|
|
|
59
59
|
disable_prompt_cache: bool = False,
|
|
60
60
|
disable_speculative_decoding: bool = False,
|
|
61
61
|
state: Literal["STARTED", "STOPPED"] = "STARTED",
|
|
62
|
+
inactive_timeout: Optional[int] = None,
|
|
62
63
|
) -> DedicatedEndpoint:
|
|
63
64
|
"""
|
|
64
65
|
Create a new dedicated endpoint.
|
|
@@ -72,6 +73,7 @@ class Endpoints:
|
|
|
72
73
|
disable_prompt_cache (bool, optional): Whether to disable the prompt cache. Defaults to False.
|
|
73
74
|
disable_speculative_decoding (bool, optional): Whether to disable speculative decoding. Defaults to False.
|
|
74
75
|
state (str, optional): The desired state of the endpoint. Defaults to "STARTED".
|
|
76
|
+
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.
|
|
75
77
|
|
|
76
78
|
Returns:
|
|
77
79
|
DedicatedEndpoint: Object containing endpoint information
|
|
@@ -80,7 +82,7 @@ class Endpoints:
|
|
|
80
82
|
client=self._client,
|
|
81
83
|
)
|
|
82
84
|
|
|
83
|
-
data: Dict[str, Union[str, bool, Dict[str, int]]] = {
|
|
85
|
+
data: Dict[str, Union[str, bool, Dict[str, int], int]] = {
|
|
84
86
|
"model": model,
|
|
85
87
|
"hardware": hardware,
|
|
86
88
|
"autoscaling": {
|
|
@@ -95,6 +97,9 @@ class Endpoints:
|
|
|
95
97
|
if display_name is not None:
|
|
96
98
|
data["display_name"] = display_name
|
|
97
99
|
|
|
100
|
+
if inactive_timeout is not None:
|
|
101
|
+
data["inactive_timeout"] = inactive_timeout
|
|
102
|
+
|
|
98
103
|
response, _, _ = requestor.request(
|
|
99
104
|
options=TogetherRequest(
|
|
100
105
|
method="POST",
|
|
@@ -161,6 +166,7 @@ class Endpoints:
|
|
|
161
166
|
max_replicas: Optional[int] = None,
|
|
162
167
|
state: Optional[Literal["STARTED", "STOPPED"]] = None,
|
|
163
168
|
display_name: Optional[str] = None,
|
|
169
|
+
inactive_timeout: Optional[int] = None,
|
|
164
170
|
) -> DedicatedEndpoint:
|
|
165
171
|
"""
|
|
166
172
|
Update an endpoint's configuration.
|
|
@@ -171,6 +177,7 @@ class Endpoints:
|
|
|
171
177
|
max_replicas (int, optional): The maximum number of replicas to scale up to
|
|
172
178
|
state (str, optional): The desired state of the endpoint ("STARTED" or "STOPPED")
|
|
173
179
|
display_name (str, optional): A human-readable name for the endpoint
|
|
180
|
+
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.
|
|
174
181
|
|
|
175
182
|
Returns:
|
|
176
183
|
DedicatedEndpoint: Object containing endpoint information
|
|
@@ -179,7 +186,7 @@ class Endpoints:
|
|
|
179
186
|
client=self._client,
|
|
180
187
|
)
|
|
181
188
|
|
|
182
|
-
data: Dict[str, Union[str, Dict[str, int]]] = {}
|
|
189
|
+
data: Dict[str, Union[str, Dict[str, int], int]] = {}
|
|
183
190
|
|
|
184
191
|
if min_replicas is not None or max_replicas is not None:
|
|
185
192
|
current_min = min_replicas
|
|
@@ -200,6 +207,9 @@ class Endpoints:
|
|
|
200
207
|
if display_name is not None:
|
|
201
208
|
data["display_name"] = display_name
|
|
202
209
|
|
|
210
|
+
if inactive_timeout is not None:
|
|
211
|
+
data["inactive_timeout"] = inactive_timeout
|
|
212
|
+
|
|
203
213
|
response, _, _ = requestor.request(
|
|
204
214
|
options=TogetherRequest(
|
|
205
215
|
method="PATCH",
|
|
@@ -297,6 +307,7 @@ class AsyncEndpoints:
|
|
|
297
307
|
disable_prompt_cache: bool = False,
|
|
298
308
|
disable_speculative_decoding: bool = False,
|
|
299
309
|
state: Literal["STARTED", "STOPPED"] = "STARTED",
|
|
310
|
+
inactive_timeout: Optional[int] = None,
|
|
300
311
|
) -> DedicatedEndpoint:
|
|
301
312
|
"""
|
|
302
313
|
Create a new dedicated endpoint.
|
|
@@ -310,6 +321,7 @@ class AsyncEndpoints:
|
|
|
310
321
|
disable_prompt_cache (bool, optional): Whether to disable the prompt cache. Defaults to False.
|
|
311
322
|
disable_speculative_decoding (bool, optional): Whether to disable speculative decoding. Defaults to False.
|
|
312
323
|
state (str, optional): The desired state of the endpoint. Defaults to "STARTED".
|
|
324
|
+
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.
|
|
313
325
|
|
|
314
326
|
Returns:
|
|
315
327
|
DedicatedEndpoint: Object containing endpoint information
|
|
@@ -318,7 +330,7 @@ class AsyncEndpoints:
|
|
|
318
330
|
client=self._client,
|
|
319
331
|
)
|
|
320
332
|
|
|
321
|
-
data: Dict[str, Union[str, bool, Dict[str, int]]] = {
|
|
333
|
+
data: Dict[str, Union[str, bool, Dict[str, int], int]] = {
|
|
322
334
|
"model": model,
|
|
323
335
|
"hardware": hardware,
|
|
324
336
|
"autoscaling": {
|
|
@@ -333,6 +345,9 @@ class AsyncEndpoints:
|
|
|
333
345
|
if display_name is not None:
|
|
334
346
|
data["display_name"] = display_name
|
|
335
347
|
|
|
348
|
+
if inactive_timeout is not None:
|
|
349
|
+
data["inactive_timeout"] = inactive_timeout
|
|
350
|
+
|
|
336
351
|
response, _, _ = await requestor.arequest(
|
|
337
352
|
options=TogetherRequest(
|
|
338
353
|
method="POST",
|
|
@@ -399,6 +414,7 @@ class AsyncEndpoints:
|
|
|
399
414
|
max_replicas: Optional[int] = None,
|
|
400
415
|
state: Optional[Literal["STARTED", "STOPPED"]] = None,
|
|
401
416
|
display_name: Optional[str] = None,
|
|
417
|
+
inactive_timeout: Optional[int] = None,
|
|
402
418
|
) -> DedicatedEndpoint:
|
|
403
419
|
"""
|
|
404
420
|
Update an endpoint's configuration.
|
|
@@ -409,6 +425,7 @@ class AsyncEndpoints:
|
|
|
409
425
|
max_replicas (int, optional): The maximum number of replicas to scale up to
|
|
410
426
|
state (str, optional): The desired state of the endpoint ("STARTED" or "STOPPED")
|
|
411
427
|
display_name (str, optional): A human-readable name for the endpoint
|
|
428
|
+
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.
|
|
412
429
|
|
|
413
430
|
Returns:
|
|
414
431
|
DedicatedEndpoint: Object containing endpoint information
|
|
@@ -417,7 +434,7 @@ class AsyncEndpoints:
|
|
|
417
434
|
client=self._client,
|
|
418
435
|
)
|
|
419
436
|
|
|
420
|
-
data: Dict[str, Union[str, Dict[str, int]]] = {}
|
|
437
|
+
data: Dict[str, Union[str, Dict[str, int], int]] = {}
|
|
421
438
|
|
|
422
439
|
if min_replicas is not None or max_replicas is not None:
|
|
423
440
|
current_min = min_replicas
|
|
@@ -438,6 +455,9 @@ class AsyncEndpoints:
|
|
|
438
455
|
if display_name is not None:
|
|
439
456
|
data["display_name"] = display_name
|
|
440
457
|
|
|
458
|
+
if inactive_timeout is not None:
|
|
459
|
+
data["inactive_timeout"] = inactive_timeout
|
|
460
|
+
|
|
441
461
|
response, _, _ = await requestor.arequest(
|
|
442
462
|
options=TogetherRequest(
|
|
443
463
|
method="PATCH",
|
together/resources/models.py
CHANGED
|
@@ -11,20 +11,47 @@ from together.types import (
|
|
|
11
11
|
)
|
|
12
12
|
|
|
13
13
|
|
|
14
|
-
class
|
|
14
|
+
class ModelsBase:
|
|
15
15
|
def __init__(self, client: TogetherClient) -> None:
|
|
16
16
|
self._client = client
|
|
17
17
|
|
|
18
|
+
def _filter_dedicated_models(
|
|
19
|
+
self, models: List[ModelObject], dedicated_response: TogetherResponse
|
|
20
|
+
) -> List[ModelObject]:
|
|
21
|
+
"""
|
|
22
|
+
Filter models based on dedicated model response.
|
|
23
|
+
|
|
24
|
+
Args:
|
|
25
|
+
models (List[ModelObject]): List of all models
|
|
26
|
+
dedicated_response (TogetherResponse): Response from autoscale models endpoint
|
|
27
|
+
|
|
28
|
+
Returns:
|
|
29
|
+
List[ModelObject]: Filtered list of models
|
|
30
|
+
"""
|
|
31
|
+
assert isinstance(dedicated_response.data, list)
|
|
32
|
+
|
|
33
|
+
# Create a set of dedicated model names for efficient lookup
|
|
34
|
+
dedicated_model_names = {model["name"] for model in dedicated_response.data}
|
|
35
|
+
|
|
36
|
+
# Filter models to only include those in dedicated_model_names
|
|
37
|
+
# Note: The model.id from ModelObject matches the name field in the autoscale response
|
|
38
|
+
return [model for model in models if model.id in dedicated_model_names]
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class Models(ModelsBase):
|
|
18
42
|
def list(
|
|
19
43
|
self,
|
|
44
|
+
dedicated: bool = False,
|
|
20
45
|
) -> List[ModelObject]:
|
|
21
46
|
"""
|
|
22
47
|
Method to return list of models on the API
|
|
23
48
|
|
|
49
|
+
Args:
|
|
50
|
+
dedicated (bool, optional): If True, returns only dedicated models. Defaults to False.
|
|
51
|
+
|
|
24
52
|
Returns:
|
|
25
53
|
List[ModelObject]: List of model objects
|
|
26
54
|
"""
|
|
27
|
-
|
|
28
55
|
requestor = api_requestor.APIRequestor(
|
|
29
56
|
client=self._client,
|
|
30
57
|
)
|
|
@@ -40,23 +67,39 @@ class Models:
|
|
|
40
67
|
assert isinstance(response, TogetherResponse)
|
|
41
68
|
assert isinstance(response.data, list)
|
|
42
69
|
|
|
43
|
-
|
|
70
|
+
models = [ModelObject(**model) for model in response.data]
|
|
44
71
|
|
|
72
|
+
if dedicated:
|
|
73
|
+
# Get dedicated models
|
|
74
|
+
dedicated_response, _, _ = requestor.request(
|
|
75
|
+
options=TogetherRequest(
|
|
76
|
+
method="GET",
|
|
77
|
+
url="autoscale/models",
|
|
78
|
+
),
|
|
79
|
+
stream=False,
|
|
80
|
+
)
|
|
45
81
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
82
|
+
models = self._filter_dedicated_models(models, dedicated_response)
|
|
83
|
+
|
|
84
|
+
models.sort(key=lambda x: x.id.lower())
|
|
49
85
|
|
|
86
|
+
return models
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
class AsyncModels(ModelsBase):
|
|
50
90
|
async def list(
|
|
51
91
|
self,
|
|
92
|
+
dedicated: bool = False,
|
|
52
93
|
) -> List[ModelObject]:
|
|
53
94
|
"""
|
|
54
95
|
Async method to return list of models on API
|
|
55
96
|
|
|
97
|
+
Args:
|
|
98
|
+
dedicated (bool, optional): If True, returns only dedicated models. Defaults to False.
|
|
99
|
+
|
|
56
100
|
Returns:
|
|
57
101
|
List[ModelObject]: List of model objects
|
|
58
102
|
"""
|
|
59
|
-
|
|
60
103
|
requestor = api_requestor.APIRequestor(
|
|
61
104
|
client=self._client,
|
|
62
105
|
)
|
|
@@ -72,4 +115,20 @@ class AsyncModels:
|
|
|
72
115
|
assert isinstance(response, TogetherResponse)
|
|
73
116
|
assert isinstance(response.data, list)
|
|
74
117
|
|
|
75
|
-
|
|
118
|
+
models = [ModelObject(**model) for model in response.data]
|
|
119
|
+
|
|
120
|
+
if dedicated:
|
|
121
|
+
# Get dedicated models
|
|
122
|
+
dedicated_response, _, _ = await requestor.arequest(
|
|
123
|
+
options=TogetherRequest(
|
|
124
|
+
method="GET",
|
|
125
|
+
url="autoscale/models",
|
|
126
|
+
),
|
|
127
|
+
stream=False,
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
models = self._filter_dedicated_models(models, dedicated_response)
|
|
131
|
+
|
|
132
|
+
models.sort(key=lambda x: x.id.lower())
|
|
133
|
+
|
|
134
|
+
return models
|
together/utils/api_helpers.py
CHANGED
|
@@ -2,6 +2,7 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
import json
|
|
4
4
|
import os
|
|
5
|
+
import sys
|
|
5
6
|
import platform
|
|
6
7
|
from typing import TYPE_CHECKING, Any, Dict
|
|
7
8
|
|
|
@@ -12,6 +13,7 @@ if TYPE_CHECKING:
|
|
|
12
13
|
import together
|
|
13
14
|
from together import error
|
|
14
15
|
from together.utils._log import _console_log_level
|
|
16
|
+
from together.utils import log_info
|
|
15
17
|
|
|
16
18
|
|
|
17
19
|
def get_headers(
|
|
@@ -82,3 +84,41 @@ def default_api_key(api_key: str | None = None) -> str | None:
|
|
|
82
84
|
return os.environ.get("TOGETHER_API_KEY")
|
|
83
85
|
|
|
84
86
|
raise error.AuthenticationError(together.constants.MISSING_API_KEY_MESSAGE)
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def get_google_colab_secret(secret_name: str = "TOGETHER_API_KEY") -> str | None:
|
|
90
|
+
"""
|
|
91
|
+
Checks to see if the user is running in Google Colab, and looks for the Together API Key secret.
|
|
92
|
+
|
|
93
|
+
Args:
|
|
94
|
+
secret_name (str, optional). Defaults to TOGETHER_API_KEY
|
|
95
|
+
|
|
96
|
+
Returns:
|
|
97
|
+
str: if the API key is found; None if an error occurred or the secret was not found.
|
|
98
|
+
"""
|
|
99
|
+
# If running in Google Colab, check for Together in notebook secrets
|
|
100
|
+
if "google.colab" in sys.modules:
|
|
101
|
+
if TYPE_CHECKING:
|
|
102
|
+
from google.colab import userdata # type: ignore
|
|
103
|
+
else:
|
|
104
|
+
from google.colab import userdata
|
|
105
|
+
|
|
106
|
+
try:
|
|
107
|
+
api_key = userdata.get(secret_name)
|
|
108
|
+
if not isinstance(api_key, str):
|
|
109
|
+
return None
|
|
110
|
+
else:
|
|
111
|
+
return str(api_key)
|
|
112
|
+
except userdata.NotebookAccessError:
|
|
113
|
+
log_info(
|
|
114
|
+
"The TOGETHER_API_KEY Colab secret was found, but notebook access is disabled. Please enable notebook "
|
|
115
|
+
"access for the secret."
|
|
116
|
+
)
|
|
117
|
+
except userdata.SecretNotFoundError:
|
|
118
|
+
# warn and carry on
|
|
119
|
+
log_info("Colab: No Google Colab secret named TOGETHER_API_KEY was found.")
|
|
120
|
+
|
|
121
|
+
return None
|
|
122
|
+
|
|
123
|
+
else:
|
|
124
|
+
return None
|
|
@@ -5,14 +5,14 @@ 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
|
|
7
7
|
together/cli/api/completions.py,sha256=l-Zw5t7hojL3w8xd_mitS2NRB72i5Z0xwkzH0rT5XMc,4263
|
|
8
|
-
together/cli/api/endpoints.py,sha256=
|
|
8
|
+
together/cli/api/endpoints.py,sha256=tM42PthzkpTjOkmL6twyWYXqEQw0DOqsEKTZdhp6vKU,13284
|
|
9
9
|
together/cli/api/files.py,sha256=QLYEXRkY8J2Gg1SbTCtzGfoTMvosoeACNK83L_oLubs,3397
|
|
10
10
|
together/cli/api/finetune.py,sha256=0Md5FOzl0D6QfAmku628CGy43VzsjJ9-RbtY6ln5W1g,15018
|
|
11
11
|
together/cli/api/images.py,sha256=GADSeaNUHUVMtWovmccGuKc28IJ9E_v4vAEwYHJhu5o,2645
|
|
12
|
-
together/cli/api/models.py,sha256=
|
|
12
|
+
together/cli/api/models.py,sha256=CXw8B1hqNkadogi58GIXhLg_dTJnvTBaE7Kq1_xQ-10,1423
|
|
13
13
|
together/cli/api/utils.py,sha256=IuqYWPnLI38_Bqd7lj8V_SnGdYc59pRmMbQmciS4FsM,1326
|
|
14
14
|
together/cli/cli.py,sha256=YCDzbXpC5is0rs2PEkUPrIhYuzdyrihQ8GVR_TlDv5s,2054
|
|
15
|
-
together/client.py,sha256=
|
|
15
|
+
together/client.py,sha256=KKmO0LadgAyj8AXKrJCYwLDyxR7_CUB4uTmay1eiyFE,5420
|
|
16
16
|
together/constants.py,sha256=UDJhEylJFmdm4bedBDpvqYXBj5Or3k7z9GWtkRY_dZQ,1526
|
|
17
17
|
together/error.py,sha256=HU6247CyzCFjaxL9A0XYbXZ6fY_ebRg0FEYjI4Skogs,5515
|
|
18
18
|
together/filemanager.py,sha256=QHhBn73oVFdgUpSYXYLmJzHJ9c5wYEMJC0ur6ZgDeYo,11269
|
|
@@ -31,11 +31,11 @@ together/resources/chat/__init__.py,sha256=RsTptdP8MeGjcdIjze896-J27cRvCbUoMft0X
|
|
|
31
31
|
together/resources/chat/completions.py,sha256=jYiNZsWa8RyEacL0VgxWj1egJ857oU4nxIY8uqGHcaU,14459
|
|
32
32
|
together/resources/completions.py,sha256=5Wa-ZjPCxRcam6CDe7KgGYlTA7yJZMmd5TrRgGCL_ug,11726
|
|
33
33
|
together/resources/embeddings.py,sha256=PTvLb82yjG_-iQOyuhsilp77Fr7gZ0o6WD2KeRnKoxs,2675
|
|
34
|
-
together/resources/endpoints.py,sha256=
|
|
34
|
+
together/resources/endpoints.py,sha256=NNjp-wyzOotzlscGGrANhOHxQBjHTN8f5kTQTH_CLvE,17177
|
|
35
35
|
together/resources/files.py,sha256=bnPbaF25e4InBRPvHwXHXT-oSX1Z1sZRsnQW5wq82U4,4990
|
|
36
36
|
together/resources/finetune.py,sha256=euTGbSlFb7fIoRWGD4bc6Q-PKlXkOW7cAbfZALS4DTU,32945
|
|
37
37
|
together/resources/images.py,sha256=LQUjKPaFxWTqOAPnyF1Pp7Rz4NLOYhmoKwshpYiprEM,4923
|
|
38
|
-
together/resources/models.py,sha256=
|
|
38
|
+
together/resources/models.py,sha256=qgmAXv61Cq4oLxytenEZBywA8shldDHYxJ_EAu_4JWQ,3864
|
|
39
39
|
together/resources/rerank.py,sha256=3Ju_aRSyZ1s_3zCSNZnSnEJErUVmt2xa3M8z1nvejMA,3931
|
|
40
40
|
together/together_response.py,sha256=a3dgKMPDrlfKQwxYENfNt2T4l2vSZxRWMixhHSy-q3E,1308
|
|
41
41
|
together/types/__init__.py,sha256=edHguHW7OeCPZZWts80Uw6mF406rPzWAcoCQLueO1_0,2552
|
|
@@ -54,12 +54,12 @@ together/types/models.py,sha256=nwQIZGHKZpX9I6mK8z56VW70YC6Ry6JGsVa0s99QVxc,1055
|
|
|
54
54
|
together/types/rerank.py,sha256=qZfuXOn7MZ6ly8hpJ_MZ7OU_Bi1-cgYNSB20Wja8Qkk,1061
|
|
55
55
|
together/utils/__init__.py,sha256=5fqvj4KT2rHxKSQot2TSyV_HcvkvkGiqAiaYuJwqtm0,786
|
|
56
56
|
together/utils/_log.py,sha256=5IYNI-jYzxyIS-pUvhb0vE_Muo3MA7GgBhsu66TKP2w,1951
|
|
57
|
-
together/utils/api_helpers.py,sha256=
|
|
57
|
+
together/utils/api_helpers.py,sha256=2K0O6qeEQ2zVFvi5NBN5m2kjZJaS3-JfKFecQ7SmGaw,3746
|
|
58
58
|
together/utils/files.py,sha256=rfp10qU0urtWOXXFeasFtO9xp-1KIhM3S43JxcnHmL0,16438
|
|
59
59
|
together/utils/tools.py,sha256=H2MTJhEqtBllaDvOyZehIO_IVNK3P17rSDeILtJIVag,2964
|
|
60
60
|
together/version.py,sha256=p03ivHyE0SyWU4jAnRTBi_sOwywVWoZPU4g2gzRgG-Y,126
|
|
61
|
-
together-1.4.
|
|
62
|
-
together-1.4.
|
|
63
|
-
together-1.4.
|
|
64
|
-
together-1.4.
|
|
65
|
-
together-1.4.
|
|
61
|
+
together-1.4.6.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
62
|
+
together-1.4.6.dist-info/METADATA,sha256=O-g6Hl_MTZUV8BhzEbeuQNEieXbuga7R15WgUUsq-8Q,14445
|
|
63
|
+
together-1.4.6.dist-info/WHEEL,sha256=XbeZDeTWKc1w7CSIyre5aMDU_-PohRwTQceYnisIYYY,88
|
|
64
|
+
together-1.4.6.dist-info/entry_points.txt,sha256=G-b5NKW6lUUf1V1fH8IPTBb7jXnK7lhbX9H1zTEJXPs,50
|
|
65
|
+
together-1.4.6.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|