together 2.0.0a14__py3-none-any.whl → 2.0.0a16__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/_base_client.py +134 -11
- together/_client.py +7 -0
- together/_models.py +16 -1
- together/_types.py +9 -0
- together/_version.py +1 -1
- together/constants.py +34 -0
- together/error.py +15 -0
- together/lib/_google_colab.py +39 -0
- together/lib/cli/__init__.py +73 -0
- together/lib/cli/api/{utils.py → _utils.py} +4 -4
- together/lib/cli/api/beta/clusters/__init__.py +47 -0
- together/lib/cli/api/beta/{clusters.py → clusters/create.py} +5 -179
- together/lib/cli/api/beta/clusters/delete.py +35 -0
- together/lib/cli/api/beta/clusters/get_credentials.py +151 -0
- together/lib/cli/api/beta/clusters/list.py +24 -0
- together/lib/cli/api/beta/clusters/list_regions.py +37 -0
- together/lib/cli/api/beta/clusters/retrieve.py +31 -0
- together/lib/cli/api/beta/clusters/storage/__init__.py +19 -0
- together/lib/cli/api/beta/clusters/storage/create.py +49 -0
- together/lib/cli/api/beta/clusters/storage/delete.py +38 -0
- together/lib/cli/api/beta/clusters/storage/list.py +42 -0
- together/lib/cli/api/beta/clusters/storage/retrieve.py +34 -0
- together/lib/cli/api/beta/clusters/update.py +54 -0
- together/lib/cli/api/endpoints/__init__.py +56 -0
- together/lib/cli/api/endpoints/availability_zones.py +26 -0
- together/lib/cli/api/endpoints/create.py +159 -0
- together/lib/cli/api/endpoints/delete.py +15 -0
- together/lib/cli/api/endpoints/hardware.py +40 -0
- together/lib/cli/api/endpoints/list.py +66 -0
- together/lib/cli/api/endpoints/retrieve.py +23 -0
- together/lib/cli/api/endpoints/start.py +25 -0
- together/lib/cli/api/endpoints/stop.py +25 -0
- together/lib/cli/api/endpoints/update.py +77 -0
- together/lib/cli/api/evals/__init__.py +19 -0
- together/lib/cli/api/{evals.py → evals/create.py} +6 -129
- together/lib/cli/api/evals/list.py +58 -0
- together/lib/cli/api/evals/retrieve.py +21 -0
- together/lib/cli/api/evals/status.py +20 -0
- together/lib/cli/api/files/__init__.py +23 -0
- together/lib/cli/api/files/check.py +21 -0
- together/lib/cli/api/files/delete.py +20 -0
- together/lib/cli/api/files/list.py +34 -0
- together/lib/cli/api/files/retrieve.py +20 -0
- together/lib/cli/api/files/retrieve_content.py +25 -0
- together/lib/cli/api/files/upload.py +38 -0
- together/lib/cli/api/fine_tuning/__init__.py +27 -0
- together/lib/cli/api/fine_tuning/cancel.py +28 -0
- together/lib/cli/api/{fine_tuning.py → fine_tuning/create.py} +5 -257
- together/lib/cli/api/fine_tuning/delete.py +29 -0
- together/lib/cli/api/fine_tuning/download.py +94 -0
- together/lib/cli/api/fine_tuning/list.py +44 -0
- together/lib/cli/api/fine_tuning/list_checkpoints.py +42 -0
- together/lib/cli/api/fine_tuning/list_events.py +35 -0
- together/lib/cli/api/fine_tuning/retrieve.py +27 -0
- together/lib/cli/api/models/__init__.py +15 -0
- together/lib/cli/api/models/list.py +51 -0
- together/lib/cli/api/{models.py → models/upload.py} +4 -51
- together/lib/types/fine_tuning.py +3 -0
- together/resources/beta/clusters/clusters.py +36 -28
- together/resources/beta/clusters/storage.py +30 -21
- together/types/__init__.py +13 -1
- together/types/beta/__init__.py +0 -2
- together/types/beta/cluster_create_params.py +3 -3
- together/types/beta/clusters/__init__.py +0 -1
- together/types/beta/clusters/cluster_storage.py +4 -0
- together/types/chat_completions.py +7 -0
- together/types/endpoints.py +4 -0
- together/types/files.py +8 -0
- together/types/fine_tuning_cancel_response.py +3 -0
- together/types/fine_tuning_list_response.py +3 -0
- together/types/finetune.py +27 -0
- together/types/finetune_response.py +2 -0
- together/types/models.py +2 -0
- {together-2.0.0a14.dist-info → together-2.0.0a16.dist-info}/METADATA +45 -2
- {together-2.0.0a14.dist-info → together-2.0.0a16.dist-info}/RECORD +79 -36
- together-2.0.0a16.dist-info/entry_points.txt +2 -0
- together/lib/cli/api/__init__.py +0 -0
- together/lib/cli/api/beta/clusters_storage.py +0 -152
- together/lib/cli/api/endpoints.py +0 -467
- together/lib/cli/api/files.py +0 -133
- together/lib/cli/cli.py +0 -73
- together/types/beta/cluster_create_response.py +0 -9
- together/types/beta/cluster_update_response.py +0 -9
- together/types/beta/clusters/storage_create_response.py +0 -9
- together-2.0.0a14.dist-info/entry_points.txt +0 -2
- /together/lib/cli/api/beta/{beta.py → __init__.py} +0 -0
- {together-2.0.0a14.dist-info → together-2.0.0a16.dist-info}/WHEEL +0 -0
- {together-2.0.0a14.dist-info → together-2.0.0a16.dist-info}/licenses/LICENSE +0 -0
together/_base_client.py
CHANGED
|
@@ -9,6 +9,7 @@ import asyncio
|
|
|
9
9
|
import inspect
|
|
10
10
|
import logging
|
|
11
11
|
import platform
|
|
12
|
+
import warnings
|
|
12
13
|
import email.utils
|
|
13
14
|
from types import TracebackType
|
|
14
15
|
from random import random
|
|
@@ -51,9 +52,11 @@ from ._types import (
|
|
|
51
52
|
ResponseT,
|
|
52
53
|
AnyMapping,
|
|
53
54
|
PostParser,
|
|
55
|
+
BinaryTypes,
|
|
54
56
|
RequestFiles,
|
|
55
57
|
HttpxSendArgs,
|
|
56
58
|
RequestOptions,
|
|
59
|
+
AsyncBinaryTypes,
|
|
57
60
|
HttpxRequestFiles,
|
|
58
61
|
ModelBuilderProtocol,
|
|
59
62
|
not_given,
|
|
@@ -477,8 +480,19 @@ class BaseClient(Generic[_HttpxClientT, _DefaultStreamT]):
|
|
|
477
480
|
retries_taken: int = 0,
|
|
478
481
|
) -> httpx.Request:
|
|
479
482
|
if log.isEnabledFor(logging.DEBUG):
|
|
480
|
-
log.debug(
|
|
481
|
-
|
|
483
|
+
log.debug(
|
|
484
|
+
"Request options: %s",
|
|
485
|
+
model_dump(
|
|
486
|
+
options,
|
|
487
|
+
exclude_unset=True,
|
|
488
|
+
# Pydantic v1 can't dump every type we support in content, so we exclude it for now.
|
|
489
|
+
exclude={
|
|
490
|
+
"content",
|
|
491
|
+
}
|
|
492
|
+
if PYDANTIC_V1
|
|
493
|
+
else {},
|
|
494
|
+
),
|
|
495
|
+
)
|
|
482
496
|
kwargs: dict[str, Any] = {}
|
|
483
497
|
|
|
484
498
|
json_data = options.json_data
|
|
@@ -532,7 +546,13 @@ class BaseClient(Generic[_HttpxClientT, _DefaultStreamT]):
|
|
|
532
546
|
is_body_allowed = options.method.lower() != "get"
|
|
533
547
|
|
|
534
548
|
if is_body_allowed:
|
|
535
|
-
if
|
|
549
|
+
if options.content is not None and json_data is not None:
|
|
550
|
+
raise TypeError("Passing both `content` and `json_data` is not supported")
|
|
551
|
+
if options.content is not None and files is not None:
|
|
552
|
+
raise TypeError("Passing both `content` and `files` is not supported")
|
|
553
|
+
if options.content is not None:
|
|
554
|
+
kwargs["content"] = options.content
|
|
555
|
+
elif isinstance(json_data, bytes):
|
|
536
556
|
kwargs["content"] = json_data
|
|
537
557
|
else:
|
|
538
558
|
kwargs["json"] = json_data if is_given(json_data) else None
|
|
@@ -1194,6 +1214,7 @@ class SyncAPIClient(BaseClient[httpx.Client, Stream[Any]]):
|
|
|
1194
1214
|
*,
|
|
1195
1215
|
cast_to: Type[ResponseT],
|
|
1196
1216
|
body: Body | None = None,
|
|
1217
|
+
content: BinaryTypes | None = None,
|
|
1197
1218
|
options: RequestOptions = {},
|
|
1198
1219
|
files: RequestFiles | None = None,
|
|
1199
1220
|
stream: Literal[False] = False,
|
|
@@ -1206,6 +1227,7 @@ class SyncAPIClient(BaseClient[httpx.Client, Stream[Any]]):
|
|
|
1206
1227
|
*,
|
|
1207
1228
|
cast_to: Type[ResponseT],
|
|
1208
1229
|
body: Body | None = None,
|
|
1230
|
+
content: BinaryTypes | None = None,
|
|
1209
1231
|
options: RequestOptions = {},
|
|
1210
1232
|
files: RequestFiles | None = None,
|
|
1211
1233
|
stream: Literal[True],
|
|
@@ -1219,6 +1241,7 @@ class SyncAPIClient(BaseClient[httpx.Client, Stream[Any]]):
|
|
|
1219
1241
|
*,
|
|
1220
1242
|
cast_to: Type[ResponseT],
|
|
1221
1243
|
body: Body | None = None,
|
|
1244
|
+
content: BinaryTypes | None = None,
|
|
1222
1245
|
options: RequestOptions = {},
|
|
1223
1246
|
files: RequestFiles | None = None,
|
|
1224
1247
|
stream: bool,
|
|
@@ -1231,13 +1254,25 @@ class SyncAPIClient(BaseClient[httpx.Client, Stream[Any]]):
|
|
|
1231
1254
|
*,
|
|
1232
1255
|
cast_to: Type[ResponseT],
|
|
1233
1256
|
body: Body | None = None,
|
|
1257
|
+
content: BinaryTypes | None = None,
|
|
1234
1258
|
options: RequestOptions = {},
|
|
1235
1259
|
files: RequestFiles | None = None,
|
|
1236
1260
|
stream: bool = False,
|
|
1237
1261
|
stream_cls: type[_StreamT] | None = None,
|
|
1238
1262
|
) -> ResponseT | _StreamT:
|
|
1263
|
+
if body is not None and content is not None:
|
|
1264
|
+
raise TypeError("Passing both `body` and `content` is not supported")
|
|
1265
|
+
if files is not None and content is not None:
|
|
1266
|
+
raise TypeError("Passing both `files` and `content` is not supported")
|
|
1267
|
+
if isinstance(body, bytes):
|
|
1268
|
+
warnings.warn(
|
|
1269
|
+
"Passing raw bytes as `body` is deprecated and will be removed in a future version. "
|
|
1270
|
+
"Please pass raw bytes via the `content` parameter instead.",
|
|
1271
|
+
DeprecationWarning,
|
|
1272
|
+
stacklevel=2,
|
|
1273
|
+
)
|
|
1239
1274
|
opts = FinalRequestOptions.construct(
|
|
1240
|
-
method="post", url=path, json_data=body, files=to_httpx_files(files), **options
|
|
1275
|
+
method="post", url=path, json_data=body, content=content, files=to_httpx_files(files), **options
|
|
1241
1276
|
)
|
|
1242
1277
|
return cast(ResponseT, self.request(cast_to, opts, stream=stream, stream_cls=stream_cls))
|
|
1243
1278
|
|
|
@@ -1247,11 +1282,23 @@ class SyncAPIClient(BaseClient[httpx.Client, Stream[Any]]):
|
|
|
1247
1282
|
*,
|
|
1248
1283
|
cast_to: Type[ResponseT],
|
|
1249
1284
|
body: Body | None = None,
|
|
1285
|
+
content: BinaryTypes | None = None,
|
|
1250
1286
|
files: RequestFiles | None = None,
|
|
1251
1287
|
options: RequestOptions = {},
|
|
1252
1288
|
) -> ResponseT:
|
|
1289
|
+
if body is not None and content is not None:
|
|
1290
|
+
raise TypeError("Passing both `body` and `content` is not supported")
|
|
1291
|
+
if files is not None and content is not None:
|
|
1292
|
+
raise TypeError("Passing both `files` and `content` is not supported")
|
|
1293
|
+
if isinstance(body, bytes):
|
|
1294
|
+
warnings.warn(
|
|
1295
|
+
"Passing raw bytes as `body` is deprecated and will be removed in a future version. "
|
|
1296
|
+
"Please pass raw bytes via the `content` parameter instead.",
|
|
1297
|
+
DeprecationWarning,
|
|
1298
|
+
stacklevel=2,
|
|
1299
|
+
)
|
|
1253
1300
|
opts = FinalRequestOptions.construct(
|
|
1254
|
-
method="patch", url=path, json_data=body, files=to_httpx_files(files), **options
|
|
1301
|
+
method="patch", url=path, json_data=body, content=content, files=to_httpx_files(files), **options
|
|
1255
1302
|
)
|
|
1256
1303
|
return self.request(cast_to, opts)
|
|
1257
1304
|
|
|
@@ -1261,11 +1308,23 @@ class SyncAPIClient(BaseClient[httpx.Client, Stream[Any]]):
|
|
|
1261
1308
|
*,
|
|
1262
1309
|
cast_to: Type[ResponseT],
|
|
1263
1310
|
body: Body | None = None,
|
|
1311
|
+
content: BinaryTypes | None = None,
|
|
1264
1312
|
files: RequestFiles | None = None,
|
|
1265
1313
|
options: RequestOptions = {},
|
|
1266
1314
|
) -> ResponseT:
|
|
1315
|
+
if body is not None and content is not None:
|
|
1316
|
+
raise TypeError("Passing both `body` and `content` is not supported")
|
|
1317
|
+
if files is not None and content is not None:
|
|
1318
|
+
raise TypeError("Passing both `files` and `content` is not supported")
|
|
1319
|
+
if isinstance(body, bytes):
|
|
1320
|
+
warnings.warn(
|
|
1321
|
+
"Passing raw bytes as `body` is deprecated and will be removed in a future version. "
|
|
1322
|
+
"Please pass raw bytes via the `content` parameter instead.",
|
|
1323
|
+
DeprecationWarning,
|
|
1324
|
+
stacklevel=2,
|
|
1325
|
+
)
|
|
1267
1326
|
opts = FinalRequestOptions.construct(
|
|
1268
|
-
method="put", url=path, json_data=body, files=to_httpx_files(files), **options
|
|
1327
|
+
method="put", url=path, json_data=body, content=content, files=to_httpx_files(files), **options
|
|
1269
1328
|
)
|
|
1270
1329
|
return self.request(cast_to, opts)
|
|
1271
1330
|
|
|
@@ -1275,9 +1334,19 @@ class SyncAPIClient(BaseClient[httpx.Client, Stream[Any]]):
|
|
|
1275
1334
|
*,
|
|
1276
1335
|
cast_to: Type[ResponseT],
|
|
1277
1336
|
body: Body | None = None,
|
|
1337
|
+
content: BinaryTypes | None = None,
|
|
1278
1338
|
options: RequestOptions = {},
|
|
1279
1339
|
) -> ResponseT:
|
|
1280
|
-
|
|
1340
|
+
if body is not None and content is not None:
|
|
1341
|
+
raise TypeError("Passing both `body` and `content` is not supported")
|
|
1342
|
+
if isinstance(body, bytes):
|
|
1343
|
+
warnings.warn(
|
|
1344
|
+
"Passing raw bytes as `body` is deprecated and will be removed in a future version. "
|
|
1345
|
+
"Please pass raw bytes via the `content` parameter instead.",
|
|
1346
|
+
DeprecationWarning,
|
|
1347
|
+
stacklevel=2,
|
|
1348
|
+
)
|
|
1349
|
+
opts = FinalRequestOptions.construct(method="delete", url=path, json_data=body, content=content, **options)
|
|
1281
1350
|
return self.request(cast_to, opts)
|
|
1282
1351
|
|
|
1283
1352
|
def get_api_list(
|
|
@@ -1717,6 +1786,7 @@ class AsyncAPIClient(BaseClient[httpx.AsyncClient, AsyncStream[Any]]):
|
|
|
1717
1786
|
*,
|
|
1718
1787
|
cast_to: Type[ResponseT],
|
|
1719
1788
|
body: Body | None = None,
|
|
1789
|
+
content: AsyncBinaryTypes | None = None,
|
|
1720
1790
|
files: RequestFiles | None = None,
|
|
1721
1791
|
options: RequestOptions = {},
|
|
1722
1792
|
stream: Literal[False] = False,
|
|
@@ -1729,6 +1799,7 @@ class AsyncAPIClient(BaseClient[httpx.AsyncClient, AsyncStream[Any]]):
|
|
|
1729
1799
|
*,
|
|
1730
1800
|
cast_to: Type[ResponseT],
|
|
1731
1801
|
body: Body | None = None,
|
|
1802
|
+
content: AsyncBinaryTypes | None = None,
|
|
1732
1803
|
files: RequestFiles | None = None,
|
|
1733
1804
|
options: RequestOptions = {},
|
|
1734
1805
|
stream: Literal[True],
|
|
@@ -1742,6 +1813,7 @@ class AsyncAPIClient(BaseClient[httpx.AsyncClient, AsyncStream[Any]]):
|
|
|
1742
1813
|
*,
|
|
1743
1814
|
cast_to: Type[ResponseT],
|
|
1744
1815
|
body: Body | None = None,
|
|
1816
|
+
content: AsyncBinaryTypes | None = None,
|
|
1745
1817
|
files: RequestFiles | None = None,
|
|
1746
1818
|
options: RequestOptions = {},
|
|
1747
1819
|
stream: bool,
|
|
@@ -1754,13 +1826,25 @@ class AsyncAPIClient(BaseClient[httpx.AsyncClient, AsyncStream[Any]]):
|
|
|
1754
1826
|
*,
|
|
1755
1827
|
cast_to: Type[ResponseT],
|
|
1756
1828
|
body: Body | None = None,
|
|
1829
|
+
content: AsyncBinaryTypes | None = None,
|
|
1757
1830
|
files: RequestFiles | None = None,
|
|
1758
1831
|
options: RequestOptions = {},
|
|
1759
1832
|
stream: bool = False,
|
|
1760
1833
|
stream_cls: type[_AsyncStreamT] | None = None,
|
|
1761
1834
|
) -> ResponseT | _AsyncStreamT:
|
|
1835
|
+
if body is not None and content is not None:
|
|
1836
|
+
raise TypeError("Passing both `body` and `content` is not supported")
|
|
1837
|
+
if files is not None and content is not None:
|
|
1838
|
+
raise TypeError("Passing both `files` and `content` is not supported")
|
|
1839
|
+
if isinstance(body, bytes):
|
|
1840
|
+
warnings.warn(
|
|
1841
|
+
"Passing raw bytes as `body` is deprecated and will be removed in a future version. "
|
|
1842
|
+
"Please pass raw bytes via the `content` parameter instead.",
|
|
1843
|
+
DeprecationWarning,
|
|
1844
|
+
stacklevel=2,
|
|
1845
|
+
)
|
|
1762
1846
|
opts = FinalRequestOptions.construct(
|
|
1763
|
-
method="post", url=path, json_data=body, files=await async_to_httpx_files(files), **options
|
|
1847
|
+
method="post", url=path, json_data=body, content=content, files=await async_to_httpx_files(files), **options
|
|
1764
1848
|
)
|
|
1765
1849
|
return await self.request(cast_to, opts, stream=stream, stream_cls=stream_cls)
|
|
1766
1850
|
|
|
@@ -1770,11 +1854,28 @@ class AsyncAPIClient(BaseClient[httpx.AsyncClient, AsyncStream[Any]]):
|
|
|
1770
1854
|
*,
|
|
1771
1855
|
cast_to: Type[ResponseT],
|
|
1772
1856
|
body: Body | None = None,
|
|
1857
|
+
content: AsyncBinaryTypes | None = None,
|
|
1773
1858
|
files: RequestFiles | None = None,
|
|
1774
1859
|
options: RequestOptions = {},
|
|
1775
1860
|
) -> ResponseT:
|
|
1861
|
+
if body is not None and content is not None:
|
|
1862
|
+
raise TypeError("Passing both `body` and `content` is not supported")
|
|
1863
|
+
if files is not None and content is not None:
|
|
1864
|
+
raise TypeError("Passing both `files` and `content` is not supported")
|
|
1865
|
+
if isinstance(body, bytes):
|
|
1866
|
+
warnings.warn(
|
|
1867
|
+
"Passing raw bytes as `body` is deprecated and will be removed in a future version. "
|
|
1868
|
+
"Please pass raw bytes via the `content` parameter instead.",
|
|
1869
|
+
DeprecationWarning,
|
|
1870
|
+
stacklevel=2,
|
|
1871
|
+
)
|
|
1776
1872
|
opts = FinalRequestOptions.construct(
|
|
1777
|
-
method="patch",
|
|
1873
|
+
method="patch",
|
|
1874
|
+
url=path,
|
|
1875
|
+
json_data=body,
|
|
1876
|
+
content=content,
|
|
1877
|
+
files=await async_to_httpx_files(files),
|
|
1878
|
+
**options,
|
|
1778
1879
|
)
|
|
1779
1880
|
return await self.request(cast_to, opts)
|
|
1780
1881
|
|
|
@@ -1784,11 +1885,23 @@ class AsyncAPIClient(BaseClient[httpx.AsyncClient, AsyncStream[Any]]):
|
|
|
1784
1885
|
*,
|
|
1785
1886
|
cast_to: Type[ResponseT],
|
|
1786
1887
|
body: Body | None = None,
|
|
1888
|
+
content: AsyncBinaryTypes | None = None,
|
|
1787
1889
|
files: RequestFiles | None = None,
|
|
1788
1890
|
options: RequestOptions = {},
|
|
1789
1891
|
) -> ResponseT:
|
|
1892
|
+
if body is not None and content is not None:
|
|
1893
|
+
raise TypeError("Passing both `body` and `content` is not supported")
|
|
1894
|
+
if files is not None and content is not None:
|
|
1895
|
+
raise TypeError("Passing both `files` and `content` is not supported")
|
|
1896
|
+
if isinstance(body, bytes):
|
|
1897
|
+
warnings.warn(
|
|
1898
|
+
"Passing raw bytes as `body` is deprecated and will be removed in a future version. "
|
|
1899
|
+
"Please pass raw bytes via the `content` parameter instead.",
|
|
1900
|
+
DeprecationWarning,
|
|
1901
|
+
stacklevel=2,
|
|
1902
|
+
)
|
|
1790
1903
|
opts = FinalRequestOptions.construct(
|
|
1791
|
-
method="put", url=path, json_data=body, files=await async_to_httpx_files(files), **options
|
|
1904
|
+
method="put", url=path, json_data=body, content=content, files=await async_to_httpx_files(files), **options
|
|
1792
1905
|
)
|
|
1793
1906
|
return await self.request(cast_to, opts)
|
|
1794
1907
|
|
|
@@ -1798,9 +1911,19 @@ class AsyncAPIClient(BaseClient[httpx.AsyncClient, AsyncStream[Any]]):
|
|
|
1798
1911
|
*,
|
|
1799
1912
|
cast_to: Type[ResponseT],
|
|
1800
1913
|
body: Body | None = None,
|
|
1914
|
+
content: AsyncBinaryTypes | None = None,
|
|
1801
1915
|
options: RequestOptions = {},
|
|
1802
1916
|
) -> ResponseT:
|
|
1803
|
-
|
|
1917
|
+
if body is not None and content is not None:
|
|
1918
|
+
raise TypeError("Passing both `body` and `content` is not supported")
|
|
1919
|
+
if isinstance(body, bytes):
|
|
1920
|
+
warnings.warn(
|
|
1921
|
+
"Passing raw bytes as `body` is deprecated and will be removed in a future version. "
|
|
1922
|
+
"Please pass raw bytes via the `content` parameter instead.",
|
|
1923
|
+
DeprecationWarning,
|
|
1924
|
+
stacklevel=2,
|
|
1925
|
+
)
|
|
1926
|
+
opts = FinalRequestOptions.construct(method="delete", url=path, json_data=body, content=content, **options)
|
|
1804
1927
|
return await self.request(cast_to, opts)
|
|
1805
1928
|
|
|
1806
1929
|
def get_api_list(
|
together/_client.py
CHANGED
|
@@ -3,11 +3,14 @@
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
5
|
import os
|
|
6
|
+
import sys
|
|
6
7
|
from typing import TYPE_CHECKING, Any, Mapping
|
|
7
8
|
from typing_extensions import Self, override
|
|
8
9
|
|
|
9
10
|
import httpx
|
|
10
11
|
|
|
12
|
+
from together.lib._google_colab import get_google_colab_secret
|
|
13
|
+
|
|
11
14
|
from . import _exceptions
|
|
12
15
|
from ._qs import Querystring
|
|
13
16
|
from ._types import (
|
|
@@ -113,6 +116,8 @@ class Together(SyncAPIClient):
|
|
|
113
116
|
"""
|
|
114
117
|
if api_key is None:
|
|
115
118
|
api_key = os.environ.get("TOGETHER_API_KEY")
|
|
119
|
+
if api_key is None and "google.colab" in sys.modules:
|
|
120
|
+
api_key = get_google_colab_secret("TOGETHER_API_KEY")
|
|
116
121
|
if api_key is None:
|
|
117
122
|
raise TogetherError(
|
|
118
123
|
"The api_key client option must be set either by passing api_key to the client or by setting the TOGETHER_API_KEY environment variable"
|
|
@@ -388,6 +393,8 @@ class AsyncTogether(AsyncAPIClient):
|
|
|
388
393
|
"""
|
|
389
394
|
if api_key is None:
|
|
390
395
|
api_key = os.environ.get("TOGETHER_API_KEY")
|
|
396
|
+
if api_key is None and "google.colab" in sys.modules:
|
|
397
|
+
api_key = get_google_colab_secret("TOGETHER_API_KEY")
|
|
391
398
|
if api_key is None:
|
|
392
399
|
raise TogetherError(
|
|
393
400
|
"The api_key client option must be set either by passing api_key to the client or by setting the TOGETHER_API_KEY environment variable"
|
together/_models.py
CHANGED
|
@@ -3,7 +3,20 @@ from __future__ import annotations
|
|
|
3
3
|
import os
|
|
4
4
|
import inspect
|
|
5
5
|
import weakref
|
|
6
|
-
from typing import
|
|
6
|
+
from typing import (
|
|
7
|
+
IO,
|
|
8
|
+
TYPE_CHECKING,
|
|
9
|
+
Any,
|
|
10
|
+
Type,
|
|
11
|
+
Union,
|
|
12
|
+
Generic,
|
|
13
|
+
TypeVar,
|
|
14
|
+
Callable,
|
|
15
|
+
Iterable,
|
|
16
|
+
Optional,
|
|
17
|
+
AsyncIterable,
|
|
18
|
+
cast,
|
|
19
|
+
)
|
|
7
20
|
from datetime import date, datetime
|
|
8
21
|
from typing_extensions import (
|
|
9
22
|
List,
|
|
@@ -787,6 +800,7 @@ class FinalRequestOptionsInput(TypedDict, total=False):
|
|
|
787
800
|
timeout: float | Timeout | None
|
|
788
801
|
files: HttpxRequestFiles | None
|
|
789
802
|
idempotency_key: str
|
|
803
|
+
content: Union[bytes, bytearray, IO[bytes], Iterable[bytes], AsyncIterable[bytes], None]
|
|
790
804
|
json_data: Body
|
|
791
805
|
extra_json: AnyMapping
|
|
792
806
|
follow_redirects: bool
|
|
@@ -805,6 +819,7 @@ class FinalRequestOptions(pydantic.BaseModel):
|
|
|
805
819
|
post_parser: Union[Callable[[Any], Any], NotGiven] = NotGiven()
|
|
806
820
|
follow_redirects: Union[bool, None] = None
|
|
807
821
|
|
|
822
|
+
content: Union[bytes, bytearray, IO[bytes], Iterable[bytes], AsyncIterable[bytes], None] = None
|
|
808
823
|
# It should be noted that we cannot use `json` here as that would override
|
|
809
824
|
# a BaseModel method in an incompatible fashion.
|
|
810
825
|
json_data: Union[Body, None] = None
|
together/_types.py
CHANGED
|
@@ -13,9 +13,11 @@ from typing import (
|
|
|
13
13
|
Mapping,
|
|
14
14
|
TypeVar,
|
|
15
15
|
Callable,
|
|
16
|
+
Iterable,
|
|
16
17
|
Iterator,
|
|
17
18
|
Optional,
|
|
18
19
|
Sequence,
|
|
20
|
+
AsyncIterable,
|
|
19
21
|
)
|
|
20
22
|
from typing_extensions import (
|
|
21
23
|
Set,
|
|
@@ -56,6 +58,13 @@ if TYPE_CHECKING:
|
|
|
56
58
|
else:
|
|
57
59
|
Base64FileInput = Union[IO[bytes], PathLike]
|
|
58
60
|
FileContent = Union[IO[bytes], bytes, PathLike] # PathLike is not subscriptable in Python 3.8.
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
# Used for sending raw binary data / streaming data in request bodies
|
|
64
|
+
# e.g. for file uploads without multipart encoding
|
|
65
|
+
BinaryTypes = Union[bytes, bytearray, IO[bytes], Iterable[bytes]]
|
|
66
|
+
AsyncBinaryTypes = Union[bytes, bytearray, IO[bytes], AsyncIterable[bytes]]
|
|
67
|
+
|
|
59
68
|
FileTypes = Union[
|
|
60
69
|
# file (or bytes)
|
|
61
70
|
FileContent,
|
together/_version.py
CHANGED
together/constants.py
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Manually added to minimize breaking changes from V1
|
|
2
|
+
from ._constants import (
|
|
3
|
+
MAX_RETRY_DELAY as MAX_RETRY_DELAY,
|
|
4
|
+
DEFAULT_MAX_RETRIES,
|
|
5
|
+
INITIAL_RETRY_DELAY as INITIAL_RETRY_DELAY,
|
|
6
|
+
)
|
|
7
|
+
from .lib.constants import (
|
|
8
|
+
MIN_SAMPLES as MIN_SAMPLES,
|
|
9
|
+
DISABLE_TQDM as DISABLE_TQDM,
|
|
10
|
+
MAX_IMAGE_BYTES as MAX_IMAGE_BYTES,
|
|
11
|
+
NUM_BYTES_IN_GB as NUM_BYTES_IN_GB,
|
|
12
|
+
MAX_FILE_SIZE_GB as MAX_FILE_SIZE_GB,
|
|
13
|
+
MIN_PART_SIZE_MB as MIN_PART_SIZE_MB,
|
|
14
|
+
DOWNLOAD_BLOCK_SIZE as DOWNLOAD_BLOCK_SIZE,
|
|
15
|
+
MAX_MULTIPART_PARTS as MAX_MULTIPART_PARTS,
|
|
16
|
+
TARGET_PART_SIZE_MB as TARGET_PART_SIZE_MB,
|
|
17
|
+
MAX_CONCURRENT_PARTS as MAX_CONCURRENT_PARTS,
|
|
18
|
+
MAX_IMAGES_PER_EXAMPLE as MAX_IMAGES_PER_EXAMPLE,
|
|
19
|
+
MULTIPART_THRESHOLD_GB as MULTIPART_THRESHOLD_GB,
|
|
20
|
+
MAX_BASE64_IMAGE_LENGTH as MAX_BASE64_IMAGE_LENGTH,
|
|
21
|
+
MULTIPART_UPLOAD_TIMEOUT as MULTIPART_UPLOAD_TIMEOUT,
|
|
22
|
+
PARQUET_EXPECTED_COLUMNS as PARQUET_EXPECTED_COLUMNS,
|
|
23
|
+
REQUIRED_COLUMNS_MESSAGE as REQUIRED_COLUMNS_MESSAGE,
|
|
24
|
+
JSONL_REQUIRED_COLUMNS_MAP as JSONL_REQUIRED_COLUMNS_MAP,
|
|
25
|
+
POSSIBLE_ROLES_CONVERSATION as POSSIBLE_ROLES_CONVERSATION,
|
|
26
|
+
DatasetFormat as DatasetFormat,
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
TIMEOUT_SECS = 600
|
|
30
|
+
MAX_SESSION_LIFETIME_SECS = 180
|
|
31
|
+
MAX_CONNECTION_RETRIES = 2
|
|
32
|
+
MAX_RETRIES = DEFAULT_MAX_RETRIES
|
|
33
|
+
|
|
34
|
+
BASE_URL = "https://api.together.xyz/v1"
|
together/error.py
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Manually added to minimize breaking changes from V1
|
|
2
|
+
from ._exceptions import (
|
|
3
|
+
APIError as APIError,
|
|
4
|
+
RateLimitError as RateLimitError,
|
|
5
|
+
APITimeoutError,
|
|
6
|
+
BadRequestError,
|
|
7
|
+
APIConnectionError as APIConnectionError,
|
|
8
|
+
AuthenticationError as AuthenticationError,
|
|
9
|
+
APIResponseValidationError,
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
Timeout = APITimeoutError
|
|
13
|
+
InvalidRequestError = BadRequestError
|
|
14
|
+
TogetherException = APIError
|
|
15
|
+
ResponseError = APIResponseValidationError
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
from typing import Union
|
|
3
|
+
|
|
4
|
+
from together.lib.utils._log import log_info
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def get_google_colab_secret(secret_name: str = "TOGETHER_API_KEY") -> Union[str, None]:
|
|
8
|
+
"""
|
|
9
|
+
Checks to see if the user is running in Google Colab, and looks for the Together API Key secret.
|
|
10
|
+
|
|
11
|
+
Args:
|
|
12
|
+
secret_name (str, optional). Defaults to TOGETHER_API_KEY
|
|
13
|
+
|
|
14
|
+
Returns:
|
|
15
|
+
str: if the API key is found; None if an error occurred or the secret was not found.
|
|
16
|
+
"""
|
|
17
|
+
# If running in Google Colab, check for Together in notebook secrets
|
|
18
|
+
if "google.colab" in sys.modules:
|
|
19
|
+
from google.colab import userdata # type: ignore
|
|
20
|
+
|
|
21
|
+
try:
|
|
22
|
+
api_key = userdata.get(secret_name) # type: ignore
|
|
23
|
+
if not isinstance(api_key, str):
|
|
24
|
+
return None
|
|
25
|
+
else:
|
|
26
|
+
return str(api_key)
|
|
27
|
+
except userdata.NotebookAccessError: # type: ignore
|
|
28
|
+
log_info(
|
|
29
|
+
"The TOGETHER_API_KEY Colab secret was found, but notebook access is disabled. Please enable notebook "
|
|
30
|
+
"access for the secret."
|
|
31
|
+
)
|
|
32
|
+
except userdata.SecretNotFoundError: # type: ignore
|
|
33
|
+
# warn and carry on
|
|
34
|
+
log_info("Colab: No Google Colab secret named TOGETHER_API_KEY was found.")
|
|
35
|
+
|
|
36
|
+
return None
|
|
37
|
+
|
|
38
|
+
else:
|
|
39
|
+
return None
|
together/lib/cli/__init__.py
CHANGED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
from typing import Any
|
|
5
|
+
|
|
6
|
+
import click
|
|
7
|
+
|
|
8
|
+
import together
|
|
9
|
+
from together._version import __version__
|
|
10
|
+
from together._constants import DEFAULT_TIMEOUT
|
|
11
|
+
from together.lib.cli.api.beta import beta
|
|
12
|
+
from together.lib.cli.api.evals import evals
|
|
13
|
+
from together.lib.cli.api.files import files
|
|
14
|
+
from together.lib.cli.api.models import models
|
|
15
|
+
from together.lib.cli.api.endpoints import endpoints
|
|
16
|
+
from together.lib.cli.api.fine_tuning import fine_tuning
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def print_version(ctx: click.Context, _params: Any, value: Any) -> None:
|
|
20
|
+
if not value or ctx.resilient_parsing:
|
|
21
|
+
return
|
|
22
|
+
click.echo(f"Version {__version__}")
|
|
23
|
+
ctx.exit()
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@click.group()
|
|
27
|
+
@click.pass_context
|
|
28
|
+
@click.option(
|
|
29
|
+
"--api-key",
|
|
30
|
+
type=str,
|
|
31
|
+
help="API Key. Defaults to environment variable `TOGETHER_API_KEY`",
|
|
32
|
+
default=os.getenv("TOGETHER_API_KEY"),
|
|
33
|
+
)
|
|
34
|
+
@click.option("--base-url", type=str, help="API Base URL. Defaults to Together AI endpoint.")
|
|
35
|
+
@click.option("--timeout", type=int, help=f"Request timeout. Defaults to {DEFAULT_TIMEOUT} seconds")
|
|
36
|
+
@click.option(
|
|
37
|
+
"--max-retries",
|
|
38
|
+
type=int,
|
|
39
|
+
help=f"Maximum number of HTTP retries.",
|
|
40
|
+
)
|
|
41
|
+
@click.option(
|
|
42
|
+
"--version",
|
|
43
|
+
is_flag=True,
|
|
44
|
+
callback=print_version,
|
|
45
|
+
expose_value=False,
|
|
46
|
+
is_eager=True,
|
|
47
|
+
help="Print version",
|
|
48
|
+
)
|
|
49
|
+
@click.option("--debug", help="Debug mode", is_flag=True)
|
|
50
|
+
def main(
|
|
51
|
+
ctx: click.Context,
|
|
52
|
+
api_key: str | None,
|
|
53
|
+
base_url: str | None,
|
|
54
|
+
timeout: int | None,
|
|
55
|
+
debug: bool | None,
|
|
56
|
+
max_retries: int | None,
|
|
57
|
+
) -> None:
|
|
58
|
+
"""This is a sample CLI tool."""
|
|
59
|
+
os.environ.setdefault("TOGETHER_LOG", "debug" if debug else "info")
|
|
60
|
+
ctx.obj = together.Together(
|
|
61
|
+
api_key=api_key, base_url=base_url, timeout=timeout, max_retries=max_retries if max_retries is not None else 0
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
main.add_command(files)
|
|
66
|
+
main.add_command(fine_tuning)
|
|
67
|
+
main.add_command(models)
|
|
68
|
+
main.add_command(endpoints)
|
|
69
|
+
main.add_command(evals)
|
|
70
|
+
main.add_command(beta)
|
|
71
|
+
|
|
72
|
+
if __name__ == "__main__":
|
|
73
|
+
main()
|
|
@@ -104,11 +104,11 @@ def generate_progress_bar(
|
|
|
104
104
|
progress = "Progress: [bold red]unavailable[/bold red]"
|
|
105
105
|
if finetune_job.status in COMPLETED_STATUSES:
|
|
106
106
|
progress = "Progress: [bold green]completed[/bold green]"
|
|
107
|
-
elif finetune_job
|
|
108
|
-
|
|
107
|
+
elif getattr(finetune_job, "started_at", None) is not None and isinstance(finetune_job.started_at, datetime):
|
|
108
|
+
started_at = finetune_job.started_at.astimezone()
|
|
109
109
|
|
|
110
110
|
if finetune_job.progress is not None:
|
|
111
|
-
if current_time <
|
|
111
|
+
if current_time < started_at:
|
|
112
112
|
return progress
|
|
113
113
|
|
|
114
114
|
if not finetune_job.progress.estimate_available:
|
|
@@ -117,7 +117,7 @@ def generate_progress_bar(
|
|
|
117
117
|
if finetune_job.progress.seconds_remaining <= 0:
|
|
118
118
|
return progress
|
|
119
119
|
|
|
120
|
-
elapsed_time = (current_time -
|
|
120
|
+
elapsed_time = (current_time - started_at).total_seconds()
|
|
121
121
|
ratio_filled = min(elapsed_time / finetune_job.progress.seconds_remaining, 1.0)
|
|
122
122
|
percentage = ratio_filled * 100
|
|
123
123
|
filled = math.ceil(ratio_filled * _PROGRESS_BAR_WIDTH)
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
from typing import Any, Dict, List
|
|
2
|
+
|
|
3
|
+
import click
|
|
4
|
+
from tabulate import tabulate
|
|
5
|
+
|
|
6
|
+
from together.types.beta.cluster import Cluster
|
|
7
|
+
|
|
8
|
+
from .list import list
|
|
9
|
+
from .create import create
|
|
10
|
+
from .delete import delete
|
|
11
|
+
from .update import update
|
|
12
|
+
from .storage import storage
|
|
13
|
+
from .retrieve import retrieve
|
|
14
|
+
from .list_regions import list_regions
|
|
15
|
+
from .get_credentials import get_credentials
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@click.group()
|
|
19
|
+
@click.pass_context
|
|
20
|
+
def clusters(ctx: click.Context) -> None:
|
|
21
|
+
"""Clusters API commands"""
|
|
22
|
+
|
|
23
|
+
def _print_clusters(clusters: List[Cluster]) -> None:
|
|
24
|
+
data: List[Dict[str, Any]] = []
|
|
25
|
+
for cluster in clusters:
|
|
26
|
+
data.append(
|
|
27
|
+
{
|
|
28
|
+
"ID": cluster.cluster_id,
|
|
29
|
+
"Name": cluster.cluster_name,
|
|
30
|
+
"Status": cluster.status,
|
|
31
|
+
"Region": cluster.region,
|
|
32
|
+
}
|
|
33
|
+
)
|
|
34
|
+
click.echo(tabulate(data, headers="keys", tablefmt="grid"))
|
|
35
|
+
|
|
36
|
+
ctx.obj.print_clusters = _print_clusters
|
|
37
|
+
pass
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
clusters.add_command(list)
|
|
41
|
+
clusters.add_command(storage)
|
|
42
|
+
clusters.add_command(create)
|
|
43
|
+
clusters.add_command(retrieve)
|
|
44
|
+
clusters.add_command(update)
|
|
45
|
+
clusters.add_command(delete)
|
|
46
|
+
clusters.add_command(list_regions)
|
|
47
|
+
clusters.add_command(get_credentials)
|