truss 0.11.6rc102__py3-none-any.whl → 0.11.24rc2__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.
- truss/api/__init__.py +5 -2
- truss/base/constants.py +1 -0
- truss/base/trt_llm_config.py +14 -3
- truss/base/truss_config.py +19 -4
- truss/cli/chains_commands.py +49 -1
- truss/cli/cli.py +38 -7
- truss/cli/logs/base_watcher.py +31 -12
- truss/cli/logs/model_log_watcher.py +24 -1
- truss/cli/remote_cli.py +29 -0
- truss/cli/resolvers/chain_team_resolver.py +82 -0
- truss/cli/resolvers/model_team_resolver.py +90 -0
- truss/cli/resolvers/training_project_team_resolver.py +81 -0
- truss/cli/train/cache.py +332 -0
- truss/cli/train/core.py +57 -163
- truss/cli/train/deploy_checkpoints/__init__.py +2 -2
- truss/cli/train/deploy_checkpoints/deploy_checkpoints.py +236 -103
- truss/cli/train/deploy_checkpoints/deploy_checkpoints_helpers.py +1 -52
- truss/cli/train/deploy_checkpoints/deploy_full_checkpoints.py +1 -86
- truss/cli/train/deploy_checkpoints/deploy_lora_checkpoints.py +1 -85
- truss/cli/train/deploy_checkpoints/deploy_whisper_checkpoints.py +1 -56
- truss/cli/train/types.py +18 -9
- truss/cli/train_commands.py +180 -35
- truss/cli/utils/common.py +40 -3
- truss/contexts/image_builder/serving_image_builder.py +17 -4
- truss/remote/baseten/api.py +215 -9
- truss/remote/baseten/core.py +63 -7
- truss/remote/baseten/custom_types.py +1 -0
- truss/remote/baseten/remote.py +42 -2
- truss/remote/baseten/service.py +0 -7
- truss/remote/baseten/utils/transfer.py +5 -2
- truss/templates/base.Dockerfile.jinja +8 -4
- truss/templates/control/control/application.py +51 -26
- truss/templates/control/control/endpoints.py +1 -5
- truss/templates/control/control/helpers/inference_server_process_controller.py +10 -4
- truss/templates/control/control/helpers/truss_patch/model_container_patch_applier.py +33 -18
- truss/templates/control/control/server.py +1 -1
- truss/templates/control/requirements.txt +1 -2
- truss/templates/docker_server/proxy.conf.jinja +13 -0
- truss/templates/docker_server/supervisord.conf.jinja +2 -1
- truss/templates/no_build.Dockerfile.jinja +1 -0
- truss/templates/server/requirements.txt +2 -3
- truss/templates/server/truss_server.py +2 -5
- truss/templates/server.Dockerfile.jinja +12 -12
- truss/templates/shared/lazy_data_resolver.py +214 -2
- truss/templates/shared/util.py +6 -5
- truss/tests/cli/chains/test_chains_team_parameter.py +443 -0
- truss/tests/cli/test_chains_cli.py +144 -0
- truss/tests/cli/test_cli.py +134 -1
- truss/tests/cli/test_cli_utils_common.py +11 -0
- truss/tests/cli/test_model_team_resolver.py +279 -0
- truss/tests/cli/train/test_cache_view.py +240 -3
- truss/tests/cli/train/test_deploy_checkpoints.py +2 -846
- truss/tests/cli/train/test_train_cli_core.py +2 -2
- truss/tests/cli/train/test_train_team_parameter.py +395 -0
- truss/tests/conftest.py +187 -0
- truss/tests/contexts/image_builder/test_serving_image_builder.py +10 -5
- truss/tests/remote/baseten/test_api.py +122 -3
- truss/tests/remote/baseten/test_chain_upload.py +294 -0
- truss/tests/remote/baseten/test_core.py +86 -0
- truss/tests/remote/baseten/test_remote.py +216 -288
- truss/tests/remote/baseten/test_service.py +56 -0
- truss/tests/templates/control/control/conftest.py +20 -0
- truss/tests/templates/control/control/test_endpoints.py +4 -0
- truss/tests/templates/control/control/test_server.py +8 -24
- truss/tests/templates/control/control/test_server_integration.py +4 -2
- truss/tests/test_config.py +21 -12
- truss/tests/test_data/server.Dockerfile +3 -1
- truss/tests/test_data/test_build_commands_truss/__init__.py +0 -0
- truss/tests/test_data/test_build_commands_truss/config.yaml +14 -0
- truss/tests/test_data/test_build_commands_truss/model/model.py +12 -0
- truss/tests/test_data/test_build_commands_truss/packages/constants/constants.py +1 -0
- truss/tests/test_data/test_truss_server_model_cache_v1/config.yaml +1 -0
- truss/tests/test_model_inference.py +13 -0
- truss/tests/util/test_env_vars.py +8 -3
- truss/util/__init__.py +0 -0
- truss/util/env_vars.py +19 -8
- truss/util/error_utils.py +37 -0
- {truss-0.11.6rc102.dist-info → truss-0.11.24rc2.dist-info}/METADATA +2 -2
- {truss-0.11.6rc102.dist-info → truss-0.11.24rc2.dist-info}/RECORD +88 -70
- {truss-0.11.6rc102.dist-info → truss-0.11.24rc2.dist-info}/WHEEL +1 -1
- truss_chains/deployment/deployment_client.py +16 -4
- truss_chains/private_types.py +18 -0
- truss_chains/public_api.py +3 -0
- truss_train/definitions.py +6 -4
- truss_train/deployment.py +43 -21
- truss_train/public_api.py +4 -2
- {truss-0.11.6rc102.dist-info → truss-0.11.24rc2.dist-info}/entry_points.txt +0 -0
- {truss-0.11.6rc102.dist-info → truss-0.11.24rc2.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,30 +1,15 @@
|
|
|
1
1
|
import os
|
|
2
2
|
import socket
|
|
3
|
-
import sys
|
|
4
3
|
from contextlib import contextmanager
|
|
5
|
-
from pathlib import Path
|
|
6
4
|
from typing import Dict, List
|
|
7
5
|
from unittest.mock import AsyncMock, patch
|
|
8
6
|
|
|
9
7
|
import httpx
|
|
10
8
|
import pytest
|
|
11
9
|
|
|
12
|
-
from truss.
|
|
13
|
-
|
|
14
|
-
# Needed to simulate the set up on the model docker container
|
|
15
|
-
sys.path.append(
|
|
16
|
-
str(
|
|
17
|
-
Path(__file__).parent.parent.parent.parent.parent
|
|
18
|
-
/ "templates"
|
|
19
|
-
/ "control"
|
|
20
|
-
/ "control"
|
|
21
|
-
)
|
|
22
|
-
)
|
|
10
|
+
from truss.tests.templates.control.control.conftest import setup_control_imports
|
|
23
11
|
|
|
24
|
-
|
|
25
|
-
sys.path.append(
|
|
26
|
-
str(Path(__file__).parent.parent.parent.parent.parent / "templates" / "shared")
|
|
27
|
-
)
|
|
12
|
+
setup_control_imports()
|
|
28
13
|
|
|
29
14
|
from truss.templates.control.control.application import create_app # noqa
|
|
30
15
|
from truss.templates.control.control.helpers.custom_types import ( # noqa
|
|
@@ -34,6 +19,7 @@ from truss.templates.control.control.helpers.custom_types import ( # noqa
|
|
|
34
19
|
PatchType,
|
|
35
20
|
PythonRequirementPatch,
|
|
36
21
|
)
|
|
22
|
+
from truss.truss_handle.patch.custom_types import PatchRequest
|
|
37
23
|
|
|
38
24
|
|
|
39
25
|
@pytest.fixture
|
|
@@ -67,7 +53,7 @@ def app(truss_container_fs, truss_original_hash, ports):
|
|
|
67
53
|
"control_server_port": ports["control_server_port"],
|
|
68
54
|
"inference_server_port": ports["inference_server_port"],
|
|
69
55
|
"oversee_inference_server": False,
|
|
70
|
-
"
|
|
56
|
+
"uv_path": "uv",
|
|
71
57
|
}
|
|
72
58
|
)
|
|
73
59
|
inference_server_controller = control_app.state.inference_server_controller
|
|
@@ -273,14 +259,12 @@ async def test_retries(client, app):
|
|
|
273
259
|
]
|
|
274
260
|
)
|
|
275
261
|
|
|
276
|
-
with (
|
|
277
|
-
|
|
278
|
-
pytest.raises(httpx.RemoteProtocolError),
|
|
279
|
-
):
|
|
280
|
-
await client.get("/v1/models/model")
|
|
262
|
+
with patch("endpoints.INFERENCE_SERVER_START_WAIT_SECS", new=4):
|
|
263
|
+
resp = await client.get("/v1/models/model")
|
|
281
264
|
|
|
282
|
-
# We should have made 5 attempts
|
|
265
|
+
# We should have made 5 attempts, and then surfaced a 500
|
|
283
266
|
assert app.state.proxy_client.send.call_count == 5
|
|
267
|
+
assert resp.status_code == 500
|
|
284
268
|
|
|
285
269
|
|
|
286
270
|
async def _verify_apply_patch_success(client, patch: Patch):
|
|
@@ -35,10 +35,12 @@ def _start_truss_server(
|
|
|
35
35
|
f"http://localhost:{patch_ping_server_port}"
|
|
36
36
|
)
|
|
37
37
|
sys.stdout = open(stdout_capture_file_path, "w")
|
|
38
|
+
|
|
39
|
+
# NB(nikhil): Insert paths at the beginning to ensure we search there first.
|
|
38
40
|
app_path = truss_control_container_fs / "app"
|
|
39
|
-
sys.path.
|
|
41
|
+
sys.path.insert(0, str(app_path))
|
|
40
42
|
control_path = truss_control_container_fs / "control" / "control"
|
|
41
|
-
sys.path.
|
|
43
|
+
sys.path.insert(0, str(control_path))
|
|
42
44
|
|
|
43
45
|
from server import ControlServer
|
|
44
46
|
|
truss/tests/test_config.py
CHANGED
|
@@ -23,6 +23,7 @@ from truss.base.truss_config import (
|
|
|
23
23
|
HTTPOptions,
|
|
24
24
|
ModelCache,
|
|
25
25
|
ModelRepo,
|
|
26
|
+
ModelRepoCacheInternal,
|
|
26
27
|
Resources,
|
|
27
28
|
Runtime,
|
|
28
29
|
TransportKind,
|
|
@@ -292,7 +293,10 @@ def test_cache_internal_with_models(default_config):
|
|
|
292
293
|
config = TrussConfig(
|
|
293
294
|
python_version="py39",
|
|
294
295
|
cache_internal=CacheInternal(
|
|
295
|
-
[
|
|
296
|
+
[
|
|
297
|
+
ModelRepoCacheInternal(repo_id="test/model"),
|
|
298
|
+
ModelRepoCacheInternal(repo_id="test/model2"),
|
|
299
|
+
]
|
|
296
300
|
),
|
|
297
301
|
)
|
|
298
302
|
new_config = default_config
|
|
@@ -305,11 +309,12 @@ def test_cache_internal_with_models(default_config):
|
|
|
305
309
|
|
|
306
310
|
def test_huggingface_cache_single_model_default_revision(default_config):
|
|
307
311
|
config = TrussConfig(
|
|
308
|
-
python_version="py39",
|
|
312
|
+
python_version="py39",
|
|
313
|
+
model_cache=ModelCache([ModelRepo(repo_id="test/model", use_volume=False)]),
|
|
309
314
|
)
|
|
310
315
|
|
|
311
316
|
new_config = default_config
|
|
312
|
-
new_config["model_cache"] = [{"repo_id": "test/model"}]
|
|
317
|
+
new_config["model_cache"] = [{"repo_id": "test/model", "use_volume": False}]
|
|
313
318
|
|
|
314
319
|
assert new_config == config.to_dict(verbose=False)
|
|
315
320
|
assert config.to_dict(verbose=True)["model_cache"][0].get("revision") is None
|
|
@@ -319,7 +324,9 @@ def test_huggingface_cache_single_model_non_default_revision_v1():
|
|
|
319
324
|
config = TrussConfig(
|
|
320
325
|
python_version="py39",
|
|
321
326
|
requirements=[],
|
|
322
|
-
model_cache=ModelCache(
|
|
327
|
+
model_cache=ModelCache(
|
|
328
|
+
[ModelRepo(repo_id="test/model", revision="not-main", use_volume=False)]
|
|
329
|
+
),
|
|
323
330
|
)
|
|
324
331
|
|
|
325
332
|
assert config.to_dict(verbose=False)["model_cache"][0].get("revision") == "not-main"
|
|
@@ -330,16 +337,16 @@ def test_huggingface_cache_multiple_models_default_revision(default_config):
|
|
|
330
337
|
python_version="py39",
|
|
331
338
|
model_cache=ModelCache(
|
|
332
339
|
[
|
|
333
|
-
ModelRepo(repo_id="test/model1", revision="main"),
|
|
334
|
-
ModelRepo(repo_id="test/model2"),
|
|
340
|
+
ModelRepo(repo_id="test/model1", revision="main", use_volume=False),
|
|
341
|
+
ModelRepo(repo_id="test/model2", use_volume=False),
|
|
335
342
|
]
|
|
336
343
|
),
|
|
337
344
|
)
|
|
338
345
|
|
|
339
346
|
new_config = default_config
|
|
340
347
|
new_config["model_cache"] = [
|
|
341
|
-
{"repo_id": "test/model1", "revision": "main"},
|
|
342
|
-
{"repo_id": "test/model2"},
|
|
348
|
+
{"repo_id": "test/model1", "revision": "main", "use_volume": False},
|
|
349
|
+
{"repo_id": "test/model2", "use_volume": False},
|
|
343
350
|
]
|
|
344
351
|
|
|
345
352
|
assert new_config == config.to_dict(verbose=False)
|
|
@@ -355,16 +362,18 @@ def test_huggingface_cache_multiple_models_mixed_revision(default_config):
|
|
|
355
362
|
python_version="py39",
|
|
356
363
|
model_cache=ModelCache(
|
|
357
364
|
[
|
|
358
|
-
ModelRepo(repo_id="test/model1"),
|
|
359
|
-
ModelRepo(
|
|
365
|
+
ModelRepo(repo_id="test/model1", use_volume=False),
|
|
366
|
+
ModelRepo(
|
|
367
|
+
repo_id="test/model2", revision="not-main2", use_volume=False
|
|
368
|
+
),
|
|
360
369
|
]
|
|
361
370
|
),
|
|
362
371
|
)
|
|
363
372
|
|
|
364
373
|
new_config = default_config
|
|
365
374
|
new_config["model_cache"] = [
|
|
366
|
-
{"repo_id": "test/model1"},
|
|
367
|
-
{"repo_id": "test/model2", "revision": "not-main2"},
|
|
375
|
+
{"repo_id": "test/model1", "use_volume": False},
|
|
376
|
+
{"repo_id": "test/model2", "revision": "not-main2", "use_volume": False},
|
|
368
377
|
]
|
|
369
378
|
|
|
370
379
|
assert new_config == config.to_dict(verbose=False)
|
|
@@ -17,7 +17,8 @@ RUN /usr/local/bin/python3 -c "import sys; \
|
|
|
17
17
|
|| { echo "ERROR: Supplied base image does not have 3.8 <= python <= 3.13"; exit 1; }
|
|
18
18
|
RUN if ! command -v uv >/dev/null 2>&1; then \
|
|
19
19
|
command -v curl >/dev/null 2>&1 || (apt update && apt install -y curl) && \
|
|
20
|
-
curl -LsSf --retry 5 --retry-delay 5 https://astral.sh/uv/0.
|
|
20
|
+
curl -LsSf --retry 5 --retry-delay 5 https://astral.sh/uv/0.8.22/install.sh | sh && \
|
|
21
|
+
test -x ${HOME}/.local/bin/uv; \
|
|
21
22
|
fi
|
|
22
23
|
ENV PATH=${PATH}:${HOME}/.local/bin
|
|
23
24
|
ENV PYTHONUNBUFFERED="True"
|
|
@@ -35,6 +36,7 @@ COPY --chown= ./data ${APP_HOME}/data
|
|
|
35
36
|
COPY --chown= ./server ${APP_HOME}
|
|
36
37
|
COPY --chown= ./config.yaml ${APP_HOME}/config.yaml
|
|
37
38
|
COPY --chown= ./model ${APP_HOME}/model
|
|
39
|
+
RUN mkdir -p /packages
|
|
38
40
|
COPY --chown= ./packages /packages
|
|
39
41
|
ENV INFERENCE_SERVER_PORT="8080"
|
|
40
42
|
ENV SERVER_START_CMD="/usr/local/bin/python3 /app/main.py"
|
|
File without changes
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
environment_variables: {}
|
|
2
|
+
external_package_dirs: []
|
|
3
|
+
model_metadata: {}
|
|
4
|
+
model_name: Test Build Commands
|
|
5
|
+
python_version: py39
|
|
6
|
+
resources:
|
|
7
|
+
accelerator: null
|
|
8
|
+
cpu: '1'
|
|
9
|
+
memory: 2Gi
|
|
10
|
+
use_gpu: false
|
|
11
|
+
secrets: {}
|
|
12
|
+
system_packages: []
|
|
13
|
+
build_commands:
|
|
14
|
+
- sed -i 's/TEST_FIRST_VALUE/TEST_SECOND_VALUE/g' /packages/constants/constants.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
TEST_KEY = "TEST_FIRST_VALUE"
|
|
@@ -2099,3 +2099,16 @@ async def test_websocket_ping_timeout_behavior(caplog):
|
|
|
2099
2099
|
|
|
2100
2100
|
# We wait 3 seconds, so there should be ~3 PING/PONGS
|
|
2101
2101
|
assert 2 <= caplog.text.count("PING") <= 4
|
|
2102
|
+
|
|
2103
|
+
|
|
2104
|
+
@pytest.mark.integration
|
|
2105
|
+
def test_build_commands_on_model_files(test_data_path):
|
|
2106
|
+
with ensure_kill_all():
|
|
2107
|
+
truss_dir = test_data_path / "test_build_commands_truss"
|
|
2108
|
+
tr = TrussHandle(truss_dir)
|
|
2109
|
+
container, urls = tr.docker_run_for_test()
|
|
2110
|
+
time.sleep(3) # Sleeping to allow the load to finish
|
|
2111
|
+
|
|
2112
|
+
response = requests.post(urls.predict_url, json={})
|
|
2113
|
+
assert response.status_code == 200
|
|
2114
|
+
assert response.json() == "TEST_SECOND_VALUE"
|
|
@@ -1,14 +1,19 @@
|
|
|
1
1
|
import os
|
|
2
2
|
|
|
3
|
-
from truss.util.env_vars import
|
|
3
|
+
from truss.util.env_vars import modify_env_vars
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
def
|
|
6
|
+
def test_modify_env_vars():
|
|
7
7
|
os.environ["API_KEY"] = "original_key"
|
|
8
|
+
os.environ["AWS_CONFIG_FILE"] = "original_config_file"
|
|
8
9
|
|
|
9
|
-
with
|
|
10
|
+
with modify_env_vars(
|
|
11
|
+
overrides={"API_KEY": "new_key", "DEBUG": "true"}, deletions={"AWS_CONFIG_FILE"}
|
|
12
|
+
):
|
|
10
13
|
assert os.environ["API_KEY"] == "new_key"
|
|
11
14
|
assert os.environ["DEBUG"] == "true"
|
|
15
|
+
assert "AWS_CONFIG_FILE" not in os.environ
|
|
12
16
|
|
|
13
17
|
assert os.environ["API_KEY"] == "original_key"
|
|
14
18
|
assert "DEBUG" not in os.environ
|
|
19
|
+
assert os.environ["AWS_CONFIG_FILE"] == "original_config_file"
|
truss/util/__init__.py
ADDED
|
File without changes
|
truss/util/env_vars.py
CHANGED
|
@@ -1,32 +1,43 @@
|
|
|
1
1
|
import os
|
|
2
|
-
from typing import Dict, Optional
|
|
2
|
+
from typing import Dict, Optional, Set
|
|
3
3
|
|
|
4
4
|
|
|
5
|
-
class
|
|
5
|
+
class modify_env_vars:
|
|
6
6
|
"""A context manager for temporarily overwriting environment variables.
|
|
7
7
|
|
|
8
8
|
Usage:
|
|
9
|
-
with
|
|
9
|
+
with modify_env_vars(overrides={'API_KEY': 'test_key', 'DEBUG': 'true'}, deletions={'AWS_CONFIG_FILE'}):
|
|
10
10
|
# Environment variables are modified here
|
|
11
11
|
...
|
|
12
12
|
# Original environment is restored here
|
|
13
13
|
"""
|
|
14
14
|
|
|
15
|
-
def __init__(
|
|
15
|
+
def __init__(
|
|
16
|
+
self,
|
|
17
|
+
overrides: Optional[Dict[str, str]] = None,
|
|
18
|
+
deletions: Optional[Set[str]] = None,
|
|
19
|
+
):
|
|
16
20
|
"""
|
|
17
21
|
Args:
|
|
18
|
-
|
|
22
|
+
overrides: Dictionary of environment variables to set
|
|
23
|
+
deletions: Set of environment variables to delete
|
|
19
24
|
"""
|
|
20
|
-
self.
|
|
25
|
+
self.overrides: Dict[str, str] = overrides or dict()
|
|
26
|
+
self.deletions: Set[str] = deletions or set()
|
|
21
27
|
self.original_vars: Dict[str, Optional[str]] = {}
|
|
22
28
|
|
|
23
29
|
def __enter__(self):
|
|
24
|
-
|
|
30
|
+
all_keys = set(self.overrides.keys()) | self.deletions
|
|
31
|
+
for key in all_keys:
|
|
25
32
|
self.original_vars[key] = os.environ.get(key)
|
|
26
33
|
|
|
27
|
-
for key, value in self.
|
|
34
|
+
for key, value in self.overrides.items():
|
|
28
35
|
os.environ[key] = value
|
|
29
36
|
|
|
37
|
+
for key in self.deletions:
|
|
38
|
+
if key in os.environ:
|
|
39
|
+
del os.environ[key]
|
|
40
|
+
|
|
30
41
|
return self
|
|
31
42
|
|
|
32
43
|
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from contextlib import contextmanager
|
|
3
|
+
from typing import Generator
|
|
4
|
+
|
|
5
|
+
from botocore.exceptions import ClientError, NoCredentialsError
|
|
6
|
+
|
|
7
|
+
logger = logging.getLogger(__name__)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@contextmanager
|
|
11
|
+
def handle_client_error(
|
|
12
|
+
operation_description: str = "AWS operation",
|
|
13
|
+
) -> Generator[None, None, None]:
|
|
14
|
+
"""
|
|
15
|
+
Context manager to handle common boto3 errors and convert them to RuntimeError.
|
|
16
|
+
|
|
17
|
+
Args:
|
|
18
|
+
operation_description: Description of the operation being performed for error messages
|
|
19
|
+
|
|
20
|
+
Raises:
|
|
21
|
+
RuntimeError: For NoCredentialsError, ClientError, and other exceptions
|
|
22
|
+
"""
|
|
23
|
+
try:
|
|
24
|
+
yield
|
|
25
|
+
except NoCredentialsError as nce:
|
|
26
|
+
raise RuntimeError(
|
|
27
|
+
f"No AWS credentials found for {operation_description}\nOriginal exception: {str(nce)}"
|
|
28
|
+
)
|
|
29
|
+
except ClientError as ce:
|
|
30
|
+
raise RuntimeError(
|
|
31
|
+
f"AWS client error when {operation_description} (check your credentials): {str(ce)}"
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
except Exception as exc:
|
|
35
|
+
raise RuntimeError(
|
|
36
|
+
f"Unexpected error `{exc}` during `{operation_description}`\nOriginal exception: {str(exc)}"
|
|
37
|
+
)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: truss
|
|
3
|
-
Version: 0.11.
|
|
3
|
+
Version: 0.11.24rc2
|
|
4
4
|
Summary: A seamless bridge from model development to model delivery
|
|
5
5
|
Project-URL: Repository, https://github.com/basetenlabs/truss
|
|
6
6
|
Project-URL: Homepage, https://truss.baseten.co
|
|
@@ -37,7 +37,7 @@ Requires-Dist: rich<14,>=13.4.2
|
|
|
37
37
|
Requires-Dist: ruff>=0.4.8
|
|
38
38
|
Requires-Dist: tenacity>=8.0.1
|
|
39
39
|
Requires-Dist: tomlkit>=0.13.2
|
|
40
|
-
Requires-Dist: truss-transfer<0.0.
|
|
40
|
+
Requires-Dist: truss-transfer<0.0.40,>=0.0.37
|
|
41
41
|
Requires-Dist: watchfiles<0.20,>=0.19.0
|
|
42
42
|
Description-Content-Type: text/markdown
|
|
43
43
|
|