thds.mops 3.8.20250602182922__py3-none-any.whl → 3.8.20250603181158__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 thds.mops might be problematic. Click here for more details.

thds/mops/k8s/config.py CHANGED
@@ -32,6 +32,15 @@ k8s_watch_read_timeout_seconds = config.item(
32
32
  # values are, and it's not 100% clear to me that they have different types of timeouts
33
33
  # from trying to grep their codebase.).
34
34
 
35
+ # whereas the below values are designed to timeout slowly, since many k8s pods don't emit logs
36
+ # on a regular basis.
37
+ k8s_logs_watch_connection_timeout_seconds = config.item(
38
+ "mops.k8s.logs.watch.connection_timeout", int(timedelta(seconds=10).total_seconds()), parse=int
39
+ )
40
+ k8s_logs_watch_read_timeout_seconds = config.item(
41
+ "mops.k8s.logs.watch.read_timeout", int(timedelta(seconds=180).total_seconds()), parse=int
42
+ )
43
+
35
44
  k8s_monitor_delay = config.item("mops.k8s.monitor.delay_seconds", 5, parse=int)
36
45
  k8s_monitor_max_attempts = config.item("mops.k8s.monitor.max_attempts", 100, parse=int)
37
46
 
thds/mops/k8s/logging.py CHANGED
@@ -192,8 +192,10 @@ def _scrape_pod_logs(
192
192
  name=pod_name,
193
193
  namespace=config.k8s_namespace(),
194
194
  _request_timeout=(
195
- config.k8s_watch_connection_timeout_seconds(),
196
- config.k8s_watch_read_timeout_seconds(),
195
+ config.k8s_logs_watch_connection_timeout_seconds(),
196
+ config.k8s_logs_watch_read_timeout_seconds(),
197
+ # we want these numbers fairly high, otherwise a pod that's temporarily silent
198
+ # will cause the stream to end, which is noisy and inefficient.
197
199
  ),
198
200
  # i'm occasionally seeing the `stream()` call below hang
199
201
  # indefinitely if logs don't come back from the pod for a
@@ -3,6 +3,7 @@ data and also functions."""
3
3
 
4
4
  import inspect
5
5
  import io
6
+ import os
6
7
  import pickle
7
8
  import typing as ty
8
9
  from functools import partial
@@ -162,12 +163,35 @@ class SourceArgumentPickler:
162
163
  return None
163
164
 
164
165
 
166
+ class DuplicateSourceBasenameError(ValueError):
167
+ pass
168
+
169
+
165
170
  class SourceResultPickler:
166
171
  """Only for use on the remote side, when serializing the result."""
167
172
 
173
+ def __init__(self) -> None:
174
+ """There will be one of these per remote function call."""
175
+ self._basenames_seen: set[str] = set()
176
+
168
177
  def __call__(self, maybe_source: ty.Any) -> ty.Optional[_DeserSource]:
169
178
  if isinstance(maybe_source, source.Source):
170
- return ty.cast(_DeserSource, UnpickleSourceResult(*prepare_source_result(maybe_source)))
179
+ src_res = prepare_source_result(maybe_source)
180
+ if src_res.file_uri:
181
+ # we need to check to make sure that this file_uri is not a duplicate
182
+ # - if it is, this indicates that this single function is attempting to return
183
+ # two Source objects that have not yet been uploaded but will be uploaded to the same name.
184
+ file_basename = os.path.basename(src_res.file_uri)
185
+ if file_basename in self._basenames_seen:
186
+ raise DuplicateSourceBasenameError(
187
+ f"Duplicate basename {os.path.basename(src_res.file_uri)} found in SourceResultPickler."
188
+ " This is usually an indication that you have two files with the same name in two different directories,"
189
+ " and are trying to convert them into Source objects with automatically-assigned URIs."
190
+ " Per the documentation, all output Source objects without explicitly assigned remote URIs must be provided"
191
+ " with unique basenames, in order to allow retention of the basename for usability and debugging."
192
+ )
193
+ self._basenames_seen.add(file_basename)
194
+ return ty.cast(_DeserSource, UnpickleSourceResult(*src_res))
171
195
 
172
196
  return None
173
197
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: thds.mops
3
- Version: 3.8.20250602182922
3
+ Version: 3.8.20250603181158
4
4
  Summary: ML Ops tools for Trilliant Health
5
5
  Author-email: Trilliant Health <info@trillianthealth.com>
6
6
  Project-URL: Repository, https://github.com/TrilliantHealth/ds-monorepo
@@ -20,11 +20,11 @@ thds/mops/k8s/__init__.py,sha256=y4bvR5DQLiriBV0I8CZoQdNlNrXWQ2VpcxY5lOrdnzU,669
20
20
  thds/mops/k8s/_shared.py,sha256=MR-s6ijWUHZGjxK_fsOpHuRDB6kuofjo5xiIb7ul2VM,86
21
21
  thds/mops/k8s/apply_yaml.py,sha256=hVW6dIVbNdzHdbGlc2VAPGkdByv_rH2oPybyIm7tKIM,820
22
22
  thds/mops/k8s/auth.py,sha256=mXFPZvyJYEPASsBatv1r8syB9AoayuHGptHHnNUg8LE,1517
23
- thds/mops/k8s/config.py,sha256=FyzuiUaNq8mQR01GqrezQWSc21QVqjLY9iaJUGu5WAo,2568
23
+ thds/mops/k8s/config.py,sha256=ha8ppDeFnDB2I9tCajiDcfZlamIk73OJe4lzD5buyXU,2993
24
24
  thds/mops/k8s/container_registry.py,sha256=qOiGCE4t_tLYgJDGrhKV9KNv48lF_AlwCDHyFgucd2s,539
25
25
  thds/mops/k8s/jobs.py,sha256=3u0jc5Fnll2ncnmcdTUHlcxJ_KYNK9s66W7r6ez49As,3271
26
26
  thds/mops/k8s/launch.py,sha256=SIeao2oJVKEvef8vmWDoE8QAPIMBV2TmRxHYBRXaJFM,10479
27
- thds/mops/k8s/logging.py,sha256=yJ5Gt_luyo6LXbUJSXbhA4f1z7il1WuHQjMcP8eB00U,9591
27
+ thds/mops/k8s/logging.py,sha256=QstE_d8a8yytTdj9S43cRetCzKTAJSc1ap0In9rkpdA,9768
28
28
  thds/mops/k8s/namespace.py,sha256=Z6trVTU9WFashto4PqIhTcxu-foOF93W0TpgqCU7WIA,383
29
29
  thds/mops/k8s/node_selection.py,sha256=Gy2Jz8IxZblg2LmtGg8-MtKI4RmXz2AMXqFPP8OQyu0,2065
30
30
  thds/mops/k8s/retry.py,sha256=JVfP304kItpLs5nrONHE5UWkVWlrFGlV_oFQqhq3zHg,2846
@@ -82,7 +82,7 @@ thds/mops/pure/joblib/__init__.py,sha256=-3hSs-GsNzE_eNnwrdZBHAR_eaub5Uyl5GPYqBw
82
82
  thds/mops/pure/joblib/backend.py,sha256=F__6lrdc1-VcX4n4Pw7Lz1bBgeefShtRy2DQh6Fp-eI,2671
83
83
  thds/mops/pure/joblib/batching.py,sha256=tPOATD28-YW7KcWa3IqKm-fhLaILzM792ApvU-_zfnM,2298
84
84
  thds/mops/pure/pickling/__init__.py,sha256=WNdG8PdJCk-kYaXkvvPa--hjYGoUlBXG3w2X86yuhGo,156
85
- thds/mops/pure/pickling/_pickle.py,sha256=vn8f6uEsaAdLyxGNYb4ED6D1a6BXsZQxnV3c0Ya6WUk,7605
85
+ thds/mops/pure/pickling/_pickle.py,sha256=Q4dd683OPsdb_4oQRDWJ9F8mN_jKIXxgySCikAABVTE,9043
86
86
  thds/mops/pure/pickling/memoize_only.py,sha256=oI5CMy6IEJc46Gb_BGWNUuAe3fysS7HxRSTajN0WssI,837
87
87
  thds/mops/pure/pickling/mprunner.py,sha256=dVbwQA8hzEL7UiwYXmzoGwN3_jbEtGoHDPMkRmo_UtA,8378
88
88
  thds/mops/pure/pickling/pickles.py,sha256=nCg7L7CqReNWDF8FAdEmCcuXVC_kLT5zuyW3V8Vvvs4,4704
@@ -105,8 +105,8 @@ thds/mops/pure/tools/summarize/cli.py,sha256=7kDtn24ok8oBO3jFjlMmOK3jnZYpMoE_5Y8
105
105
  thds/mops/pure/tools/summarize/run_summary.py,sha256=LUtvbankAYbss2NCF_XbNl05jkNgxYz_SLyERJlp4sk,5773
106
106
  thds/mops/testing/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
107
107
  thds/mops/testing/deferred_imports.py,sha256=f0ezCgQAtzTqW1yAOb0OWgsB9ZrlztLB894LtpWDaVw,3780
108
- thds_mops-3.8.20250602182922.dist-info/METADATA,sha256=sigW-qM8htEhi0hjYjve882Zv2GpAaxWdmnOsUc4J8o,2222
109
- thds_mops-3.8.20250602182922.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
110
- thds_mops-3.8.20250602182922.dist-info/entry_points.txt,sha256=GShNqjcjbq0TAJuwpyeCI5XCltiwdZxnNHkBpmYbNkU,329
111
- thds_mops-3.8.20250602182922.dist-info/top_level.txt,sha256=LTZaE5SkWJwv9bwOlMbIhiS-JWQEEIcjVYnJrt-CriY,5
112
- thds_mops-3.8.20250602182922.dist-info/RECORD,,
108
+ thds_mops-3.8.20250603181158.dist-info/METADATA,sha256=G5rLrVJiIDTZLXtQwQlyeyiqIW2F6Yr5qBt9kYaKeWE,2222
109
+ thds_mops-3.8.20250603181158.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
110
+ thds_mops-3.8.20250603181158.dist-info/entry_points.txt,sha256=GShNqjcjbq0TAJuwpyeCI5XCltiwdZxnNHkBpmYbNkU,329
111
+ thds_mops-3.8.20250603181158.dist-info/top_level.txt,sha256=LTZaE5SkWJwv9bwOlMbIhiS-JWQEEIcjVYnJrt-CriY,5
112
+ thds_mops-3.8.20250603181158.dist-info/RECORD,,