truss 0.11.9rc6__py3-none-any.whl → 0.11.10rc1__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.

@@ -17,7 +17,9 @@ class LogWatcher(ABC):
17
17
  # NB(nikhil): we add buffer for clock skew, so this helps us detect duplicates.
18
18
  # TODO(nikhil): clean up hashes so this doesn't grow indefinitely.
19
19
  _log_hashes: set[str] = set()
20
- _last_poll_time: Optional[int] = None
20
+
21
+ _last_poll_time_ms: Optional[int] = None
22
+ _last_log_time_ms: Optional[int] = None
21
23
 
22
24
  def __init__(self, api: BasetenApi):
23
25
  self.api = api
@@ -26,37 +28,54 @@ class LogWatcher(ABC):
26
28
  log_str = f"{log.timestamp}-{log.message}-{log.replica}"
27
29
  return hashlib.sha256(log_str.encode("utf-8")).hexdigest()
28
30
 
29
- def _poll(self) -> Iterator[ParsedLog]:
30
- start_epoch: Optional[int] = None
31
- now = int(time.time() * 1000)
32
- if self._last_poll_time is not None:
33
- start_epoch = self._last_poll_time - CLOCK_SKEW_BUFFER_MS
31
+ def get_start_epoch_ms(self, now_ms: int) -> Optional[int]:
32
+ if self._last_poll_time_ms:
33
+ return self._last_poll_time_ms - CLOCK_SKEW_BUFFER_MS
34
+
35
+ return None
34
36
 
37
+ def fetch_and_parse_logs(
38
+ self, start_epoch_millis: Optional[int], end_epoch_millis: Optional[int]
39
+ ) -> Iterator[ParsedLog]:
35
40
  api_logs = self.fetch_logs(
36
- start_epoch_millis=start_epoch, end_epoch_millis=now + CLOCK_SKEW_BUFFER_MS
41
+ start_epoch_millis=start_epoch_millis, end_epoch_millis=end_epoch_millis
37
42
  )
38
43
 
39
44
  parsed_logs = parse_logs(api_logs)
45
+
40
46
  for log in parsed_logs:
41
- h = self._hash_log(log)
42
- if h not in self._log_hashes:
47
+ if (h := self._hash_log(log)) not in self._log_hashes:
43
48
  self._log_hashes.add(h)
49
+
44
50
  yield log
45
51
 
46
- self._last_poll_time = now
52
+ def poll(self) -> Iterator[ParsedLog]:
53
+ now_ms = int(time.time() * 1000)
54
+ start_epoch_ms = self.get_start_epoch_ms(now_ms)
55
+
56
+ for log in self.fetch_and_parse_logs(
57
+ start_epoch_millis=start_epoch_ms,
58
+ end_epoch_millis=now_ms + CLOCK_SKEW_BUFFER_MS,
59
+ ):
60
+ yield log
61
+
62
+ epoch_ns = int(log.timestamp)
63
+ self._last_log_time_ms = int(epoch_ns / 1e6)
64
+
65
+ self._last_poll_time_ms = now_ms
47
66
 
48
67
  def watch(self) -> Iterator[ParsedLog]:
49
68
  self.before_polling()
50
69
  with console.status("Polling logs", spinner="aesthetic"):
51
70
  while True:
52
- for log in self._poll():
71
+ for log in self.poll():
53
72
  yield log
54
73
  if self._log_hashes:
55
74
  break
56
75
  time.sleep(POLL_INTERVAL_SEC)
57
76
 
58
77
  while self.should_poll_again():
59
- for log in self._poll():
78
+ for log in self.poll():
60
79
  yield log
61
80
  time.sleep(POLL_INTERVAL_SEC)
62
81
  self.post_poll()
@@ -1,9 +1,12 @@
1
+ from functools import cached_property
1
2
  from typing import Any, List, Optional
2
3
 
3
4
  from truss.cli.logs.base_watcher import LogWatcher
4
5
  from truss.remote.baseten.api import BasetenApi
5
6
  from truss.remote.baseten.utils.status import MODEL_RUNNING_STATES
6
7
 
8
+ MAX_LOOK_BACK_MS = 1000 * 60 * 60 # 1 hour.
9
+
7
10
 
8
11
  class ModelDeploymentLogWatcher(LogWatcher):
9
12
  _model_id: str
@@ -25,11 +28,31 @@ class ModelDeploymentLogWatcher(LogWatcher):
25
28
  self._model_id, self._deployment_id, start_epoch_millis, end_epoch_millis
26
29
  )
27
30
 
31
+ def get_start_epoch_ms(self, now_ms: int) -> Optional[int]:
32
+ # NOTE(Tyron): If there can be multiple replicas,
33
+ # we can't use a timestamp cursor to poll for logs.
34
+ if not self._is_development:
35
+ return super().get_start_epoch_ms(now_ms)
36
+
37
+ # Cursor logic.
38
+
39
+ if self._last_log_time_ms:
40
+ return max(self._last_log_time_ms, now_ms - MAX_LOOK_BACK_MS)
41
+
42
+ return None
43
+
28
44
  def should_poll_again(self) -> bool:
29
45
  return self._current_status in MODEL_RUNNING_STATES
30
46
 
47
+ def _get_deployment(self) -> Any:
48
+ return self.api.get_deployment(self._model_id, self._deployment_id)
49
+
31
50
  def _get_current_status(self) -> str:
32
- return self.api.get_deployment(self._model_id, self._deployment_id)["status"]
51
+ return self._get_deployment()["status"]
52
+
53
+ @cached_property
54
+ def _is_development(self) -> bool:
55
+ return self._get_deployment()["is_development"]
33
56
 
34
57
  def post_poll(self) -> None:
35
58
  self._current_status = self._get_current_status()
@@ -40,6 +40,7 @@ class SanitizedExceptionMiddleware(BaseHTTPMiddleware):
40
40
  except Exception as exc:
41
41
  sanitized_traceback = self._create_sanitized_traceback(exc)
42
42
  request.app.state.logger.error(sanitized_traceback)
43
+ request.app.state.logger.error(f"Request headers: {dict(request.headers)}")
43
44
 
44
45
  if isinstance(exc, ModelLoadFailed):
45
46
  return JSONResponse(
@@ -84,10 +85,9 @@ def create_app(base_config: Dict):
84
85
  base_url=f"http://localhost:{app_state.inference_server_port}", limits=limits
85
86
  )
86
87
 
87
- pip_path = getattr(app_state, "pip_path", None)
88
-
88
+ uv_path = getattr(app_state, "uv_path", None)
89
89
  patch_applier = ModelContainerPatchApplier(
90
- Path(app_state.inference_server_home), app_logger, pip_path
90
+ Path(app_state.inference_server_home), app_logger, uv_path
91
91
  )
92
92
 
93
93
  oversee_inference_server = getattr(app_state, "oversee_inference_server", True)
@@ -53,7 +53,7 @@ def app(truss_container_fs, truss_original_hash, ports):
53
53
  "control_server_port": ports["control_server_port"],
54
54
  "inference_server_port": ports["inference_server_port"],
55
55
  "oversee_inference_server": False,
56
- "pip_path": "pip",
56
+ "uv_path": "uv",
57
57
  }
58
58
  )
59
59
  inference_server_controller = control_app.state.inference_server_controller
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: truss
3
- Version: 0.11.9rc6
3
+ Version: 0.11.10rc1
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
@@ -12,8 +12,8 @@ truss/cli/chains_commands.py,sha256=Kpa5mCg6URAJQE2ZmZfVQFhjBHEitKT28tKiW0H6XAI,
12
12
  truss/cli/cli.py,sha256=PaMkuwXZflkU7sa1tEoT_Zmy-iBkEZs1m4IVqcieaeo,30367
13
13
  truss/cli/remote_cli.py,sha256=G_xCKRXzgkCmkiZJhUFfsv5YSVgde1jLA5LPQitpZgI,1905
14
14
  truss/cli/train_commands.py,sha256=Cfr9-TDE-esQI_R8az5OpLoQyz3Qv38mLsSNwy9znmI,18873
15
- truss/cli/logs/base_watcher.py,sha256=KKyd7lIrdaEeDVt8EtjMioSPGVpLyOcF0ewyzE_GGdQ,2785
16
- truss/cli/logs/model_log_watcher.py,sha256=NACcP-wkcaroYa2Cb9BZC7Yr0554WZa_FSM2LXOf4A8,1263
15
+ truss/cli/logs/base_watcher.py,sha256=vuqteoaMVGX34cgKcETf4X_gOkvnSnDaWz1_pbeFhqs,3343
16
+ truss/cli/logs/model_log_watcher.py,sha256=38vQCcNItfDrTKucvdJ10ZYLOcbGa5ZAKUqUnV4nH34,1971
17
17
  truss/cli/logs/training_log_watcher.py,sha256=r6HRqrLnz-PiKTUXiDYYxg4ZnP8vYcXlEX1YmgHhzlo,1173
18
18
  truss/cli/logs/utils.py,sha256=z-U_FG4BUzdZLbE3BnXb4DZQ0zt3LSZ3PiQpLaDuc3o,1031
19
19
  truss/cli/train/common.py,sha256=xTR41U5FeSndXfNBBHF9wF5XwZH1sOIVFlv-XHjsKIU,1547
@@ -73,7 +73,7 @@ truss/templates/copy_cache_files.Dockerfile.jinja,sha256=Os5zFdYLZ_AfCRGq4RcpVTO
73
73
  truss/templates/docker_server_requirements.txt,sha256=PyhOPKAmKW1N2vLvTfLMwsEtuGpoRrbWuNo7tT6v2Mc,18
74
74
  truss/templates/server.Dockerfile.jinja,sha256=CUYnF_hgxPGq2re7__0UPWlwzOHMoFkxp6NVKi3U16s,7071
75
75
  truss/templates/control/requirements.txt,sha256=nqqNmlTwFeV8sV4fqwItwzzd_egADBP_e-cEopXBJ4k,358
76
- truss/templates/control/control/application.py,sha256=KVnOf_ZUPBifgnyfUhOSW9AkhPuWhECUQybSWthm_iY,5126
76
+ truss/templates/control/control/application.py,sha256=yT1K_xNDAHJwe4Ruk_ej9fiXxv2yKllnPh0xJHkJ16w,5210
77
77
  truss/templates/control/control/endpoints.py,sha256=KzqsLVNJE6r6TCPW8D5FMCtsfHadTwR15A3z_viGxmM,11782
78
78
  truss/templates/control/control/server.py,sha256=R4Y219i1dcz0kkksN8obLoX-YXWGo9iW1igindyG50c,3128
79
79
  truss/templates/control/control/helpers/context_managers.py,sha256=W6dyFgLBhPa5meqrOb3w_phMtKfaJI-GhwUfpiycDc8,413
@@ -166,7 +166,7 @@ truss/tests/remote/baseten/test_remote.py,sha256=y1qSPL1t7dBeYI3xMFn436fttG7wkYd
166
166
  truss/tests/remote/baseten/test_service.py,sha256=ufZbtQlBNIzFCxRt_iE-APLpWbVw_3ViUpSh6H9W5nU,1945
167
167
  truss/tests/templates/control/control/conftest.py,sha256=euDFh0AhcHP-vAmTzi1Qj3lymnplDTgvtbt4Ez_lfpw,654
168
168
  truss/tests/templates/control/control/test_endpoints.py,sha256=HIlRYOicsdHD8r_V5gHpZWybDC26uwXJfbvCohdE3HI,3751
169
- truss/tests/templates/control/control/test_server.py,sha256=I4iIywlpXmlKC0SbQLfx4rX4d_uzUxUZj6h2x_7vytE,9151
169
+ truss/tests/templates/control/control/test_server.py,sha256=0D0OMwZ-9jZRxxHoiQYij0RBMenuA9o29LlwNzd04Vk,9149
170
170
  truss/tests/templates/control/control/test_server_integration.py,sha256=kvhgN1OGF5SZ1JFeg6qwbcrTy-Vr7B2JSP2z507ahxo,11925
171
171
  truss/tests/templates/control/control/helpers/test_context_managers.py,sha256=3LoonRaKu_UvhaWs1eNmEQCZq-iJ3aIjI0Mn4amC8Bw,283
172
172
  truss/tests/templates/control/control/helpers/test_model_container_patch_applier.py,sha256=jhPgExGFF42iuWPM9ry93dnpF765d-CGTCIhbswK0hk,5730
@@ -369,8 +369,8 @@ truss_train/deployment.py,sha256=lWWANSuzBWu2M4oK4qD7n-oVR1JKdmw2Pn5BJQHg-Ck,307
369
369
  truss_train/loader.py,sha256=0o66EjBaHc2YY4syxxHVR4ordJWs13lNXnKjKq2wq0U,1630
370
370
  truss_train/public_api.py,sha256=9N_NstiUlmBuLUwH_fNG_1x7OhGCytZLNvqKXBlStrM,1220
371
371
  truss_train/restore_from_checkpoint.py,sha256=8hdPm-WSgkt74HDPjvCjZMBpvA9MwtoYsxVjOoa7BaM,1176
372
- truss-0.11.9rc6.dist-info/METADATA,sha256=NUD1BVgmVysXZZU0V8ReAEjV7bzyJhgUumLhz4FGWno,6680
373
- truss-0.11.9rc6.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
374
- truss-0.11.9rc6.dist-info/entry_points.txt,sha256=-MwKfHHQHQ6j0HqIgvxrz3CehCmczDLTD-OsRHnjjuU,130
375
- truss-0.11.9rc6.dist-info/licenses/LICENSE,sha256=FTqGzu85i-uw1Gi8E_o0oD60bH9yQ_XIGtZbA1QUYiw,1064
376
- truss-0.11.9rc6.dist-info/RECORD,,
372
+ truss-0.11.10rc1.dist-info/METADATA,sha256=oTLeL5Egb7Lz3YesvtO0HeTOMSi80FZzawxTHX69ud8,6681
373
+ truss-0.11.10rc1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
374
+ truss-0.11.10rc1.dist-info/entry_points.txt,sha256=-MwKfHHQHQ6j0HqIgvxrz3CehCmczDLTD-OsRHnjjuU,130
375
+ truss-0.11.10rc1.dist-info/licenses/LICENSE,sha256=FTqGzu85i-uw1Gi8E_o0oD60bH9yQ_XIGtZbA1QUYiw,1064
376
+ truss-0.11.10rc1.dist-info/RECORD,,