truss 0.11.13rc1__py3-none-any.whl → 0.11.13rc2__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.

Potentially problematic release.


This version of truss might be problematic. Click here for more details.

@@ -18,7 +18,7 @@ psutil>=5.9.4
18
18
  python-json-logger>=2.0.2
19
19
  pyyaml>=6.0.0
20
20
  requests>=2.31.0
21
- truss-transfer==0.0.34
21
+ truss-transfer==0.0.37
22
22
  uvicorn>=0.24.0
23
23
  uvloop>=0.19.0
24
24
  websockets>=10.0
@@ -56,6 +56,12 @@ RUN mkdir -p {{ dst.parent }}; curl -L "{{ url }}" -o {{ dst }}
56
56
  {% endfor %} {#- endfor external_data_files #}
57
57
  {%- endif %} {#- endif external_data_files #}
58
58
 
59
+ {%- if build_commands %}
60
+ {% for command in build_commands %}
61
+ RUN {% for secret,path in config.build.secret_to_path_mapping.items() %} --mount=type=secret,id={{ secret }},target={{ path }}{%- endfor %} {{ command }}
62
+ {% endfor %} {#- endfor build_commands #}
63
+ {%- endif %} {#- endif build_commands #}
64
+
59
65
  {# Copy data before code for better caching #}
60
66
  {%- if data_dir_exists %}
61
67
  COPY --chown={{ default_owner }} ./{{ config.data_dir }} ${APP_HOME}/data
@@ -63,7 +69,7 @@ COPY --chown={{ default_owner }} ./{{ config.data_dir }} ${APP_HOME}/data
63
69
 
64
70
  {%- if model_cache_v2 %}
65
71
  {# v0.0.9, keep synced with server_requirements.txt #}
66
- RUN curl -sSL --fail --retry 5 --retry-delay 2 -o /usr/local/bin/truss-transfer-cli https://github.com/basetenlabs/truss/releases/download/v0.11.12rc0/truss-transfer-cli-v0.11.12rc0-linux-x86_64-unknown-linux-musl
72
+ RUN curl -sSL --fail --retry 5 --retry-delay 2 -o /usr/local/bin/truss-transfer-cli https://github.com/basetenlabs/truss/releases/download/v0.11.12rc4/truss-transfer-cli-v0.11.12rc4-linux-x86_64-unknown-linux-musl
67
73
  RUN chmod +x /usr/local/bin/truss-transfer-cli
68
74
  RUN mkdir /static-bptr
69
75
  RUN echo "hash {{model_cache_hash}}"
@@ -95,12 +101,6 @@ COPY --chown={{ default_owner }} ./{{ config.model_module_dir }} ${APP_HOME}/mod
95
101
  {% endblock %} {#- endblock app_copy #}
96
102
 
97
103
  {% block run %}
98
- {%- if build_commands %}
99
- {% for command in build_commands %}
100
- RUN {% for secret,path in config.build.secret_to_path_mapping.items() %} --mount=type=secret,id={{ secret }},target={{ path }}{%- endfor %} {{ command }}
101
- {% endfor %} {#- endfor build_commands #}
102
- {%- endif %} {#- endif build_commands #}
103
-
104
104
  {# Macro to change ownership of directories and switch to regular user #}
105
105
  {%- macro chown_and_switch_to_regular_user_if_enabled(additional_chown_dirs=[]) -%}
106
106
  {%- if non_root_user %}
@@ -1,11 +1,67 @@
1
1
  import atexit
2
+ import json
2
3
  import logging
3
4
  import time
5
+ from dataclasses import dataclass
4
6
  from functools import lru_cache
5
7
  from pathlib import Path
6
8
  from threading import Lock, Thread
7
9
  from typing import Optional, Union
8
10
 
11
+
12
+ @dataclass(frozen=True)
13
+ class FileDownloadMetric:
14
+ file_name: str
15
+ file_size_bytes: int
16
+ download_time_secs: float
17
+ download_speed_mb_s: float
18
+
19
+
20
+ @dataclass(frozen=True)
21
+ class TrussTransferStats:
22
+ total_manifest_size_bytes: int
23
+ total_download_time_secs: float
24
+ total_aggregated_mb_s: Optional[float]
25
+ file_downloads: list[FileDownloadMetric]
26
+ b10fs_read_speed_mbps: Optional[float]
27
+ b10fs_decision_to_use: bool
28
+ b10fs_enabled: bool
29
+ b10fs_hot_starts_files: int
30
+ b10fs_hot_starts_bytes: int
31
+ b10fs_cold_starts_files: int
32
+ b10fs_cold_starts_bytes: int
33
+ success: bool
34
+ timestamp: int
35
+
36
+ @classmethod
37
+ def from_json_file(cls, path: Path) -> Optional["TrussTransferStats"]:
38
+ if not path.exists():
39
+ return None
40
+ try:
41
+ with open(path) as f:
42
+ data = json.load(f)
43
+ file_downloads = [
44
+ FileDownloadMetric(**fd) for fd in data.get("file_downloads", [])
45
+ ]
46
+ return cls(
47
+ total_manifest_size_bytes=data["total_manifest_size_bytes"],
48
+ total_download_time_secs=data["total_download_time_secs"],
49
+ total_aggregated_mb_s=data.get("total_aggregated_mb_s"),
50
+ file_downloads=file_downloads,
51
+ b10fs_read_speed_mbps=data.get("b10fs_read_speed_mbps"),
52
+ b10fs_decision_to_use=data["b10fs_decision_to_use"],
53
+ b10fs_enabled=data["b10fs_enabled"],
54
+ b10fs_hot_starts_files=data["b10fs_hot_starts_files"],
55
+ b10fs_hot_starts_bytes=data["b10fs_hot_starts_bytes"],
56
+ b10fs_cold_starts_files=data["b10fs_cold_starts_files"],
57
+ b10fs_cold_starts_bytes=data["b10fs_cold_starts_bytes"],
58
+ success=data["success"],
59
+ timestamp=data["timestamp"],
60
+ )
61
+ except Exception:
62
+ return None
63
+
64
+
9
65
  LAZY_DATA_RESOLVER_PATH = [
10
66
  # synced with pub static LAZY_DATA_RESOLVER_PATHS: &[&str]
11
67
  Path("/bptr/bptr-manifest"),
@@ -137,6 +193,14 @@ class LazyDataResolverV2:
137
193
  f"Error occurred while fetching data: {result}"
138
194
  ) from result
139
195
  if log_stats and result:
196
+ # TODO: instument the stats, which are written to /tmp/truss_transfer_stats.json
197
+ # also add fetch time, and blocking time
198
+ # TrussTransferStats
199
+ stats = TrussTransferStats.from_json_file(
200
+ Path("/tmp/truss_transfer_stats.json")
201
+ )
202
+ if stats is None:
203
+ self.logger.info(f"model_cache: {stats}")
140
204
  self.logger.info(
141
205
  f"model_cache: Fetch took {time.time() - self._start_time:.2f} seconds, of which {time.time() - start_lock:.2f} seconds were spent blocking."
142
206
  )
truss/tests/conftest.py CHANGED
@@ -700,15 +700,6 @@ def helpers():
700
700
  return Helpers()
701
701
 
702
702
 
703
- @pytest.fixture
704
- def test_editable_external_pkg(test_data_path, tmp_path):
705
- truss_dir = test_data_path / "test_editable_external_pkg"
706
- parent_dir = test_data_path / "test_editable_external_pkg_parent"
707
- shutil.copytree(truss_dir, tmp_path / "test_editable_external_pkg")
708
- shutil.copytree(parent_dir, tmp_path / "test_editable_external_pkg_parent")
709
- return tmp_path / "test_editable_external_pkg"
710
-
711
-
712
703
  def _build_truss_fs(truss_dir: Path, tmp_path: Path) -> Path:
713
704
  truss_fs = tmp_path / "truss_fs"
714
705
  truss_fs.mkdir()
@@ -12,9 +12,6 @@ from truss.base.constants import SUPPORTED_PYTHON_VERSIONS
12
12
  from truss.base.custom_types import Example
13
13
  from truss.base.errors import ContainerIsDownError, ContainerNotFoundError
14
14
  from truss.base.truss_config import map_local_to_supported_python_version
15
- from truss.contexts.image_builder.serving_image_builder import (
16
- ServingImageBuilderContext,
17
- )
18
15
  from truss.contexts.image_builder.util import TRUSS_BASE_IMAGE_VERSION_TAG
19
16
  from truss.local.local_config_handler import LocalConfigHandler
20
17
  from truss.templates.control.control.helpers.custom_types import (
@@ -483,27 +480,6 @@ def test_build_commands(test_data_path):
483
480
  assert r1 == {"predictions": [1, 2]}
484
481
 
485
482
 
486
- def test_build_commands_in_run_block_order(test_data_path, tmp_path):
487
- truss_dir = test_data_path / "test_editable_external_pkg"
488
- build_dir = tmp_path / "build_dir"
489
- image_builder = ServingImageBuilderContext.run(truss_dir)
490
- image_builder.prepare_image_build_dir(build_dir)
491
- dockerfile = (build_dir / "Dockerfile").read_text()
492
-
493
- cmd_idx = dockerfile.find("uv pip install --system -e /packages/local_pkg")
494
- if cmd_idx == -1:
495
- cmd_idx = dockerfile.find("uv pip install -e /packages/local_pkg")
496
- if cmd_idx == -1:
497
- cmd_idx = dockerfile.find("pip install -e /packages/local_pkg")
498
- assert cmd_idx != -1
499
-
500
- entry_idx = dockerfile.find("ENTRYPOINT ")
501
- user_idx = dockerfile.find("\nUSER ")
502
- if user_idx != -1:
503
- assert cmd_idx < user_idx
504
- assert cmd_idx < entry_idx
505
-
506
-
507
483
  @pytest.mark.integration
508
484
  def test_build_commands_failure(test_data_path):
509
485
  truss_dir = test_data_path / "test_build_commands_failure"
@@ -872,21 +848,3 @@ def test_config_verbose(custom_model_truss_dir_with_pre_and_post):
872
848
  th.live_reload()
873
849
  new_config["live_reload"] = True
874
850
  assert new_config == th.spec.config.to_dict(verbose=False)
875
-
876
-
877
- @pytest.mark.integration
878
- def test_editable_external_package_install_and_predict(test_editable_external_pkg):
879
- th = TrussHandle(test_editable_external_pkg)
880
- # Ensure standard inference server flow for this test
881
- th.live_reload(False)
882
- tag = "test-editable-ext-pkg:0.0.1"
883
- with ensure_kill_all():
884
- container = th.docker_run(tag=tag, local_port=None)
885
- try:
886
- verify_python_requirement_installed_on_container(container, "local-pkg")
887
- finally:
888
- Docker.client().kill(container)
889
-
890
- with ensure_kill_all():
891
- result = th.docker_predict([1], tag=tag, local_port=None)
892
- assert result == {"predictions": [42]}
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: truss
3
- Version: 0.11.13rc1
3
+ Version: 0.11.13rc2
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.36,>=0.0.32
40
+ Requires-Dist: truss-transfer<0.0.40,>=0.0.36
41
41
  Requires-Dist: watchfiles<0.20,>=0.19.0
42
42
  Description-Content-Type: text/markdown
43
43
 
@@ -71,7 +71,7 @@ truss/templates/cache.Dockerfile.jinja,sha256=1qZqDo1phrcqi-Vwol-VafYJkADsBbQWU6
71
71
  truss/templates/cache_requirements.txt,sha256=xoPoJ-OVnf1z6oq_RVM3vCr3ionByyqMLj7wGs61nUs,87
72
72
  truss/templates/copy_cache_files.Dockerfile.jinja,sha256=Os5zFdYLZ_AfCRGq4RcpVTObOTwL7zvmwYcvOzd_Zqo,126
73
73
  truss/templates/docker_server_requirements.txt,sha256=PyhOPKAmKW1N2vLvTfLMwsEtuGpoRrbWuNo7tT6v2Mc,18
74
- truss/templates/server.Dockerfile.jinja,sha256=iXHFqmi1Ug6oFl-8k3yPLo0dyXI98G8UwZPSM9p4tpE,7071
74
+ truss/templates/server.Dockerfile.jinja,sha256=BQpo2Mt_fBrdin1qD8HBKBo2N3Yr2lXrvV_a7J5WSzE,7071
75
75
  truss/templates/control/requirements.txt,sha256=tJGr83WoE0CZm2FrloZ9VScK84q-_FTuVXjDYrexhW0,250
76
76
  truss/templates/control/control/application.py,sha256=5Kam6M-XtfKGaXQz8cc3d0bwDkB80o2MskABWROx1gk,5321
77
77
  truss/templates/control/control/endpoints.py,sha256=KzqsLVNJE6r6TCPW8D5FMCtsfHadTwR15A3z_viGxmM,11782
@@ -96,7 +96,7 @@ truss/templates/docker_server/supervisord.conf.jinja,sha256=dd37fwZE--cutrvOUCqE
96
96
  truss/templates/server/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
97
97
  truss/templates/server/main.py,sha256=kWXrdD8z8IpamyWxc8qcvd5ck9gM1Kz2QH5qHJCnmOQ,222
98
98
  truss/templates/server/model_wrapper.py,sha256=k75VVISwwlsx5EGb82UZsu8kCM_i6Yi3-Hd0-Kpm1yo,42055
99
- truss/templates/server/requirements.txt,sha256=oHhuasv7ImNsthlZbXzN8rA_WPNXEylE4FcFGo7JIqw,672
99
+ truss/templates/server/requirements.txt,sha256=ZRnawwwAMkf88-S5GhXdjkLzB36IRg11AKUvIOV8kxg,672
100
100
  truss/templates/server/truss_server.py,sha256=YKcG7Sr0T_8XjIC3GK9vBwoNb8oxVgwic3-3Ikzpmgw,19781
101
101
  truss/templates/server/common/__init__.py,sha256=qHIqr68L5Tn4mV6S-PbORpcuJ4jmtBR8aCuRTIWDvNo,85
102
102
  truss/templates/server/common/errors.py,sha256=My0P6-Y7imVTICIhazHT0vlSu3XJDH7As06OyVzu4Do,8589
@@ -107,7 +107,7 @@ truss/templates/server/common/tracing.py,sha256=XSTXNoRtV8vXwveJoX3H32go0JKnLmzn
107
107
  truss/templates/server/common/patches/whisper/patch.py,sha256=kDECQ-wmEpeAZFhUTQP457ofueeMsm7DgNy9tqinhJQ,2383
108
108
  truss/templates/shared/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
109
109
  truss/templates/shared/dynamic_config_resolver.py,sha256=75s42NFhQI5jL7BqlJH_UkuQS7ptbtFh13f2nh6X5Wo,920
110
- truss/templates/shared/lazy_data_resolver.py,sha256=SMw3L24R_UkNXuL0fO-AN02rUTHfy0Aiz3JTyS0PAEc,5978
110
+ truss/templates/shared/lazy_data_resolver.py,sha256=eOq7Fgr9QkAWpsxyDWkeZic1Z2S4Mt-drB1A7zNEkYE,8368
111
111
  truss/templates/shared/log_config.py,sha256=l9udyu4VKHZePlfK9LQEd5TOUUodPuehypsXRSUL4Ac,5411
112
112
  truss/templates/shared/secrets_resolver.py,sha256=3prDe3Q06NTmUEe7KCW-W4TD1CzGck9lpDG789209z4,2110
113
113
  truss/templates/shared/serialization.py,sha256=_WC_2PPkRi-MdTwxwjG8LKQptnHi4sANfpOlKWevqWc,3736
@@ -126,7 +126,7 @@ truss/templates/trtllm-audio/packages/whisper_trt/utils.py,sha256=pi-c486yPe85Te
126
126
  truss/templates/trtllm-briton/README.md,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
127
127
  truss/templates/trtllm-briton/src/extension.py,sha256=6qwYPIYQEmXd2xz50-v80Nilc_xLAMgdYkHu2JWboH4,2655
128
128
  truss/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
129
- truss/tests/conftest.py,sha256=m803zxkmU1GXq6Cdwq8O7cyTJDTOY_XcpJgegHPz_uQ,24632
129
+ truss/tests/conftest.py,sha256=LCP-knM4UsQYvGd2Vbv2hHnbPCuOELCqPui31DrtxyM,24221
130
130
  truss/tests/helpers.py,sha256=DKnUGzmt-k4IN_wSnlAXbVYCiEt58xFzFmmuCDSQ0dg,555
131
131
  truss/tests/test_build.py,sha256=Wq4sM9tmZFVTCN3YljvOcn04Kkj-L-41Tlw0DKQ8Z7c,709
132
132
  truss/tests/test_config.py,sha256=AVpVCL_XHYXKSGHzwecrh7BAJlB_Wr5AUlnnwMqWM98,30559
@@ -138,7 +138,7 @@ truss/tests/test_model_inference.py,sha256=Q8mgNDNbwAUi7AQTgmyK-QrYuksuARDczYndT
138
138
  truss/tests/test_model_schema.py,sha256=Bw28CZ4D0JQOkYdBQJZvgryeW0TRn7Axketp5kvZ_t4,14219
139
139
  truss/tests/test_testing_utilities_for_other_tests.py,sha256=YqIKflnd_BUMYaDBSkX76RWiWGWM_UlC2IoT4NngMqE,3048
140
140
  truss/tests/test_truss_gatherer.py,sha256=bn288OEkC49YY0mhly4cAl410ktZPfElNdWwZy82WfA,1261
141
- truss/tests/test_truss_handle.py,sha256=_f8Ivoi9LI_atIf1U5oXZGijG_Lzb8ssP_2DhufHGg0,32341
141
+ truss/tests/test_truss_handle.py,sha256=-xz9VXkecXDTslmQZ-dmUmQLnvD0uumRqHS2uvGlMBA,30750
142
142
  truss/tests/test_util.py,sha256=hs1bNMkXKEdoPRx4Nw-NAEdoibR92OubZuADGmbiYsQ,1344
143
143
  truss/tests/cli/test_cli.py,sha256=yfbVS5u1hnAmmA8mJ539vj3lhH-JVGUvC4Q_Mbort44,787
144
144
  truss/tests/cli/train/test_cache_view.py,sha256=aVRCh3atRpFbJqyYgq7N-vAW0DiKMftQ7ajUqO2ClOg,22606
@@ -235,10 +235,6 @@ truss/tests/test_data/test_custom_server_truss/test_docker_image/VERSION,sha256=
235
235
  truss/tests/test_data/test_custom_server_truss/test_docker_image/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
236
236
  truss/tests/test_data/test_custom_server_truss/test_docker_image/app.py,sha256=9KXdwDHzVvTnsEkKKOJnM41cWpN4Iozv4nbNqKIL5mo,364
237
237
  truss/tests/test_data/test_custom_server_truss/test_docker_image/build_upload_new_image.sh,sha256=3rmSfusTL_g346ha7WgDig8iaQIVdIR1rjrlHh_7l2o,435
238
- truss/tests/test_data/test_editable_external_pkg/config.yaml,sha256=znok04OZWASbq9ETspahO_Ho5Hqpb-kPZNf7JYlteT4,128
239
- truss/tests/test_data/test_editable_external_pkg/model/model.py,sha256=Ni7TTPB0yStyvhgmogdt_CBrfBMFzWwZc2ay1J6ceZA,114
240
- truss/tests/test_data/test_editable_external_pkg_parent/local_pkg/pyproject.toml,sha256=gjxmzcDN_-XIt1t8VyEavmQU-jK9axPhKScODEG0_IE,185
241
- truss/tests/test_data/test_editable_external_pkg_parent/local_pkg/src/local_pkg/__init__.py,sha256=Ccv1rhOmQ6mwI9oQNcYMUBhzHV2WM6htYbGbTj86p-s,11
242
238
  truss/tests/test_data/test_env_vars/config.yaml,sha256=h-yX05GMwfjvnSLHnrSwJYIBDNuEkNWe1hWYLGeImZk,598
243
239
  truss/tests/test_data/test_go_custom_server_truss/config.yaml,sha256=85H3GDtmHAtU5P4PJk77tm04ma1ftv14fdLXBtbWsow,416
244
240
  truss/tests/test_data/test_go_custom_server_truss/docker/Dockerfile,sha256=eggWZ7xVcs-VYAUm2Z6LqSdgaXS9wff611Dz7hVXGUw,123
@@ -374,8 +370,8 @@ truss_train/deployment.py,sha256=lWWANSuzBWu2M4oK4qD7n-oVR1JKdmw2Pn5BJQHg-Ck,307
374
370
  truss_train/loader.py,sha256=0o66EjBaHc2YY4syxxHVR4ordJWs13lNXnKjKq2wq0U,1630
375
371
  truss_train/public_api.py,sha256=9N_NstiUlmBuLUwH_fNG_1x7OhGCytZLNvqKXBlStrM,1220
376
372
  truss_train/restore_from_checkpoint.py,sha256=8hdPm-WSgkt74HDPjvCjZMBpvA9MwtoYsxVjOoa7BaM,1176
377
- truss-0.11.13rc1.dist-info/METADATA,sha256=FMnGd0rxQ0hkl9QrpIMrajJooeZfxIu7e0nWe6vT-BY,6681
378
- truss-0.11.13rc1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
379
- truss-0.11.13rc1.dist-info/entry_points.txt,sha256=-MwKfHHQHQ6j0HqIgvxrz3CehCmczDLTD-OsRHnjjuU,130
380
- truss-0.11.13rc1.dist-info/licenses/LICENSE,sha256=FTqGzu85i-uw1Gi8E_o0oD60bH9yQ_XIGtZbA1QUYiw,1064
381
- truss-0.11.13rc1.dist-info/RECORD,,
373
+ truss-0.11.13rc2.dist-info/METADATA,sha256=GCadCR-s-rOXbH__XXvO5wFJEp-sPcFjpRC1tlcRBwo,6681
374
+ truss-0.11.13rc2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
375
+ truss-0.11.13rc2.dist-info/entry_points.txt,sha256=-MwKfHHQHQ6j0HqIgvxrz3CehCmczDLTD-OsRHnjjuU,130
376
+ truss-0.11.13rc2.dist-info/licenses/LICENSE,sha256=FTqGzu85i-uw1Gi8E_o0oD60bH9yQ_XIGtZbA1QUYiw,1064
377
+ truss-0.11.13rc2.dist-info/RECORD,,
@@ -1,5 +0,0 @@
1
- external_package_dirs:
2
- - ../test_editable_external_pkg_parent
3
-
4
- build_commands:
5
- - uv pip install --system -e /packages/local_pkg
@@ -1,6 +0,0 @@
1
- import local_pkg
2
-
3
-
4
- class Model:
5
- def predict(self, request):
6
- return {"predictions": [local_pkg.VALUE]}
@@ -1,10 +0,0 @@
1
- [build-system]
2
- requires = ["hatchling"]
3
- build-backend = "hatchling.build"
4
-
5
- [project]
6
- name = "local-pkg"
7
- version = "0.0.1"
8
-
9
- [tool.hatch.build.targets.wheel]
10
- packages = ["src/local_pkg"]