thds.mops 3.9.20251029034848__py3-none-any.whl → 3.10.20251106191559__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.
- thds/mops/pure/_magic/api.py +33 -3
- thds/mops/pure/_magic/sauce.py +49 -8
- {thds_mops-3.9.20251029034848.dist-info → thds_mops-3.10.20251106191559.dist-info}/METADATA +1 -1
- {thds_mops-3.9.20251029034848.dist-info → thds_mops-3.10.20251106191559.dist-info}/RECORD +7 -7
- {thds_mops-3.9.20251029034848.dist-info → thds_mops-3.10.20251106191559.dist-info}/WHEEL +0 -0
- {thds_mops-3.9.20251029034848.dist-info → thds_mops-3.10.20251106191559.dist-info}/entry_points.txt +0 -0
- {thds_mops-3.9.20251029034848.dist-info → thds_mops-3.10.20251106191559.dist-info}/top_level.txt +0 -0
thds/mops/pure/_magic/api.py
CHANGED
|
@@ -51,9 +51,14 @@ class _MagicApi:
|
|
|
51
51
|
calls: ty.Collection[ty.Callable] = tuple(),
|
|
52
52
|
) -> ty.Callable[[ty.Callable[P, R]], sauce.Magic[P, R]]:
|
|
53
53
|
"""This is the main pure.magic() decorator. It is designed to be applied directly
|
|
54
|
-
at the site of function definition, i.e. on the `def`. We dynamically capture
|
|
55
|
-
|
|
56
|
-
|
|
54
|
+
at the site of function definition, i.e. on the `def`. We dynamically capture the
|
|
55
|
+
fully qualified name of the function being decorated and use that to look up the
|
|
56
|
+
appropriate 'magic' configuration at the time of each call to the function. Any
|
|
57
|
+
configuration passed here will be entered into the global magic config registry as
|
|
58
|
+
the 'base case' for this function.
|
|
59
|
+
|
|
60
|
+
DO NOT use this decorator multiple times on the same function, as this will overwrite
|
|
61
|
+
config globally in a way that is very hard to understand.
|
|
57
62
|
"""
|
|
58
63
|
return sauce.make_magic(_get_config(), shim_or_builder, blob_root, pipeline_id, calls)
|
|
59
64
|
|
|
@@ -75,6 +80,11 @@ class _MagicApi:
|
|
|
75
80
|
|
|
76
81
|
We attempt to detect this and raise an error if it happens. If it does, you should
|
|
77
82
|
provide an explicit unique config_path for each usage.
|
|
83
|
+
|
|
84
|
+
NOTE: In many cases, you may be better off using pure.magic.wand instead, which
|
|
85
|
+
will allow you to prevent any 'outside' configuration from unintentionally
|
|
86
|
+
affecting your function, because the explicitly-provided configuration is used but
|
|
87
|
+
not entered into the global 'magic' config registry.
|
|
78
88
|
"""
|
|
79
89
|
return ty.cast(
|
|
80
90
|
ty.Callable[[F], F],
|
|
@@ -88,6 +98,26 @@ class _MagicApi:
|
|
|
88
98
|
),
|
|
89
99
|
)
|
|
90
100
|
|
|
101
|
+
@staticmethod
|
|
102
|
+
def wand(
|
|
103
|
+
shim_or_builder: ty.Union[ShimName, ShimOrBuilder, None] = None,
|
|
104
|
+
*,
|
|
105
|
+
blob_root: uris.UriResolvable = "",
|
|
106
|
+
pipeline_id: str = "",
|
|
107
|
+
calls: ty.Collection[ty.Callable] = tuple(),
|
|
108
|
+
) -> ty.Callable[[F], F]:
|
|
109
|
+
"""Meant for truly dynamic (i.e. runtime-controlled) use cases. This picks up
|
|
110
|
+
_current_ magic configuration at the time of wrapping the function, but does not allow
|
|
111
|
+
further magic configuration at the time of function call, and does not enter any
|
|
112
|
+
of the supplied configuration into the global 'magic' config registry.
|
|
113
|
+
|
|
114
|
+
Suitable for cases where you want to fall back to existing module and config-file
|
|
115
|
+
configuration at the time of wrapping the function for anything that you don't supply explicitly.
|
|
116
|
+
"""
|
|
117
|
+
return sauce.wand(
|
|
118
|
+
_get_config(), shim_or_builder, blob_root=blob_root, pipeline_id=pipeline_id, calls=calls
|
|
119
|
+
)
|
|
120
|
+
|
|
91
121
|
@staticmethod
|
|
92
122
|
def blob_root(
|
|
93
123
|
blob_root_uri: uris.UriResolvable, pathable: config_tree.Pathable = None, *, mask: bool = False
|
thds/mops/pure/_magic/sauce.py
CHANGED
|
@@ -9,7 +9,7 @@ from typing_extensions import ParamSpec
|
|
|
9
9
|
from thds.core import futures, log, stack_context
|
|
10
10
|
from thds.mops._utils import config_tree
|
|
11
11
|
|
|
12
|
-
from ..
|
|
12
|
+
from .. import core
|
|
13
13
|
from ..core.memo.unique_name_for_function import full_name_and_callable
|
|
14
14
|
from ..core.use_runner import use_runner
|
|
15
15
|
from ..pickling.mprunner import MemoizingPicklingRunner
|
|
@@ -18,7 +18,7 @@ from ..runner.simple_shims import samethread_shim
|
|
|
18
18
|
from ..runner.types import Shim, ShimBuilder
|
|
19
19
|
from .shims import ShimName, ShimOrBuilder, to_shim_builder
|
|
20
20
|
|
|
21
|
-
_local_root = lambda: f"file://{file_blob_store.MOPS_ROOT()}" # noqa: E731
|
|
21
|
+
_local_root = lambda: f"file://{core.file_blob_store.MOPS_ROOT()}" # noqa: E731
|
|
22
22
|
P = ParamSpec("P")
|
|
23
23
|
R = ty.TypeVar("R")
|
|
24
24
|
|
|
@@ -31,7 +31,7 @@ class _MagicConfig:
|
|
|
31
31
|
"mops.pure.magic.shim", parse=to_shim_builder # type: ignore
|
|
32
32
|
)
|
|
33
33
|
self.blob_root = config_tree.ConfigTree[ty.Callable[[], str]](
|
|
34
|
-
"mops.pure.magic.blob_root", parse=uris.to_lazy_uri
|
|
34
|
+
"mops.pure.magic.blob_root", parse=core.uris.to_lazy_uri
|
|
35
35
|
)
|
|
36
36
|
self.pipeline_id = config_tree.ConfigTree[str]("mops.pure.magic.pipeline_id")
|
|
37
37
|
self.blob_root[""] = _local_root # default Blob Store
|
|
@@ -78,7 +78,7 @@ class Magic(ty.Generic[P, R]):
|
|
|
78
78
|
|
|
79
79
|
self.config = config
|
|
80
80
|
|
|
81
|
-
if p_id := pipeline_id_mask.extract_from_docstr(func, require=False):
|
|
81
|
+
if p_id := core.pipeline_id_mask.extract_from_docstr(func, require=False):
|
|
82
82
|
# this allows the docstring pipeline id to become 'the most specific' config.
|
|
83
83
|
self.config.pipeline_id.setv(p_id, self._magic_config_path)
|
|
84
84
|
self._shim = stack_context.StackContext[ty.Union[None, ShimName, ShimOrBuilder]](
|
|
@@ -132,12 +132,12 @@ class Magic(ty.Generic[P, R]):
|
|
|
132
132
|
function call, but returns a PFuture once either a result has been found or a a
|
|
133
133
|
new invocation has been started.
|
|
134
134
|
"""
|
|
135
|
-
with pipeline_id.set_pipeline_id_for_stack(self._pipeline_id):
|
|
135
|
+
with core.pipeline_id.set_pipeline_id_for_stack(self._pipeline_id):
|
|
136
136
|
return self.runner.submit(self.__wrapped__, *args, **kwargs)
|
|
137
137
|
|
|
138
138
|
def __call__(self, *args: P.args, **kwargs: P.kwargs) -> R:
|
|
139
139
|
"""This is the wrapped function - call this as though it were the function itself."""
|
|
140
|
-
with pipeline_id.set_pipeline_id_for_stack(self._pipeline_id):
|
|
140
|
+
with core.pipeline_id.set_pipeline_id_for_stack(self._pipeline_id):
|
|
141
141
|
return self._func(*args, **kwargs)
|
|
142
142
|
|
|
143
143
|
def __repr__(self) -> str:
|
|
@@ -158,7 +158,7 @@ class MagicReregistrationError(ValueError):
|
|
|
158
158
|
def make_magic(
|
|
159
159
|
config: _MagicConfig,
|
|
160
160
|
shim_or_builder: ty.Union[ShimName, ShimOrBuilder, None],
|
|
161
|
-
blob_root: uris.UriResolvable,
|
|
161
|
+
blob_root: core.uris.UriResolvable,
|
|
162
162
|
pipeline_id: str,
|
|
163
163
|
calls: ty.Collection[ty.Callable],
|
|
164
164
|
*,
|
|
@@ -210,7 +210,7 @@ def make_magic(
|
|
|
210
210
|
if shim_or_builder is not None:
|
|
211
211
|
config.shim_bld[magic_config_path] = to_shim_builder(shim_or_builder)
|
|
212
212
|
if blob_root: # could be empty string
|
|
213
|
-
config.blob_root[magic_config_path] = uris.to_lazy_uri(blob_root)
|
|
213
|
+
config.blob_root[magic_config_path] = core.uris.to_lazy_uri(blob_root)
|
|
214
214
|
if pipeline_id: # could be empty string
|
|
215
215
|
config.pipeline_id[magic_config_path] = pipeline_id
|
|
216
216
|
|
|
@@ -219,3 +219,44 @@ def make_magic(
|
|
|
219
219
|
return Magic(func, config, magic_config_path, calls)
|
|
220
220
|
|
|
221
221
|
return deco
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
F = ty.TypeVar("F", bound=ty.Callable)
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
def wand(
|
|
228
|
+
config: _MagicConfig,
|
|
229
|
+
shim_or_builder: ty.Union[ShimName, ShimOrBuilder, None] = None,
|
|
230
|
+
# None means 'pull from config' - 'off' means off.
|
|
231
|
+
*,
|
|
232
|
+
blob_root: core.uris.UriResolvable = "",
|
|
233
|
+
pipeline_id: str = "",
|
|
234
|
+
calls: ty.Collection[ty.Callable] = tuple(),
|
|
235
|
+
) -> ty.Callable[[F], F]:
|
|
236
|
+
"""A higher-order function factory that prefers your arguments but falls back to magic
|
|
237
|
+
config at the time of wrapping the function.
|
|
238
|
+
|
|
239
|
+
You are creating a magic wand, not doing magic. In fact, the wand doesn't actually use
|
|
240
|
+
Magic at all - it resolves things from config as soon as the function is _wrapped_,
|
|
241
|
+
not at the time of function call.
|
|
242
|
+
"""
|
|
243
|
+
|
|
244
|
+
def deco_that_resolves_and_locks_in_config(func: F) -> F:
|
|
245
|
+
magic_config_path = make_magic_config_path(func)
|
|
246
|
+
shim_builder = (
|
|
247
|
+
to_shim_builder(shim_or_builder)
|
|
248
|
+
if shim_or_builder
|
|
249
|
+
else config.shim_bld.getv(magic_config_path)
|
|
250
|
+
)
|
|
251
|
+
if not shim_builder: # this means 'off'
|
|
252
|
+
return func # just run the function normally
|
|
253
|
+
|
|
254
|
+
blob_root_uri = (
|
|
255
|
+
core.uris.to_lazy_uri(blob_root) if blob_root else config.blob_root.getv(magic_config_path)()
|
|
256
|
+
)
|
|
257
|
+
|
|
258
|
+
return core.pipeline_id.set_pipeline_id_for_stack(
|
|
259
|
+
pipeline_id or config.pipeline_id.getv(magic_config_path)
|
|
260
|
+
)(use_runner(MemoizingPicklingRunner(shim_builder, blob_root_uri).calls(func, *calls))(func))
|
|
261
|
+
|
|
262
|
+
return deco_that_resolves_and_locks_in_config
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: thds.mops
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.10.20251106191559
|
|
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
|
|
@@ -39,8 +39,8 @@ thds/mops/k8s/tools/krsync.py,sha256=us7pXX0-bRMwD2oAno7Z6BJcPs6FgaUabHW0STyQJYg
|
|
|
39
39
|
thds/mops/k8s/tools/krsync.sh,sha256=fWgwkdzWnJeTbzEA_uBiIIi-bNU4nXAYj3dNovyRluU,747
|
|
40
40
|
thds/mops/pure/__init__.py,sha256=3xLimQ2JWdeq1YgPs7bPwlwOspzPRwaR2w2KX7vfJU0,1624
|
|
41
41
|
thds/mops/pure/_magic/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
42
|
-
thds/mops/pure/_magic/api.py,sha256=
|
|
43
|
-
thds/mops/pure/_magic/sauce.py,sha256=
|
|
42
|
+
thds/mops/pure/_magic/api.py,sha256=f2lF7_0XzRleYWksD3uxxl_dssl0wW_CLGHIY1WZLUM,8019
|
|
43
|
+
thds/mops/pure/_magic/sauce.py,sha256=lMZ4StInNH7vn1t96Ajo4KKCE99ebw0orGRatMqWrKM,11331
|
|
44
44
|
thds/mops/pure/_magic/shims.py,sha256=CXN8wlHv039oKRzDtp5YFDlwGXmmaheWLCi2I95gSeM,1212
|
|
45
45
|
thds/mops/pure/adls/__init__.py,sha256=fw67xxwnizBurScMa-_zWb94lo5gamEVRt27V4bR0jc,54
|
|
46
46
|
thds/mops/pure/adls/_files.py,sha256=9m35Y4elWF0DjgAXVp4oi5CaY6fXWt8n67PilWxWJns,821
|
|
@@ -109,8 +109,8 @@ thds/mops/pure/tools/summarize/cli.py,sha256=7kDtn24ok8oBO3jFjlMmOK3jnZYpMoE_5Y8
|
|
|
109
109
|
thds/mops/pure/tools/summarize/run_summary.py,sha256=glEN_YxUGADzp2Ofvr4ZDeHvnZ1znNR7HD7EATn1sPI,5644
|
|
110
110
|
thds/mops/testing/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
111
111
|
thds/mops/testing/deferred_imports.py,sha256=f0ezCgQAtzTqW1yAOb0OWgsB9ZrlztLB894LtpWDaVw,3780
|
|
112
|
-
thds_mops-3.
|
|
113
|
-
thds_mops-3.
|
|
114
|
-
thds_mops-3.
|
|
115
|
-
thds_mops-3.
|
|
116
|
-
thds_mops-3.
|
|
112
|
+
thds_mops-3.10.20251106191559.dist-info/METADATA,sha256=BX_qLAaa6x7Oa20s9H3iEzraK5YKy111k_kcBuiAF6g,2226
|
|
113
|
+
thds_mops-3.10.20251106191559.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
114
|
+
thds_mops-3.10.20251106191559.dist-info/entry_points.txt,sha256=qKvCAaB80syXfxVR3xx6x9J0YJdaQWkIbVSw-NwFgMw,322
|
|
115
|
+
thds_mops-3.10.20251106191559.dist-info/top_level.txt,sha256=LTZaE5SkWJwv9bwOlMbIhiS-JWQEEIcjVYnJrt-CriY,5
|
|
116
|
+
thds_mops-3.10.20251106191559.dist-info/RECORD,,
|
|
File without changes
|
{thds_mops-3.9.20251029034848.dist-info → thds_mops-3.10.20251106191559.dist-info}/entry_points.txt
RENAMED
|
File without changes
|
{thds_mops-3.9.20251029034848.dist-info → thds_mops-3.10.20251106191559.dist-info}/top_level.txt
RENAMED
|
File without changes
|