splime 0.1.2__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.
Files changed (74) hide show
  1. spl/__init__.py +14 -0
  2. spl/client.py +1364 -0
  3. spl/core/__init__.py +23 -0
  4. spl/core/common.py +350 -0
  5. spl/core/entities/__init__.py +0 -0
  6. spl/core/entities/adapter.py +210 -0
  7. spl/core/entities/artifact.py +141 -0
  8. spl/core/entities/control.py +45 -0
  9. spl/core/entities/distribution.py +65 -0
  10. spl/core/entities/function.py +254 -0
  11. spl/core/entities/local_function.py +286 -0
  12. spl/core/entities/misc.py +14 -0
  13. spl/core/entities/module.py +88 -0
  14. spl/core/entities/node.py +286 -0
  15. spl/core/entities/node_function.py +79 -0
  16. spl/core/entities/node_remote.py +295 -0
  17. spl/core/entities/pipeline.py +436 -0
  18. spl/core/entities/scalar.py +55 -0
  19. spl/core/ir/__init__.py +0 -0
  20. spl/core/ir/common.py +34 -0
  21. spl/core/ir/parse.py +79 -0
  22. spl/core/ir/unparse.py +29 -0
  23. spl/core/ir/utils.py +163 -0
  24. spl/daemon/__init__.py +23 -0
  25. spl/daemon/__main__.py +11 -0
  26. spl/daemon/cli.py +582 -0
  27. spl/daemon/client.py +43 -0
  28. spl/daemon/docker_environment.py +329 -0
  29. spl/daemon/docker_pool.py +516 -0
  30. spl/daemon/environment.py +228 -0
  31. spl/daemon/environment_base.py +479 -0
  32. spl/daemon/heartbeat_service.py +119 -0
  33. spl/daemon/metadata.py +427 -0
  34. spl/daemon/remote_client.py +457 -0
  35. spl/daemon/repositories/__init__.py +17 -0
  36. spl/daemon/repositories/env.py +323 -0
  37. spl/daemon/repositories/library.py +181 -0
  38. spl/daemon/repositories/object.py +997 -0
  39. spl/daemon/repositories/run.py +279 -0
  40. spl/daemon/repositories/server_connection.py +657 -0
  41. spl/daemon/repositories/sync_event.py +129 -0
  42. spl/daemon/routes/__init__.py +1 -0
  43. spl/daemon/routes/_helpers.py +147 -0
  44. spl/daemon/routes/artifacts.py +77 -0
  45. spl/daemon/routes/diagnostics.py +114 -0
  46. spl/daemon/routes/envs.py +82 -0
  47. spl/daemon/routes/libraries.py +129 -0
  48. spl/daemon/routes/objects.py +174 -0
  49. spl/daemon/routes/remote.py +56 -0
  50. spl/daemon/routes/runs.py +96 -0
  51. spl/daemon/routes/server_connections.py +86 -0
  52. spl/daemon/runtime_backend.py +368 -0
  53. spl/daemon/runtime_config.py +133 -0
  54. spl/daemon/runtime_dependencies.py +459 -0
  55. spl/daemon/secret_store.py +187 -0
  56. spl/daemon/server.py +2224 -0
  57. spl/daemon/server_connection.py +267 -0
  58. spl/daemon/services/__init__.py +1 -0
  59. spl/daemon/services/sync.py +76 -0
  60. spl/daemon/signature.py +376 -0
  61. spl/daemon/storage_base.py +542 -0
  62. spl/daemon/store.py +436 -0
  63. spl/daemon/worker.py +526 -0
  64. spl/daemon_client.py +945 -0
  65. spl/pipeline_widget.py +1452 -0
  66. spl/py.typed +0 -0
  67. spl/server_client.py +787 -0
  68. splime-0.1.2.dist-info/METADATA +189 -0
  69. splime-0.1.2.dist-info/RECORD +74 -0
  70. splime-0.1.2.dist-info/WHEEL +5 -0
  71. splime-0.1.2.dist-info/entry_points.txt +2 -0
  72. splime-0.1.2.dist-info/licenses/LICENSE +201 -0
  73. splime-0.1.2.dist-info/licenses/NOTICE +8 -0
  74. splime-0.1.2.dist-info/top_level.txt +1 -0
spl/core/ir/utils.py ADDED
@@ -0,0 +1,163 @@
1
+ import sys
2
+ from itertools import chain, repeat
3
+ from operator import itemgetter
4
+ from pathlib import Path
5
+ from typing import Any
6
+
7
+ import yaml
8
+
9
+ from spl.core.entities.adapter import DAdapter
10
+ from spl.core.entities.artifact import DArtifactRef
11
+ from spl.core.entities.control import DSPLImport, DSPLSelfImport
12
+ from spl.core.entities.distribution import DDistribution, validate_distributions
13
+ from spl.core.entities.function import DFunction
14
+ from spl.core.entities.local_function import DLocalAlias
15
+ from spl.core.entities.module import DImport, DImportFrom
16
+ from spl.core.entities.node import (
17
+ DFormattedOutputRef,
18
+ DNodeInputRef,
19
+ DNodeOutputRef,
20
+ InputPort,
21
+ OutputPort,
22
+ )
23
+ from spl.core.entities.node_function import DNodeFunction
24
+ from spl.core.entities.node_remote import DNodeRemote
25
+ from spl.core.entities.pipeline import DPipeline
26
+ from spl.core.entities.scalar import DScalar
27
+ from spl.core.ir.parse import get_top_level_deps
28
+ from spl.core.ir.unparse import mk_top_level_ast
29
+
30
+
31
+ class SPLSafeLoader(yaml.SafeLoader):
32
+ pass
33
+
34
+
35
+ def _construct_dataclass(cls):
36
+ def _construct(loader, node):
37
+ return cls(**loader.construct_mapping(node, deep = True))
38
+ return _construct
39
+
40
+
41
+ def _construct_dfunction(loader, node):
42
+ data = loader.construct_mapping(node, deep = True)
43
+ return DFunction(
44
+ name = data['name'],
45
+ body = data['body'],
46
+ inputs = [
47
+ InputPort(
48
+ name = x['name'],
49
+ typ_ = x['type'],
50
+ default = x.get('default'))
51
+ for x in data['inputs']],
52
+ outputs = None if data['outputs'] is None else [
53
+ OutputPort(
54
+ name = x['name'],
55
+ typ_ = x['type'])
56
+ for x in data['outputs']])
57
+
58
+
59
+ SPL_YAML_CONSTRUCTORS = {
60
+ '!DSPLSelfImport': _construct_dataclass(DSPLSelfImport),
61
+ '!DSPLImport': _construct_dataclass(DSPLImport),
62
+ '!DDistribution': _construct_dataclass(DDistribution),
63
+ '!DFunction': _construct_dfunction,
64
+ '!DLocalAlias': _construct_dataclass(DLocalAlias),
65
+ '!DImport': _construct_dataclass(DImport),
66
+ '!DImportFrom': _construct_dataclass(DImportFrom),
67
+ '!DFormattedOutputRef': _construct_dataclass(DFormattedOutputRef),
68
+ '!DNodeInputRef': _construct_dataclass(DNodeInputRef),
69
+ '!DNodeOutputRef': _construct_dataclass(DNodeOutputRef),
70
+ '!DNodeFunction': _construct_dataclass(DNodeFunction),
71
+ '!DNodeRemote': _construct_dataclass(DNodeRemote),
72
+ '!DPipeline': _construct_dataclass(DPipeline),
73
+ '!DScalar': _construct_dataclass(DScalar),
74
+ '!DArtifactRef': _construct_dataclass(DArtifactRef),
75
+ '!DAdapter': _construct_dataclass(DAdapter),
76
+ }
77
+
78
+
79
+ for _tag, _constructor in SPL_YAML_CONSTRUCTORS.items():
80
+ SPLSafeLoader.add_constructor(_tag, _constructor)
81
+
82
+
83
+ def spl_export_to_file(fname: Path, xs: list[Any]):
84
+ top_level_deps = get_top_level_deps(2, xs)
85
+
86
+ mapping = {
87
+ root: DSPLSelfImport(name = root.name)
88
+ for (root, _) in top_level_deps
89
+ if hasattr(root, 'name')}
90
+
91
+ top_level_deps = {
92
+ root: [mapping.get(x, x) for x in dependencies]
93
+ for root, dependencies in top_level_deps}
94
+
95
+ fname.write_text(yaml.dump_all(
96
+ [[root, *dependencies] for root, dependencies in top_level_deps.items()],
97
+ sort_keys = False,
98
+ allow_unicode = True))
99
+
100
+
101
+ def spl_export_to_dir(dname: Path, xs: list[Any]):
102
+ top_level_deps = get_top_level_deps(2, xs)
103
+ mapping = {
104
+ root: DSPLImport(
105
+ path = './{}.yaml'.format(root.name),
106
+ name = root.name)
107
+ for (root, _) in top_level_deps}
108
+
109
+ top_level_deps = {
110
+ root: [mapping.get(x, x) for x in dependencies]
111
+ for root, dependencies in top_level_deps}
112
+
113
+ for root, dependencies in top_level_deps.items():
114
+ fname = dname / '{}.yaml'.format(root.name)
115
+ fname.write_text(yaml.dump(
116
+ [root, *dependencies],
117
+ sort_keys = False,
118
+ allow_unicode = True))
119
+
120
+
121
+ def mk_top_level_deps_closure(fnames):
122
+ top_level_deps = []
123
+ imports = set(map(Path.absolute, fnames))
124
+ queue = list(imports)
125
+
126
+ while len(queue) > 0:
127
+ fname, *queue = queue
128
+
129
+ top_level_deps_new = [
130
+ (root, dependencies)
131
+ for (root, *dependencies) in yaml.load_all(fname.read_text(), SPLSafeLoader)]
132
+
133
+ top_level_deps = [
134
+ *top_level_deps,
135
+ *zip(repeat(fname), top_level_deps_new, strict = False)]
136
+
137
+ # TODO: filter by x.name
138
+ new_imports = sorted(set([
139
+ (fname.parent / x.path).absolute()
140
+ for x in chain.from_iterable([dependencies for (_, dependencies) in top_level_deps_new])
141
+ if isinstance(x, DSPLImport)]) - imports)
142
+
143
+ imports = set([*imports, *new_imports])
144
+ queue = [*queue, *new_imports]
145
+
146
+ return top_level_deps
147
+
148
+
149
+ def spl_import_from_file(fname: Path, globals: dict[str, Any] | None = None):
150
+ if globals is None:
151
+ globals = sys._getframe(1).f_globals
152
+
153
+ top_level_deps = mk_top_level_deps_closure([fname])
154
+
155
+ validate_distributions(
156
+ list(map(itemgetter(1), top_level_deps)),
157
+ str(fname.absolute()))
158
+
159
+ for fname, (root, dependencies) in top_level_deps[::-1]:
160
+ expr = mk_top_level_ast((root, dependencies), fname)
161
+ eval( # noqa: S307
162
+ compile(expr, str(fname), mode = 'exec'),
163
+ globals = globals)
spl/daemon/__init__.py ADDED
@@ -0,0 +1,23 @@
1
+ """Minimal local daemon runtime for SPL objects.
2
+
3
+ This package is intentionally kept outside ``spl.core``. The current core
4
+ already knows how to describe functions and pipelines as SPL/YAML; the daemon
5
+ adds only the missing local runtime pieces:
6
+
7
+ * a SQLite registry for environments, serialized objects, versions, and runs;
8
+ * a local HTTP API available from other Python environments;
9
+ * a worker subprocess that executes the object with its registered Python.
10
+
11
+ The public entry point is the module CLI:
12
+
13
+ python -m spl.daemon serve
14
+
15
+ The package does not import ``spl.core`` here on purpose. The daemon process
16
+ can start and manage its registry even if a particular target environment is
17
+ missing the dependencies required by an object; those errors belong to the
18
+ worker process and are reported per run.
19
+ """
20
+
21
+ from spl.daemon.client import Client
22
+
23
+ __all__ = ["Client"]
spl/daemon/__main__.py ADDED
@@ -0,0 +1,11 @@
1
+ """Command line entry point for ``python -m spl.daemon``.
2
+
3
+ Keeping this file tiny makes the module invocation predictable: all argument
4
+ parsing lives in ``cli.py`` and this file simply delegates to it.
5
+ """
6
+
7
+ from spl.daemon.cli import main
8
+
9
+
10
+ if __name__ == "__main__":
11
+ raise SystemExit(main())