kkrunner 0.1.0b1__tar.gz

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 (170) hide show
  1. kkrunner-0.1.0b1/LICENCE +19 -0
  2. kkrunner-0.1.0b1/MANIFEST.in +5 -0
  3. kkrunner-0.1.0b1/Makefile +10 -0
  4. kkrunner-0.1.0b1/PKG-INFO +162 -0
  5. kkrunner-0.1.0b1/README.md +139 -0
  6. kkrunner-0.1.0b1/docs/_templates/autosummary/class.rst +8 -0
  7. kkrunner-0.1.0b1/docs/_templates/autosummary/function.rst +5 -0
  8. kkrunner-0.1.0b1/docs/api.rst +141 -0
  9. kkrunner-0.1.0b1/docs/architecture.md +218 -0
  10. kkrunner-0.1.0b1/docs/backends.rst +113 -0
  11. kkrunner-0.1.0b1/docs/command-line.rst +34 -0
  12. kkrunner-0.1.0b1/docs/conf.py +35 -0
  13. kkrunner-0.1.0b1/docs/development.rst +149 -0
  14. kkrunner-0.1.0b1/docs/files.rst +105 -0
  15. kkrunner-0.1.0b1/docs/index.rst +35 -0
  16. kkrunner-0.1.0b1/docs/installation.rst +53 -0
  17. kkrunner-0.1.0b1/docs/persistent-runs.rst +130 -0
  18. kkrunner-0.1.0b1/docs/projects.rst +58 -0
  19. kkrunner-0.1.0b1/docs/quickstart.rst +59 -0
  20. kkrunner-0.1.0b1/docs/remarks/README.md +9 -0
  21. kkrunner-0.1.0b1/docs/remarks/modularization-validation.md +24 -0
  22. kkrunner-0.1.0b1/docs/remarks/source-provenance.md +9 -0
  23. kkrunner-0.1.0b1/docs/remarks/validation.md +101 -0
  24. kkrunner-0.1.0b1/docs/remote.rst +97 -0
  25. kkrunner-0.1.0b1/pyproject.toml +36 -0
  26. kkrunner-0.1.0b1/setup.cfg +4 -0
  27. kkrunner-0.1.0b1/src/kkrunner/__init__.py +16 -0
  28. kkrunner-0.1.0b1/src/kkrunner/__main__.py +3 -0
  29. kkrunner-0.1.0b1/src/kkrunner/_version.py +5 -0
  30. kkrunner-0.1.0b1/src/kkrunner/backends/__init__.py +35 -0
  31. kkrunner-0.1.0b1/src/kkrunner/backends/endpoint.py +179 -0
  32. kkrunner-0.1.0b1/src/kkrunner/backends/local.py +328 -0
  33. kkrunner-0.1.0b1/src/kkrunner/backends/local_managed.py +363 -0
  34. kkrunner-0.1.0b1/src/kkrunner/backends/local_process.py +144 -0
  35. kkrunner-0.1.0b1/src/kkrunner/backends/mpi.py +63 -0
  36. kkrunner-0.1.0b1/src/kkrunner/backends/pool.py +68 -0
  37. kkrunner-0.1.0b1/src/kkrunner/backends/psij.py +930 -0
  38. kkrunner-0.1.0b1/src/kkrunner/cli.py +180 -0
  39. kkrunner-0.1.0b1/src/kkrunner/files/__init__.py +27 -0
  40. kkrunner-0.1.0b1/src/kkrunner/files/availability.py +92 -0
  41. kkrunner-0.1.0b1/src/kkrunner/files/fingerprints.py +35 -0
  42. kkrunner-0.1.0b1/src/kkrunner/files/manifest.py +376 -0
  43. kkrunner-0.1.0b1/src/kkrunner/files/paths.py +66 -0
  44. kkrunner-0.1.0b1/src/kkrunner/files/queries.py +110 -0
  45. kkrunner-0.1.0b1/src/kkrunner/files/task_file.py +67 -0
  46. kkrunner-0.1.0b1/src/kkrunner/files/versions.py +187 -0
  47. kkrunner-0.1.0b1/src/kkrunner/projects/__init__.py +21 -0
  48. kkrunner-0.1.0b1/src/kkrunner/projects/manager.py +89 -0
  49. kkrunner-0.1.0b1/src/kkrunner/projects/repository.py +436 -0
  50. kkrunner-0.1.0b1/src/kkrunner/projects/resolution.py +19 -0
  51. kkrunner-0.1.0b1/src/kkrunner/remote/__init__.py +6 -0
  52. kkrunner-0.1.0b1/src/kkrunner/remote/executor.py +715 -0
  53. kkrunner-0.1.0b1/src/kkrunner/remote/mailbox.py +85 -0
  54. kkrunner-0.1.0b1/src/kkrunner/remote/protocol.py +27 -0
  55. kkrunner-0.1.0b1/src/kkrunner/remote/runner.py +771 -0
  56. kkrunner-0.1.0b1/src/kkrunner/remote/service.py +600 -0
  57. kkrunner-0.1.0b1/src/kkrunner/remote/stream.py +154 -0
  58. kkrunner-0.1.0b1/src/kkrunner/remote/supervisor.py +318 -0
  59. kkrunner-0.1.0b1/src/kkrunner/remote/transport.py +429 -0
  60. kkrunner-0.1.0b1/src/kkrunner/remote/worker.py +199 -0
  61. kkrunner-0.1.0b1/src/kkrunner/runs/__init__.py +45 -0
  62. kkrunner-0.1.0b1/src/kkrunner/runs/base.py +700 -0
  63. kkrunner-0.1.0b1/src/kkrunner/runs/conflicts.py +92 -0
  64. kkrunner-0.1.0b1/src/kkrunner/runs/manager.py +1132 -0
  65. kkrunner-0.1.0b1/src/kkrunner/runs/metadata.py +40 -0
  66. kkrunner-0.1.0b1/src/kkrunner/runs/model.py +58 -0
  67. kkrunner-0.1.0b1/src/kkrunner/runs/processing.py +214 -0
  68. kkrunner-0.1.0b1/src/kkrunner/runs/records.py +252 -0
  69. kkrunner-0.1.0b1/src/kkrunner/support/__init__.py +1 -0
  70. kkrunner-0.1.0b1/src/kkrunner/support/async_utils.py +30 -0
  71. kkrunner-0.1.0b1/src/kkrunner/support/decorators.py +24 -0
  72. kkrunner-0.1.0b1/src/kkrunner/support/durability.py +137 -0
  73. kkrunner-0.1.0b1/src/kkrunner/support/file_locks.py +91 -0
  74. kkrunner-0.1.0b1/src/kkrunner/support/growing_file_tail.py +260 -0
  75. kkrunner-0.1.0b1/src/kkrunner/support/process_identity.py +85 -0
  76. kkrunner-0.1.0b1/src/kkrunner.egg-info/PKG-INFO +162 -0
  77. kkrunner-0.1.0b1/src/kkrunner.egg-info/SOURCES.txt +168 -0
  78. kkrunner-0.1.0b1/src/kkrunner.egg-info/dependency_links.txt +1 -0
  79. kkrunner-0.1.0b1/src/kkrunner.egg-info/entry_points.txt +2 -0
  80. kkrunner-0.1.0b1/src/kkrunner.egg-info/requires.txt +13 -0
  81. kkrunner-0.1.0b1/src/kkrunner.egg-info/top_level.txt +1 -0
  82. kkrunner-0.1.0b1/tests/__init__.py +0 -0
  83. kkrunner-0.1.0b1/tests/conftest.py +32 -0
  84. kkrunner-0.1.0b1/tests/docker/Dockerfile +62 -0
  85. kkrunner-0.1.0b1/tests/docker/cgroup.conf +4 -0
  86. kkrunner-0.1.0b1/tests/docker/entrypoint.sh +96 -0
  87. kkrunner-0.1.0b1/tests/docker/psij_slurm_test_in_docker.py +33 -0
  88. kkrunner-0.1.0b1/tests/docker/slurm.conf +28 -0
  89. kkrunner-0.1.0b1/tests/smoke_distribution.py +88 -0
  90. kkrunner-0.1.0b1/tests/test_artifact_failure_semantics.py +180 -0
  91. kkrunner-0.1.0b1/tests/test_attach_output_listener.py +233 -0
  92. kkrunner-0.1.0b1/tests/test_cancel_dispatch.py +55 -0
  93. kkrunner-0.1.0b1/tests/test_cancellation.py +113 -0
  94. kkrunner-0.1.0b1/tests/test_cli.py +96 -0
  95. kkrunner-0.1.0b1/tests/test_completion_contracts.py +165 -0
  96. kkrunner-0.1.0b1/tests/test_duplicate_submission.py +262 -0
  97. kkrunner-0.1.0b1/tests/test_durability_mode.py +20 -0
  98. kkrunner-0.1.0b1/tests/test_endpoint_persistence.py +143 -0
  99. kkrunner-0.1.0b1/tests/test_execution_policy.py +267 -0
  100. kkrunner-0.1.0b1/tests/test_executor_pool.py +73 -0
  101. kkrunner-0.1.0b1/tests/test_extraction_contracts.py +225 -0
  102. kkrunner-0.1.0b1/tests/test_file_availability.py +195 -0
  103. kkrunner-0.1.0b1/tests/test_file_fingerprints.py +23 -0
  104. kkrunner-0.1.0b1/tests/test_file_locks.py +26 -0
  105. kkrunner-0.1.0b1/tests/test_file_queries.py +216 -0
  106. kkrunner-0.1.0b1/tests/test_file_versions.py +55 -0
  107. kkrunner-0.1.0b1/tests/test_finishing_state.py +146 -0
  108. kkrunner-0.1.0b1/tests/test_growing_file_tail.py +409 -0
  109. kkrunner-0.1.0b1/tests/test_incremental_output.py +33 -0
  110. kkrunner-0.1.0b1/tests/test_lifecycle_review_regressions.py +32 -0
  111. kkrunner-0.1.0b1/tests/test_local_managed.py +385 -0
  112. kkrunner-0.1.0b1/tests/test_local_status.py +110 -0
  113. kkrunner-0.1.0b1/tests/test_local_stream_contract.py +95 -0
  114. kkrunner-0.1.0b1/tests/test_managed_run_id.py +20 -0
  115. kkrunner-0.1.0b1/tests/test_monitor_completion.py +86 -0
  116. kkrunner-0.1.0b1/tests/test_monitored_runner_wait.py +36 -0
  117. kkrunner-0.1.0b1/tests/test_mpi_runtime.py +220 -0
  118. kkrunner-0.1.0b1/tests/test_optional_remote_output.py +42 -0
  119. kkrunner-0.1.0b1/tests/test_output_closure.py +150 -0
  120. kkrunner-0.1.0b1/tests/test_output_observer_bytes.py +110 -0
  121. kkrunner-0.1.0b1/tests/test_package_structure.py +121 -0
  122. kkrunner-0.1.0b1/tests/test_path_streams.py +43 -0
  123. kkrunner-0.1.0b1/tests/test_persistence_durability.py +141 -0
  124. kkrunner-0.1.0b1/tests/test_persistent_runner_completion_once.py +131 -0
  125. kkrunner-0.1.0b1/tests/test_postprocessing_recovery.py +228 -0
  126. kkrunner-0.1.0b1/tests/test_process_identity.py +239 -0
  127. kkrunner-0.1.0b1/tests/test_process_termination.py +77 -0
  128. kkrunner-0.1.0b1/tests/test_project_global_history.py +110 -0
  129. kkrunner-0.1.0b1/tests/test_project_resolution.py +31 -0
  130. kkrunner-0.1.0b1/tests/test_project_run_assignment.py +99 -0
  131. kkrunner-0.1.0b1/tests/test_project_run_contract.py +21 -0
  132. kkrunner-0.1.0b1/tests/test_projects.py +216 -0
  133. kkrunner-0.1.0b1/tests/test_psij.py +1266 -0
  134. kkrunner-0.1.0b1/tests/test_psij_finalization.py +28 -0
  135. kkrunner-0.1.0b1/tests/test_psij_persistent_identity.py +62 -0
  136. kkrunner-0.1.0b1/tests/test_psij_slurm.py +35 -0
  137. kkrunner-0.1.0b1/tests/test_psij_slurm_time.py +9 -0
  138. kkrunner-0.1.0b1/tests/test_remote.py +525 -0
  139. kkrunner-0.1.0b1/tests/test_remote_attach.py +203 -0
  140. kkrunner-0.1.0b1/tests/test_remote_backend_options.py +112 -0
  141. kkrunner-0.1.0b1/tests/test_remote_endpoint_status.py +193 -0
  142. kkrunner-0.1.0b1/tests/test_remote_mailbox.py +52 -0
  143. kkrunner-0.1.0b1/tests/test_remote_output_gate.py +222 -0
  144. kkrunner-0.1.0b1/tests/test_remote_output_integrity.py +76 -0
  145. kkrunner-0.1.0b1/tests/test_remote_prepare_boundary.py +209 -0
  146. kkrunner-0.1.0b1/tests/test_remote_public_api.py +7 -0
  147. kkrunner-0.1.0b1/tests/test_remote_result_files_fetch.py +221 -0
  148. kkrunner-0.1.0b1/tests/test_remote_run_context.py +212 -0
  149. kkrunner-0.1.0b1/tests/test_remote_service.py +907 -0
  150. kkrunner-0.1.0b1/tests/test_remote_stream_protocol.py +189 -0
  151. kkrunner-0.1.0b1/tests/test_remote_submission_namespace.py +78 -0
  152. kkrunner-0.1.0b1/tests/test_remote_submission_recovery.py +89 -0
  153. kkrunner-0.1.0b1/tests/test_remote_supervisor_modes.py +261 -0
  154. kkrunner-0.1.0b1/tests/test_remote_supervisor_stream.py +449 -0
  155. kkrunner-0.1.0b1/tests/test_remote_wildcards.py +337 -0
  156. kkrunner-0.1.0b1/tests/test_reservations.py +90 -0
  157. kkrunner-0.1.0b1/tests/test_resource_closure.py +57 -0
  158. kkrunner-0.1.0b1/tests/test_result_files_api.py +31 -0
  159. kkrunner-0.1.0b1/tests/test_review_fixes.py +72 -0
  160. kkrunner-0.1.0b1/tests/test_run_manager.py +182 -0
  161. kkrunner-0.1.0b1/tests/test_run_model.py +436 -0
  162. kkrunner-0.1.0b1/tests/test_run_record_schema.py +109 -0
  163. kkrunner-0.1.0b1/tests/test_run_store_merge.py +67 -0
  164. kkrunner-0.1.0b1/tests/test_run_task_metadata.py +14 -0
  165. kkrunner-0.1.0b1/tests/test_runner_edge_cases.py +11 -0
  166. kkrunner-0.1.0b1/tests/test_ssh_standalone.py +108 -0
  167. kkrunner-0.1.0b1/tests/test_standalone_recovery.py +268 -0
  168. kkrunner-0.1.0b1/tests/test_submitting_recovery.py +110 -0
  169. kkrunner-0.1.0b1/tests/test_terminal_states.py +15 -0
  170. kkrunner-0.1.0b1/tests/test_transport.py +520 -0
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2018 The Python Packaging Authority
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ SOFTWARE.
@@ -0,0 +1,5 @@
1
+ include LICENCE README.md Makefile
2
+ recursive-include docs *.md *.rst *.py
3
+ prune docs/_generated
4
+ recursive-include tests *.py *.sh *.conf Dockerfile
5
+ global-exclude *.py[cod]
@@ -0,0 +1,10 @@
1
+ PYTHON ?= python
2
+ SPHINXOPTS ?= -W --keep-going
3
+
4
+ .PHONY: docs docs-test
5
+
6
+ docs:
7
+ $(PYTHON) -m sphinx -M html docs build/docs $(SPHINXOPTS)
8
+
9
+ docs-test:
10
+ $(PYTHON) -m sphinx -M doctest docs build/docs $(SPHINXOPTS)
@@ -0,0 +1,162 @@
1
+ Metadata-Version: 2.4
2
+ Name: kkrunner
3
+ Version: 0.1.0b1
4
+ Summary: Program-independent local and remote scientific job execution
5
+ License-Expression: MIT
6
+ Project-URL: Documentation, https://ase2sprkkr.github.io/kkrunner/
7
+ Project-URL: Source, https://github.com/ase2sprkkr/kkrunner
8
+ Project-URL: Issues, https://github.com/ase2sprkkr/kkrunner/issues
9
+ Requires-Python: >=3.9
10
+ Description-Content-Type: text/markdown
11
+ License-File: LICENCE
12
+ Requires-Dist: platformdirs
13
+ Requires-Dist: psutil>=5.8.0
14
+ Provides-Extra: psij
15
+ Requires-Dist: psij-python>=0.9.11; extra == "psij"
16
+ Provides-Extra: test
17
+ Requires-Dist: pytest; extra == "test"
18
+ Provides-Extra: docs
19
+ Requires-Dist: sphinx>=7; extra == "docs"
20
+ Requires-Dist: sphinx-rtd-theme>=3; extra == "docs"
21
+ Requires-Dist: myst-parser>=3; extra == "docs"
22
+ Dynamic: license-file
23
+
24
+ # KKRunner
25
+
26
+ Program-independent Python execution, durable run history, file manifests,
27
+ local/MPI processes, SSH transport and optional PSI/J scheduler support.
28
+ The core depends on `platformdirs` and `psutil`; scheduler support is an optional extra.
29
+
30
+ ```sh
31
+ python -m pip install .
32
+ python -m pip install '.[psij]' # optional scheduler support
33
+ kkrunner remote --help
34
+ ```
35
+
36
+ Run these commands from the KKRunner checkout in a virtual environment.
37
+ Use `python -m pip install --editable .` instead when editing the source.
38
+
39
+ ## Raw execution
40
+
41
+ ```python
42
+ import sys
43
+ from kkrunner import ExecutionSpec
44
+ from kkrunner.backends import LocalExecutor
45
+
46
+ run = LocalExecutor().create_run(ExecutionSpec([sys.executable, '-c', 'print(42)']))
47
+ outcome = run.run()
48
+ assert outcome.return_code == 0
49
+ ```
50
+
51
+ ## Persistent execution
52
+
53
+ A `RunManager` records runs in a `RunStore` so a later client can reconnect.
54
+ Projects are optional; see the [project guide](docs/projects.rst) for grouping.
55
+
56
+ ```python
57
+ import sys
58
+ from pathlib import Path
59
+ from kkrunner import ExecutionSpec, RunManager, RunStore
60
+ from kkrunner.backends import LocalExecutor
61
+
62
+ root = Path('example').absolute()
63
+ root.mkdir(exist_ok=True)
64
+ manager = RunManager(RunStore(root / 'runs'))
65
+ run = manager.create_run(
66
+ LocalExecutor(),
67
+ ExecutionSpec([sys.executable, '-c', 'print(42)'],
68
+ directory=root, output_file='stdout.txt'),
69
+ metadata={'example': {'label': 'answer'}},
70
+ )
71
+ outcome = run.run()
72
+ assert manager.store.get(run.id).state.value == 'finished'
73
+ ```
74
+
75
+ `manager.attach(run_id)` resumes monitoring and required transfers. A result
76
+ callback is optional; when supplied it receives an `ExecutionOutcome` and may
77
+ return any Python object. To defer processing, create a run with
78
+ `processing_required=True`, then supply `process_result=` on a later attach.
79
+ Without that callback the durable state remains `postprocessing` and `wait()`
80
+ raises `ProcessingPending`. The same exception tells an application observer
81
+ that another client owns/already performed processing; load the historical
82
+ application result instead of treating a raw outcome as a parsed result.
83
+
84
+ `manager.retry_postprocessing(run_id, callback)` retries failed/interrupted
85
+ processing against the captured files without submitting another process.
86
+ `manager.resume_download(run_id)` reopens a failed download before attach.
87
+ `run.stop_observation()` detaches observation without cancelling the backend;
88
+ `run.cancel()` requests backend cancellation. Untracked raw local runs have no
89
+ restart/reconnect guarantee; managed local runs use the same supervisor as SSH.
90
+
91
+ See the [documentation guide](docs/index.rst) and [architecture](docs/architecture.md)
92
+ for usage, ownership, recovery and format rules.
93
+
94
+ ## Development and distribution
95
+
96
+ For development, install an editable checkout with test dependencies:
97
+
98
+ ```sh
99
+ python -m pip install --editable '.[test]'
100
+ python -m pytest -q
101
+ ```
102
+
103
+ To produce archives for sharing, install the build tool with
104
+ `python -m pip install build`, then run `python -m build`. This creates a source
105
+ archive and an installable wheel in `dist/`. CI validates these artifacts on
106
+ Linux with Python 3.9, 3.12 and 3.14, plus macOS tests on Apple Silicon and
107
+ Intel with Python 3.12, including durable local supervision and reconnect.
108
+ See [development](docs/development.rst) for test scope and packaging details.
109
+
110
+ ## Publish to PyPI
111
+
112
+ The `publish-pypi.yml` workflow runs on a `v<version>` tag from any branch.
113
+ The tag must exactly match `[project].version` in `pyproject.toml`; publication
114
+ is independent of branch names.
115
+ The version is defined in `pyproject.toml`; `kkrunner.__version__` reads the
116
+ installed distribution metadata automatically.
117
+
118
+ Configure a PyPI Trusted Publisher for project `kkrunner`, GitHub owner
119
+ `ase2sprkkr`, repository `kkrunner`, workflow `publish-pypi.yml` and environment
120
+ `pypi`. Protect the GitHub `pypi` environment with required reviewers and `v*`
121
+ tag rules. If hosted under another owner, use that owner in
122
+ the publisher configuration. No PyPI API token is needed.
123
+
124
+ The workflow verifies the tag, builds one source archive and wheel,
125
+ then tests that wheel on Python 3.9, 3.12 and 3.14 and builds/tests the documentation.
126
+ Only after all checks pass does the publish job upload those exact artifacts
127
+ using the `pypi` environment and GitHub's OIDC token.
128
+
129
+ For nonpublic evaluation, use a prerelease version and do not push a version tag.
130
+ Branch CI retains wheel/sdist artifacts for evaluation. Use access-controlled
131
+ storage when sharing with testers: GitHub artifacts in a public repository are
132
+ not private, and an upload to PyPI is public even for a development version.
133
+
134
+ ## Documentation
135
+
136
+ Documentation is published at <https://ase2sprkkr.github.io/kkrunner/> after
137
+ successful runtime and documentation checks on `master`.
138
+
139
+ The user guide and API reference use Sphinx with the Read the Docs theme.
140
+ Install the documentation extra and build the HTML and examples:
141
+
142
+ ```sh
143
+ python -m venv .venv
144
+ .venv/bin/python -m pip install -e '.[docs]'
145
+ make docs PYTHON=.venv/bin/python
146
+ make docs-test PYTHON=.venv/bin/python
147
+ ```
148
+
149
+ Use the same Python for dependency installation and Makefile targets; the
150
+ `docs` extra includes MyST and the theme. Open `build/docs/html/index.html`. See [the guide](docs/index.rst) for raw and
151
+ persistent execution, manifests, projects, schedulers, remote execution and the
152
+ CLI; [development](docs/development.rst) covers builds and releases. Generated
153
+ API pages and HTML are not committed. CI validates documentation against the
154
+ installed wheel and uploads the HTML artifact. The separate documentation
155
+ workflow checks the same wheel and documentation, omits the runtime test
156
+ matrices, and deploys to GitHub Pages for `v*` tags or manual runs. Enable
157
+ **Settings → Pages → Build and deployment → GitHub Actions** and allow release
158
+ tags and manually selected source branches in the `github-pages` environment
159
+ deployment rules.
160
+
161
+ Source provenance is recorded in [development remarks](docs/remarks/source-provenance.md);
162
+ the license is in [LICENCE](LICENCE).
@@ -0,0 +1,139 @@
1
+ # KKRunner
2
+
3
+ Program-independent Python execution, durable run history, file manifests,
4
+ local/MPI processes, SSH transport and optional PSI/J scheduler support.
5
+ The core depends on `platformdirs` and `psutil`; scheduler support is an optional extra.
6
+
7
+ ```sh
8
+ python -m pip install .
9
+ python -m pip install '.[psij]' # optional scheduler support
10
+ kkrunner remote --help
11
+ ```
12
+
13
+ Run these commands from the KKRunner checkout in a virtual environment.
14
+ Use `python -m pip install --editable .` instead when editing the source.
15
+
16
+ ## Raw execution
17
+
18
+ ```python
19
+ import sys
20
+ from kkrunner import ExecutionSpec
21
+ from kkrunner.backends import LocalExecutor
22
+
23
+ run = LocalExecutor().create_run(ExecutionSpec([sys.executable, '-c', 'print(42)']))
24
+ outcome = run.run()
25
+ assert outcome.return_code == 0
26
+ ```
27
+
28
+ ## Persistent execution
29
+
30
+ A `RunManager` records runs in a `RunStore` so a later client can reconnect.
31
+ Projects are optional; see the [project guide](docs/projects.rst) for grouping.
32
+
33
+ ```python
34
+ import sys
35
+ from pathlib import Path
36
+ from kkrunner import ExecutionSpec, RunManager, RunStore
37
+ from kkrunner.backends import LocalExecutor
38
+
39
+ root = Path('example').absolute()
40
+ root.mkdir(exist_ok=True)
41
+ manager = RunManager(RunStore(root / 'runs'))
42
+ run = manager.create_run(
43
+ LocalExecutor(),
44
+ ExecutionSpec([sys.executable, '-c', 'print(42)'],
45
+ directory=root, output_file='stdout.txt'),
46
+ metadata={'example': {'label': 'answer'}},
47
+ )
48
+ outcome = run.run()
49
+ assert manager.store.get(run.id).state.value == 'finished'
50
+ ```
51
+
52
+ `manager.attach(run_id)` resumes monitoring and required transfers. A result
53
+ callback is optional; when supplied it receives an `ExecutionOutcome` and may
54
+ return any Python object. To defer processing, create a run with
55
+ `processing_required=True`, then supply `process_result=` on a later attach.
56
+ Without that callback the durable state remains `postprocessing` and `wait()`
57
+ raises `ProcessingPending`. The same exception tells an application observer
58
+ that another client owns/already performed processing; load the historical
59
+ application result instead of treating a raw outcome as a parsed result.
60
+
61
+ `manager.retry_postprocessing(run_id, callback)` retries failed/interrupted
62
+ processing against the captured files without submitting another process.
63
+ `manager.resume_download(run_id)` reopens a failed download before attach.
64
+ `run.stop_observation()` detaches observation without cancelling the backend;
65
+ `run.cancel()` requests backend cancellation. Untracked raw local runs have no
66
+ restart/reconnect guarantee; managed local runs use the same supervisor as SSH.
67
+
68
+ See the [documentation guide](docs/index.rst) and [architecture](docs/architecture.md)
69
+ for usage, ownership, recovery and format rules.
70
+
71
+ ## Development and distribution
72
+
73
+ For development, install an editable checkout with test dependencies:
74
+
75
+ ```sh
76
+ python -m pip install --editable '.[test]'
77
+ python -m pytest -q
78
+ ```
79
+
80
+ To produce archives for sharing, install the build tool with
81
+ `python -m pip install build`, then run `python -m build`. This creates a source
82
+ archive and an installable wheel in `dist/`. CI validates these artifacts on
83
+ Linux with Python 3.9, 3.12 and 3.14, plus macOS tests on Apple Silicon and
84
+ Intel with Python 3.12, including durable local supervision and reconnect.
85
+ See [development](docs/development.rst) for test scope and packaging details.
86
+
87
+ ## Publish to PyPI
88
+
89
+ The `publish-pypi.yml` workflow runs on a `v<version>` tag from any branch.
90
+ The tag must exactly match `[project].version` in `pyproject.toml`; publication
91
+ is independent of branch names.
92
+ The version is defined in `pyproject.toml`; `kkrunner.__version__` reads the
93
+ installed distribution metadata automatically.
94
+
95
+ Configure a PyPI Trusted Publisher for project `kkrunner`, GitHub owner
96
+ `ase2sprkkr`, repository `kkrunner`, workflow `publish-pypi.yml` and environment
97
+ `pypi`. Protect the GitHub `pypi` environment with required reviewers and `v*`
98
+ tag rules. If hosted under another owner, use that owner in
99
+ the publisher configuration. No PyPI API token is needed.
100
+
101
+ The workflow verifies the tag, builds one source archive and wheel,
102
+ then tests that wheel on Python 3.9, 3.12 and 3.14 and builds/tests the documentation.
103
+ Only after all checks pass does the publish job upload those exact artifacts
104
+ using the `pypi` environment and GitHub's OIDC token.
105
+
106
+ For nonpublic evaluation, use a prerelease version and do not push a version tag.
107
+ Branch CI retains wheel/sdist artifacts for evaluation. Use access-controlled
108
+ storage when sharing with testers: GitHub artifacts in a public repository are
109
+ not private, and an upload to PyPI is public even for a development version.
110
+
111
+ ## Documentation
112
+
113
+ Documentation is published at <https://ase2sprkkr.github.io/kkrunner/> after
114
+ successful runtime and documentation checks on `master`.
115
+
116
+ The user guide and API reference use Sphinx with the Read the Docs theme.
117
+ Install the documentation extra and build the HTML and examples:
118
+
119
+ ```sh
120
+ python -m venv .venv
121
+ .venv/bin/python -m pip install -e '.[docs]'
122
+ make docs PYTHON=.venv/bin/python
123
+ make docs-test PYTHON=.venv/bin/python
124
+ ```
125
+
126
+ Use the same Python for dependency installation and Makefile targets; the
127
+ `docs` extra includes MyST and the theme. Open `build/docs/html/index.html`. See [the guide](docs/index.rst) for raw and
128
+ persistent execution, manifests, projects, schedulers, remote execution and the
129
+ CLI; [development](docs/development.rst) covers builds and releases. Generated
130
+ API pages and HTML are not committed. CI validates documentation against the
131
+ installed wheel and uploads the HTML artifact. The separate documentation
132
+ workflow checks the same wheel and documentation, omits the runtime test
133
+ matrices, and deploys to GitHub Pages for `v*` tags or manual runs. Enable
134
+ **Settings → Pages → Build and deployment → GitHub Actions** and allow release
135
+ tags and manually selected source branches in the `github-pages` environment
136
+ deployment rules.
137
+
138
+ Source provenance is recorded in [development remarks](docs/remarks/source-provenance.md);
139
+ the license is in [LICENCE](LICENCE).
@@ -0,0 +1,8 @@
1
+ {{ fullname | escape | underline }}
2
+
3
+ .. currentmodule:: {{ module }}
4
+
5
+ .. autoclass:: {{ objname }}
6
+ :members:
7
+ :undoc-members:
8
+ :show-inheritance:
@@ -0,0 +1,5 @@
1
+ {{ fullname | escape | underline }}
2
+
3
+ .. currentmodule:: {{ module }}
4
+
5
+ .. autofunction:: {{ objname }}
@@ -0,0 +1,141 @@
1
+ API reference
2
+ ===============
3
+
4
+ The root package provides backend-independent entry points for ordinary runs.
5
+ Choose executors from :mod:`kkrunner.backends` or :mod:`kkrunner.remote`; projects,
6
+ file manifests and advanced run contracts have their own public subpackages.
7
+ These import paths are independent of the modules implementing each type.
8
+
9
+ Common entry points
10
+ ----------------------
11
+
12
+ .. py:module:: kkrunner
13
+
14
+ .. currentmodule:: kkrunner
15
+
16
+ .. autosummary::
17
+ :toctree: _generated
18
+
19
+ ExecutionSpec
20
+ ExecutionOutcome
21
+ RunManager
22
+ RunStore
23
+ RunState
24
+ TaskFile
25
+ ProcessingPending
26
+
27
+ Execution contracts and durable records
28
+ -----------------------------------------
29
+
30
+ .. py:module:: kkrunner.runs
31
+
32
+ .. currentmodule:: kkrunner.runs
33
+
34
+ .. autosummary::
35
+ :toctree: _generated
36
+
37
+ LaunchSpec
38
+ MpiSpec
39
+ MpiNotFoundWarning
40
+ RunStatus
41
+ FailurePhase
42
+ Runner
43
+ BackendRunner
44
+ ManagedRunner
45
+ Executor
46
+ PersistentRunner
47
+ RunRecord
48
+ CorruptRunRecord
49
+ DuplicateSubmissionError
50
+ HistoricalFileMismatchError
51
+ Execution
52
+ WorkingDirectory
53
+
54
+ Declared files and identity
55
+ -----------------------------
56
+
57
+ .. py:module:: kkrunner.files
58
+
59
+ .. currentmodule:: kkrunner.files
60
+
61
+ .. autosummary::
62
+ :toctree: _generated
63
+
64
+ FileEntry
65
+ CacheEntry
66
+ FileMapping
67
+ FileManifest
68
+ FileSyncPolicy
69
+ ArtifactAvailabilityState
70
+ FileFingerprint
71
+ FileState
72
+ FileVersion
73
+ FileVersionCaptureError
74
+
75
+ Execution backends
76
+ ---------------------
77
+
78
+ .. py:module:: kkrunner.backends
79
+
80
+ .. currentmodule:: kkrunner.backends
81
+
82
+ .. autosummary::
83
+ :toctree: _generated
84
+
85
+ LocalExecutor
86
+ PsijExecutor
87
+ ExecutorEndpoint
88
+ ExecutorPool
89
+ default_executor_pool
90
+
91
+ Remote execution and transport
92
+ --------------------------------
93
+
94
+ .. py:module:: kkrunner.remote
95
+
96
+ .. currentmodule:: kkrunner.remote
97
+
98
+ .. autosummary::
99
+ :toctree: _generated
100
+
101
+ RemoteEndpointExecutor
102
+ Transport
103
+ RunningCommand
104
+ LocalTransport
105
+ SshTransport
106
+
107
+ Projects
108
+ ----------
109
+
110
+ .. py:module:: kkrunner.projects
111
+
112
+ .. currentmodule:: kkrunner.projects
113
+
114
+ .. autosummary::
115
+ :toctree: _generated
116
+
117
+ Project
118
+ ProjectRepository
119
+ ProjectRepositoryError
120
+ ProjectConflictError
121
+ ProjectDeleteError
122
+ ProjectExecutionManager
123
+ default_projects_directory
124
+
125
+ Backend implementation interfaces
126
+ ------------------------------------
127
+
128
+ These modules expose lower-level runner implementations and resource ownership
129
+ helpers for backend authors. They are not re-exported by the public facades.
130
+
131
+ .. currentmodule:: kkrunner
132
+
133
+ .. autosummary::
134
+ :toctree: _generated
135
+
136
+ backends.local.LocalRunner
137
+ backends.psij.PsijRunner
138
+ remote.runner.RemoteRunner
139
+ runs.processing.PostprocessingRunner
140
+ runs.base.ExecutionResources
141
+ runs.base.ResourceOwnedRunner