simrun 0.1.0__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.
- simrun/__init__.py +3 -0
- simrun/argo.py +449 -0
- simrun/build_constraints.txt +20 -0
- simrun/cgroup.py +77 -0
- simrun/cli.py +350 -0
- simrun/client.py +407 -0
- simrun/config.py +63 -0
- simrun/cwl.py +287 -0
- simrun/demo.py +106 -0
- simrun/edit.py +408 -0
- simrun/environment.py +370 -0
- simrun/ledger.py +286 -0
- simrun/mcp.py +161 -0
- simrun/planner.py +303 -0
- simrun/plugins.py +149 -0
- simrun/plugins_builtin.py +33 -0
- simrun/podspec.py +166 -0
- simrun/resources.py +270 -0
- simrun/service/__init__.py +1 -0
- simrun/service/app.py +1721 -0
- simrun/service/argo_backend.py +842 -0
- simrun/service/auth.py +93 -0
- simrun/service/backend.py +170 -0
- simrun/service/compare.py +77 -0
- simrun/service/controller.py +788 -0
- simrun/service/edits.py +406 -0
- simrun/service/index.py +292 -0
- simrun/service/logs.py +91 -0
- simrun/service/submission.py +349 -0
- simrun/snapshot.py +196 -0
- simrun/store.py +190 -0
- simrun/testing.py +263 -0
- simrun/worker.py +1097 -0
- simrun/workflow.py +188 -0
- simrun-0.1.0.dist-info/METADATA +107 -0
- simrun-0.1.0.dist-info/RECORD +39 -0
- simrun-0.1.0.dist-info/WHEEL +4 -0
- simrun-0.1.0.dist-info/entry_points.txt +10 -0
- simrun-0.1.0.dist-info/licenses/LICENSE +7 -0
simrun/workflow.py
ADDED
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
"""The workflow model: tasks, the references between them and their order."""
|
|
2
|
+
|
|
3
|
+
from enum import StrEnum
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
from typing import Any, Self
|
|
6
|
+
|
|
7
|
+
import yaml
|
|
8
|
+
from pydantic import BaseModel, Field, ValidationError, model_validator
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class SplitMode(StrEnum):
|
|
12
|
+
"""How the pieces of a task are placed on the nodes."""
|
|
13
|
+
|
|
14
|
+
FASTEST = "fastest"
|
|
15
|
+
SINGLE_SERVER = "single-server"
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class Priority(StrEnum):
|
|
19
|
+
"""The priority of a run in the queue."""
|
|
20
|
+
|
|
21
|
+
OWNER = "owner"
|
|
22
|
+
STANDARD = "standard"
|
|
23
|
+
AGENT = "agent"
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class WorkflowError(ValueError):
|
|
27
|
+
"""A workflow which is not valid."""
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class ResourceOverride(BaseModel):
|
|
31
|
+
"""Resources of a task which replace the learned or default ones."""
|
|
32
|
+
|
|
33
|
+
workers: int | None = None
|
|
34
|
+
memory_per_worker_gb: float | None = None
|
|
35
|
+
scratch_gb: float | None = None
|
|
36
|
+
gpus: int | None = None
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class TaskSpec(BaseModel):
|
|
40
|
+
"""A task of a workflow.
|
|
41
|
+
|
|
42
|
+
Attributes:
|
|
43
|
+
id: Identifier of the task within the workflow.
|
|
44
|
+
type: Name of the task plugin.
|
|
45
|
+
settings: Settings handed to the plugin.
|
|
46
|
+
inputs: Input port to the output of another task, `<task>.<port>`.
|
|
47
|
+
split: Split mode of the task, the one of the workflow by default.
|
|
48
|
+
resources: Resources replacing the learned or default ones.
|
|
49
|
+
stage: Input ports copied to local scratch.
|
|
50
|
+
"""
|
|
51
|
+
|
|
52
|
+
id: str = Field(pattern=r"^[a-z][a-z0-9-]*$")
|
|
53
|
+
type: str
|
|
54
|
+
settings: dict[str, Any] = Field(default_factory=dict)
|
|
55
|
+
inputs: dict[str, str] = Field(default_factory=dict)
|
|
56
|
+
split: SplitMode | None = None
|
|
57
|
+
resources: ResourceOverride | None = None
|
|
58
|
+
stage: list[str] = Field(default_factory=list)
|
|
59
|
+
|
|
60
|
+
def dependencies(self) -> list[str]:
|
|
61
|
+
"""Ids of the tasks this task reads from, in input order, without repeats."""
|
|
62
|
+
return list(dict.fromkeys(ref.split(".", 1)[0] for ref in self.inputs.values()))
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
class Workflow(BaseModel):
|
|
66
|
+
"""A workflow: tasks which read the outputs of each other."""
|
|
67
|
+
|
|
68
|
+
name: str
|
|
69
|
+
tasks: list[TaskSpec]
|
|
70
|
+
split: SplitMode = SplitMode.FASTEST
|
|
71
|
+
reserve: str | None = None
|
|
72
|
+
|
|
73
|
+
def __init__(self, **data: Any) -> None:
|
|
74
|
+
"""Create a workflow, a reference error is raised as a `WorkflowError`."""
|
|
75
|
+
try:
|
|
76
|
+
super().__init__(**data)
|
|
77
|
+
except ValidationError as error:
|
|
78
|
+
for detail in error.errors():
|
|
79
|
+
cause = detail.get("ctx", {}).get("error")
|
|
80
|
+
if isinstance(cause, WorkflowError):
|
|
81
|
+
raise cause from error
|
|
82
|
+
raise
|
|
83
|
+
|
|
84
|
+
@model_validator(mode="after")
|
|
85
|
+
def _validate(self) -> Self:
|
|
86
|
+
ids = [t.id for t in self.tasks]
|
|
87
|
+
duplicates = sorted({i for i in ids if ids.count(i) > 1})
|
|
88
|
+
if duplicates:
|
|
89
|
+
raise WorkflowError(f"duplicate task ids: {', '.join(duplicates)}")
|
|
90
|
+
for task in self.tasks:
|
|
91
|
+
for port, ref in task.inputs.items():
|
|
92
|
+
source, dot, output = ref.partition(".")
|
|
93
|
+
if not dot or not output:
|
|
94
|
+
raise WorkflowError(
|
|
95
|
+
f"input {port!r} of task {task.id!r} must be "
|
|
96
|
+
f"'<task>.<port>', got {ref!r}"
|
|
97
|
+
)
|
|
98
|
+
if source not in ids:
|
|
99
|
+
raise WorkflowError(
|
|
100
|
+
f"input {port!r} of task {task.id!r} refers to "
|
|
101
|
+
f"unknown task {source!r}"
|
|
102
|
+
)
|
|
103
|
+
self.order()
|
|
104
|
+
return self
|
|
105
|
+
|
|
106
|
+
def task(self, task_id: str) -> TaskSpec:
|
|
107
|
+
"""Return the task with the given id.
|
|
108
|
+
|
|
109
|
+
Raises:
|
|
110
|
+
WorkflowError: If there is no such task.
|
|
111
|
+
"""
|
|
112
|
+
for task in self.tasks:
|
|
113
|
+
if task.id == task_id:
|
|
114
|
+
return task
|
|
115
|
+
raise WorkflowError(f"unknown task {task_id!r}")
|
|
116
|
+
|
|
117
|
+
def order(self) -> list[TaskSpec]:
|
|
118
|
+
"""Return the tasks in topological order, stable in file order.
|
|
119
|
+
|
|
120
|
+
Raises:
|
|
121
|
+
WorkflowError: If the references form a cycle.
|
|
122
|
+
"""
|
|
123
|
+
remaining = {t.id: set(t.dependencies()) for t in self.tasks}
|
|
124
|
+
done: set[str] = set()
|
|
125
|
+
ordered: list[TaskSpec] = []
|
|
126
|
+
while remaining:
|
|
127
|
+
ready = next(
|
|
128
|
+
(
|
|
129
|
+
t
|
|
130
|
+
for t in self.tasks
|
|
131
|
+
if t.id in remaining and remaining[t.id] <= done
|
|
132
|
+
),
|
|
133
|
+
None,
|
|
134
|
+
)
|
|
135
|
+
if ready is None:
|
|
136
|
+
raise WorkflowError(
|
|
137
|
+
f"cycle among tasks: {', '.join(sorted(remaining))}"
|
|
138
|
+
)
|
|
139
|
+
ordered.append(ready)
|
|
140
|
+
done.add(ready.id)
|
|
141
|
+
del remaining[ready.id]
|
|
142
|
+
return ordered
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
def load_workflow(path: Path) -> Workflow:
|
|
146
|
+
"""Read a workflow from a YAML file.
|
|
147
|
+
|
|
148
|
+
Raises:
|
|
149
|
+
WorkflowError: If the file is not a valid workflow.
|
|
150
|
+
"""
|
|
151
|
+
try:
|
|
152
|
+
data = yaml.safe_load(path.read_text())
|
|
153
|
+
if not isinstance(data, dict):
|
|
154
|
+
raise WorkflowError(f"{path}: not a mapping")
|
|
155
|
+
return Workflow(**data)
|
|
156
|
+
except (ValidationError, yaml.YAMLError, UnicodeDecodeError, TypeError) as error:
|
|
157
|
+
raise WorkflowError(f"{path}: {error}") from error
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
def dump_workflow(workflow: Workflow, path: Path) -> None:
|
|
161
|
+
"""Write a workflow as a YAML file."""
|
|
162
|
+
data = workflow.model_dump(mode="json")
|
|
163
|
+
path.write_text(yaml.safe_dump(data, sort_keys=False))
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
class _IndentedDumper(yaml.SafeDumper):
|
|
167
|
+
"""The safe dumper which indents a sequence below its key, as `- id:` below `tasks:`."""
|
|
168
|
+
|
|
169
|
+
def increase_indent(self, flow: bool = False, indentless: bool = False) -> None:
|
|
170
|
+
"""Indent every block, also a sequence which PyYAML would leave indentless."""
|
|
171
|
+
super().increase_indent(flow, False)
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
def workflow_yaml(workflow: Workflow) -> str:
|
|
175
|
+
"""The compact YAML of a workflow: the fields which differ from the defaults.
|
|
176
|
+
|
|
177
|
+
`name` and `tasks` are always written, also when they are the defaults. A
|
|
178
|
+
sequence is indented below its key, as the workflows of the docs are written.
|
|
179
|
+
|
|
180
|
+
Args:
|
|
181
|
+
workflow: The workflow.
|
|
182
|
+
|
|
183
|
+
Returns:
|
|
184
|
+
The YAML text.
|
|
185
|
+
"""
|
|
186
|
+
data = workflow.model_dump(mode="json", exclude_defaults=True)
|
|
187
|
+
data = {"name": workflow.name, "tasks": data.get("tasks", [])} | data
|
|
188
|
+
return yaml.dump(data, Dumper=_IndentedDumper, sort_keys=False)
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: simrun
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Runner of simulation workflows on a k3s cluster with Argo Workflows and Kueue.
|
|
5
|
+
Project-URL: Homepage, https://matthiaskoenig.github.io/simrun
|
|
6
|
+
Project-URL: Documentation, https://matthiaskoenig.github.io/simrun
|
|
7
|
+
Project-URL: Source, https://github.com/matthiaskoenig/simrun
|
|
8
|
+
Project-URL: Issues, https://github.com/matthiaskoenig/simrun/issues
|
|
9
|
+
Project-URL: Changelog, https://github.com/matthiaskoenig/simrun/tree/develop/release-notes
|
|
10
|
+
Project-URL: Download, https://pypi.org/project/simrun
|
|
11
|
+
Author-email: Matthias König <konigmatt@googlemail.com>
|
|
12
|
+
Maintainer-email: Matthias König <konigmatt@googlemail.com>
|
|
13
|
+
License-Expression: MIT
|
|
14
|
+
License-File: LICENSE
|
|
15
|
+
Keywords: argo workflows,computational modeling,k3s,kubernetes,kueue,mcp,simulation,workflow
|
|
16
|
+
Classifier: Development Status :: 3 - Alpha
|
|
17
|
+
Classifier: Environment :: Console
|
|
18
|
+
Classifier: Framework :: FastAPI
|
|
19
|
+
Classifier: Intended Audience :: Science/Research
|
|
20
|
+
Classifier: Intended Audience :: System Administrators
|
|
21
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.15
|
|
24
|
+
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
25
|
+
Classifier: Topic :: Scientific/Engineering
|
|
26
|
+
Classifier: Topic :: System :: Clustering
|
|
27
|
+
Classifier: Topic :: System :: Distributed Computing
|
|
28
|
+
Requires-Python: >=3.14
|
|
29
|
+
Requires-Dist: fastapi>=0.162
|
|
30
|
+
Requires-Dist: fastmcp>=4.1
|
|
31
|
+
Requires-Dist: hera>=7.2
|
|
32
|
+
Requires-Dist: httpx>=0.28.1
|
|
33
|
+
Requires-Dist: kubernetes>=37
|
|
34
|
+
Requires-Dist: pydantic>=2.14
|
|
35
|
+
Requires-Dist: pyyaml>=6.0.3
|
|
36
|
+
Requires-Dist: rich>=14
|
|
37
|
+
Requires-Dist: tomlkit>=0.15.2
|
|
38
|
+
Requires-Dist: typer>=0.27
|
|
39
|
+
Requires-Dist: uvicorn>=0.54.0
|
|
40
|
+
Provides-Extra: cwl
|
|
41
|
+
Requires-Dist: cwl-utils>=0.46; extra == 'cwl'
|
|
42
|
+
Requires-Dist: cwltool>=3.3.20260925135507; extra == 'cwl'
|
|
43
|
+
Provides-Extra: dev
|
|
44
|
+
Requires-Dist: bump-my-version>=1.6.7; extra == 'dev'
|
|
45
|
+
Requires-Dist: cwl-utils>=0.46; extra == 'dev'
|
|
46
|
+
Requires-Dist: cwltool>=3.3.20260925135507; extra == 'dev'
|
|
47
|
+
Requires-Dist: mkdocstrings-python>=2.0.10; extra == 'dev'
|
|
48
|
+
Requires-Dist: pre-commit>=4.7.0; extra == 'dev'
|
|
49
|
+
Requires-Dist: pytest-xdist>=3.8.0; extra == 'dev'
|
|
50
|
+
Requires-Dist: pytest>=9.2.0; extra == 'dev'
|
|
51
|
+
Requires-Dist: ruff>=0.17.4; extra == 'dev'
|
|
52
|
+
Requires-Dist: tox!=4.67.5,>=4.64.9; extra == 'dev'
|
|
53
|
+
Requires-Dist: tox-uv>=1.36.1; extra == 'dev'
|
|
54
|
+
Requires-Dist: ty>=0.0.98; extra == 'dev'
|
|
55
|
+
Requires-Dist: zensical>=0.0.73; extra == 'dev'
|
|
56
|
+
Description-Content-Type: text/markdown
|
|
57
|
+
|
|
58
|
+
# simrun: simulation workflows on a k3s cluster
|
|
59
|
+
[](https://github.com/matthiaskoenig/simrun/actions/workflows/ci-cd.yml)
|
|
60
|
+
[](https://matthiaskoenig.github.io/simrun)
|
|
61
|
+
[](https://pypi.org/project/simrun/)
|
|
62
|
+
[](https://pypi.org/project/simrun/)
|
|
63
|
+
[](https://opensource.org/licenses/MIT)
|
|
64
|
+
[](https://matthiaskoenig.github.io/simrun/development/#pypi-and-zenodo)
|
|
65
|
+
|
|
66
|
+
`simrun` runs simulation workflows on a small cluster of servers with [k3s](https://k3s.io), [Argo Workflows](https://argoproj.github.io/workflows/) and [Kueue](https://kueue.sigs.k8s.io). People and agents submit a workflow of tasks together with the working trees of their model and libraries, uncommitted changes included, and get a run id at once; the run is queued, placed, executed and recorded without the submitter staying connected.
|
|
67
|
+
|
|
68
|
+
Features include
|
|
69
|
+
|
|
70
|
+
- **workflows** - YAML files of tasks of task types from plugins, which read the output ports of other tasks
|
|
71
|
+
- **split tasks** - the units of a task (the repeats of a fit, the points of a scan) spread over the idle servers and are taken back by runs of a higher priority, with results which do not depend on the split
|
|
72
|
+
- **priorities** - the owner of the cluster and the owner's agents first, then the other people, then their agents, with preemption by Kueue and reservations of nodes
|
|
73
|
+
- **learned resources** - the memory of a pod is learned from earlier runs, a pod killed for memory is retried with more
|
|
74
|
+
- **snapshots and environments** - the working trees are snapshotted into a shared run store, the third party dependencies are locked and built into an image only when they change
|
|
75
|
+
- **for people and agents** - a command line, an HTTP API and an MCP server to submit, follow, compare and cancel runs
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
simrun submit fit.yaml --source model=~/git/pkdb_models --source sbmlsim=~/git/sbmlsim --group hctz
|
|
79
|
+
simrun wait <run>
|
|
80
|
+
simrun compare <run> <run>
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
The documentation is available at [https://matthiaskoenig.github.io/simrun](https://matthiaskoenig.github.io/simrun): [installation](https://matthiaskoenig.github.io/simrun/installation/), [concepts](https://matthiaskoenig.github.io/simrun/concepts/), [workflows](https://matthiaskoenig.github.io/simrun/workflows/), [command line](https://matthiaskoenig.github.io/simrun/command-line/), [agents and MCP](https://matthiaskoenig.github.io/simrun/mcp/), [plugins](https://matthiaskoenig.github.io/simrun/plugins/), [service](https://matthiaskoenig.github.io/simrun/service/), [cluster deployment](https://matthiaskoenig.github.io/simrun/deployment/) and [development](https://matthiaskoenig.github.io/simrun/development/).
|
|
84
|
+
|
|
85
|
+
If you have any questions or issues please [open an issue](https://github.com/matthiaskoenig/simrun/issues).
|
|
86
|
+
|
|
87
|
+
## Installation
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
pip install simrun
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
`simrun` needs python 3.14 or newer and runs on Linux, see [Installation](https://matthiaskoenig.github.io/simrun/installation/).
|
|
94
|
+
|
|
95
|
+
## How to cite
|
|
96
|
+
|
|
97
|
+
If you use `simrun` please cite the archived software on [Zenodo](https://zenodo.org); the DOI follows with the first release, see [CITATION.cff](CITATION.cff).
|
|
98
|
+
|
|
99
|
+
## License
|
|
100
|
+
|
|
101
|
+
`simrun` is licensed under the [MIT License](LICENSE).
|
|
102
|
+
|
|
103
|
+
## Funding
|
|
104
|
+
|
|
105
|
+
Matthias König is supported by the Federal Ministry of Education and Research (BMBF, Germany) within the research network Systems Medicine of the Liver (**LiSyM**, grant number 031L0054) and by the German Research Foundation (DFG) within the Research Unit Programme FOR 5151 [QuaLiPerF](https://qualiperf.de) (Quantifying Liver Perfusion-Function Relationship in Complex Resection - A Systems Medicine Approach) by grant number 436883643 and by grant number 465194077 (Priority Programme SPP 2311, Subproject SimLivA). Matthias König has received funds from the EOSCsecretariat.eu which has received funding from the European Union's Horizon Programme call H2020-INFRAEOSC-05-2018-2019, grant Agreement number 831644.
|
|
106
|
+
|
|
107
|
+
© 2026 Matthias König
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
simrun/__init__.py,sha256=2WkMl29mm1mI4GONAAt1hwehkyf5Mk_eGtZBeo19Sfs,88
|
|
2
|
+
simrun/argo.py,sha256=AdOoY3cHBQFAZEcP9oHIcnYPuf-dtlT-arSQeUn3E8M,17169
|
|
3
|
+
simrun/build_constraints.txt,sha256=vUuUCjavINiqy0H0W4Qa4lx_1OQ29RswduUukMHd2QA,722
|
|
4
|
+
simrun/cgroup.py,sha256=pkLqXMRssLstML-2BkUdNZkpjuXfMdlLXuELTnoGpCI,2240
|
|
5
|
+
simrun/cli.py,sha256=TTmBtEP4k8xgGxM9xICJ3j9uG6oT9jPWN9eWO-eJGas,10996
|
|
6
|
+
simrun/client.py,sha256=Z6r2beJj2M1RXB420inAIW7p7Ow4rNiRU9p_p72czDQ,15077
|
|
7
|
+
simrun/config.py,sha256=vYvO0CIDThMJBm76fcT-vOZcjBDzWtypmcWCUG7P9mY,2882
|
|
8
|
+
simrun/cwl.py,sha256=iMNWRPdqNKmXlROSmnrb_GGN1xyoJIx2vL9Uh4V1mUs,10294
|
|
9
|
+
simrun/demo.py,sha256=I0Gy1VpKdGA95crR_4UNxrttpgEJK9AVjBrB2cX6Dfo,3039
|
|
10
|
+
simrun/edit.py,sha256=nYNhLJXWJrRFUL0W2jEC7weuHexRTkihasR47AW6LMo,14618
|
|
11
|
+
simrun/environment.py,sha256=f92LEuwPcLz5Vu3JTUbzl2cRKhJQ9wsyLlNg0sad_mA,16413
|
|
12
|
+
simrun/ledger.py,sha256=RD6tuEoUSJ2p8qfdWI6s12jgxqwYx3-r-wdQjaVTxik,10799
|
|
13
|
+
simrun/mcp.py,sha256=xIUd1QXTIGGh8gPzT0xKXHejNAky4atW0vi3R2VsJNY,5779
|
|
14
|
+
simrun/planner.py,sha256=vdaCrFwFDd_vI639vhkTEbS3xkIj2cx6tkMwqKACSag,9907
|
|
15
|
+
simrun/plugins.py,sha256=nG7qm_d4sF4oc0qhPPnUBhueg4TDM2a9gZh4bM4RMvw,5436
|
|
16
|
+
simrun/plugins_builtin.py,sha256=k8D_28hA9hF5v1y-t0sFxTiTRgJWYi-AXgc9WhmkErk,735
|
|
17
|
+
simrun/podspec.py,sha256=SlRZcECVPXtx8RzWMn6AqRYg6k9Yxctga8SZ1De5zFY,5976
|
|
18
|
+
simrun/resources.py,sha256=8E-wfz96dqE5b7gmPjjq4v8uMyxy-7COrSqD6weYsI4,9709
|
|
19
|
+
simrun/snapshot.py,sha256=iqyhO3C1ONddOXIPHKlPK0VkHCDQht1ixTUHxvz0_FM,7020
|
|
20
|
+
simrun/store.py,sha256=BefcMp_7psI5JcBnZBhW3hyGqxfoIASge0pLvXUOJrw,5749
|
|
21
|
+
simrun/testing.py,sha256=NDYf5iG5yP3fDnrJPodVCJzmMnl-J9MuE17eHJ7PENY,9986
|
|
22
|
+
simrun/worker.py,sha256=NcI4jjLiw_l-Z5xuY3UiUMIet3KQON8eP2snbqDgQZ8,40011
|
|
23
|
+
simrun/workflow.py,sha256=Z-XEsS2VKkutO--As8L6Lxsq5MaOglkudBI0diPzE4U,6294
|
|
24
|
+
simrun/service/__init__.py,sha256=uB44sSOqMuPgxogrzpSbqTSLlOUAd1giqDFmRocqJFY,83
|
|
25
|
+
simrun/service/app.py,sha256=pfAub9oPGOa7ynzJoJATn3FfC53uInK3ze7ih4-24v0,64999
|
|
26
|
+
simrun/service/argo_backend.py,sha256=8pPRVl3Jpgz5IzqMyYR8ywEUaoMMqW9BdQi-MYie8pk,33873
|
|
27
|
+
simrun/service/auth.py,sha256=MlVBPMy6X_NACq66YO9B1CLvkSazTwk10FaUUkxz9nA,2944
|
|
28
|
+
simrun/service/backend.py,sha256=E-jsRzcYPCQCg0Xejfh_MfM3ddAJoPM4uaOf21bp-P8,5685
|
|
29
|
+
simrun/service/compare.py,sha256=o-P-Rwghmo4pZ4a0XTTFqVBF_EPvd6KRa7FJXF_aCjc,2404
|
|
30
|
+
simrun/service/controller.py,sha256=K0NpDTgr0_acfPCu3Xbk10neJKCbL45Ah1k70EDuXws,32918
|
|
31
|
+
simrun/service/edits.py,sha256=kBuQr7AyPViWm-EYDIxeuT-l0T-0ryBFBpjB0Nv68Y8,12974
|
|
32
|
+
simrun/service/index.py,sha256=fPQCImiVHXfCRCib1scWCxG1cjx31qwBhUuOdXDBYwY,10914
|
|
33
|
+
simrun/service/logs.py,sha256=fmLfVDyvbbqQeZaHDjNR9RZ2Usq4P1UO45u405hCVPY,3324
|
|
34
|
+
simrun/service/submission.py,sha256=yTYGxLXoKE6PrTWfjhPFxYgnVmt7yMF71xltxCb_u_c,13852
|
|
35
|
+
simrun-0.1.0.dist-info/METADATA,sha256=LxhHtHnHuoATTKNEkEN_tn_T9iwYcZ1m2_LuFfwRd48,6813
|
|
36
|
+
simrun-0.1.0.dist-info/WHEEL,sha256=2iZrJkDIkeDh0k9SikKMqFuRP-ua6mb4Ir1AsER4BEw,87
|
|
37
|
+
simrun-0.1.0.dist-info/entry_points.txt,sha256=mYlANnOVF5jAfb1G-5RFtiNEbCnoPs2dIe34ZALW7lQ,281
|
|
38
|
+
simrun-0.1.0.dist-info/licenses/LICENSE,sha256=zPHyGxsERxx2deQExcGSq3mg5NgDaCZ5-4pfkbgsEXo,1059
|
|
39
|
+
simrun-0.1.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
[console_scripts]
|
|
2
|
+
simrun = simrun.cli:app
|
|
3
|
+
simrun-exec = simrun.worker:exec_main
|
|
4
|
+
simrun-mcp = simrun.mcp:main
|
|
5
|
+
simrun-merge = simrun.worker:merge_main
|
|
6
|
+
simrun-worker = simrun.worker:main
|
|
7
|
+
|
|
8
|
+
[simrun.task_types]
|
|
9
|
+
command = simrun.plugins_builtin:COMMAND
|
|
10
|
+
demo.squares = simrun.demo:SQUARES
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
Copyright (c) 2026 Matthias König
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
4
|
+
|
|
5
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
6
|
+
|
|
7
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|