runnable 0.17.1__tar.gz → 0.19.0__tar.gz

Sign up to get free protection for your applications and to get access to all the features.
Files changed (248) hide show
  1. {runnable-0.17.1 → runnable-0.19.0}/PKG-INFO +1 -7
  2. runnable-0.19.0/extensions/catalog/pyproject.toml +14 -0
  3. {runnable-0.17.1 → runnable-0.19.0}/extensions/job_executor/k8s.py +148 -26
  4. runnable-0.19.0/extensions/job_executor/pyproject.toml +16 -0
  5. runnable-0.19.0/extensions/nodes/pyproject.toml +15 -0
  6. {runnable-0.17.1 → runnable-0.19.0}/extensions/pipeline_executor/local_container.py +0 -1
  7. runnable-0.19.0/extensions/pipeline_executor/pyproject.toml +16 -0
  8. runnable-0.19.0/extensions/run_log_store/pyproject.toml +15 -0
  9. runnable-0.19.0/extensions/secrets/pyproject.toml +15 -0
  10. {runnable-0.17.1 → runnable-0.19.0}/pyproject.toml +26 -15
  11. {runnable-0.17.1 → runnable-0.19.0}/runnable/__init__.py +1 -0
  12. {runnable-0.17.1 → runnable-0.19.0}/runnable/catalog.py +1 -2
  13. {runnable-0.17.1 → runnable-0.19.0}/runnable/entrypoints.py +1 -5
  14. {runnable-0.17.1 → runnable-0.19.0}/runnable/executor.py +1 -1
  15. {runnable-0.17.1 → runnable-0.19.0}/runnable/parameters.py +0 -9
  16. {runnable-0.17.1 → runnable-0.19.0}/runnable/utils.py +5 -25
  17. runnable-0.17.1/.dockerignore +0 -10
  18. runnable-0.17.1/.github/workflows/docs.yaml +0 -18
  19. runnable-0.17.1/.github/workflows/pr.yaml +0 -53
  20. runnable-0.17.1/.github/workflows/release.yaml +0 -101
  21. runnable-0.17.1/.mypy.ini +0 -48
  22. runnable-0.17.1/.pre-commit-config.yaml +0 -34
  23. runnable-0.17.1/.python-version +0 -1
  24. runnable-0.17.1/CHANGELOG.md +0 -1897
  25. runnable-0.17.1/Dockerfile +0 -22
  26. runnable-0.17.1/docs/assets/cropped.png +0 -0
  27. runnable-0.17.1/docs/assets/screenshots/argo-expose-parameters.png +0 -0
  28. runnable-0.17.1/docs/assets/screenshots/argo-kubeflow-exec.png +0 -0
  29. runnable-0.17.1/docs/assets/screenshots/argo-kubeflow-ui.png +0 -0
  30. runnable-0.17.1/docs/assets/screenshots/argo-nested.png +0 -0
  31. runnable-0.17.1/docs/assets/screenshots/argo-parallel-map.png +0 -0
  32. runnable-0.17.1/docs/assets/screenshots/argo-sequential-map.png +0 -0
  33. runnable-0.17.1/docs/assets/screenshots/argo-workflows-gant.png +0 -0
  34. runnable-0.17.1/docs/assets/screenshots/argo-workflows-logs.png +0 -0
  35. runnable-0.17.1/docs/assets/screenshots/mlflow.png +0 -0
  36. runnable-0.17.1/docs/assets/screenshots/mlflow_example.png +0 -0
  37. runnable-0.17.1/docs/assets/screenshots/mlflow_step.png +0 -0
  38. runnable-0.17.1/docs/assets/screenshots/notebook_api_parameters.png +0 -0
  39. runnable-0.17.1/docs/assets/screenshots/notebook_env_parameters.png +0 -0
  40. runnable-0.17.1/docs/assets/screenshots/notebook_input_parameters.png +0 -0
  41. runnable-0.17.1/docs/assets/screenshots/notebook_native_parameters.png +0 -0
  42. runnable-0.17.1/docs/assets/screenshots/simple_notebook.png +0 -0
  43. runnable-0.17.1/docs/assets/speed.png +0 -0
  44. runnable-0.17.1/docs/assets/sport.png +0 -0
  45. runnable-0.17.1/docs/assets/work_dark.png +0 -0
  46. runnable-0.17.1/docs/assets/work_light.png +0 -0
  47. runnable-0.17.1/docs/concepts/catalog.md +0 -87
  48. runnable-0.17.1/docs/concepts/index.md +0 -55
  49. runnable-0.17.1/docs/concepts/map.md +0 -227
  50. runnable-0.17.1/docs/concepts/nesting.md +0 -1354
  51. runnable-0.17.1/docs/concepts/parallel.md +0 -134
  52. runnable-0.17.1/docs/concepts/parameters.md +0 -255
  53. runnable-0.17.1/docs/concepts/pipeline.md +0 -176
  54. runnable-0.17.1/docs/concepts/run-log.md +0 -144
  55. runnable-0.17.1/docs/concepts/secrets.md +0 -69
  56. runnable-0.17.1/docs/concepts/task.md +0 -146
  57. runnable-0.17.1/docs/configurations/catalog.md +0 -279
  58. runnable-0.17.1/docs/configurations/executors/argo.md +0 -1650
  59. runnable-0.17.1/docs/configurations/executors/container-environments.md +0 -71
  60. runnable-0.17.1/docs/configurations/executors/local-container.md +0 -352
  61. runnable-0.17.1/docs/configurations/executors/local.md +0 -17
  62. runnable-0.17.1/docs/configurations/executors/mocked.md +0 -1015
  63. runnable-0.17.1/docs/configurations/overview.md +0 -80
  64. runnable-0.17.1/docs/configurations/run-log.md +0 -427
  65. runnable-0.17.1/docs/configurations/secrets.md +0 -140
  66. runnable-0.17.1/docs/css/extra.css +0 -3
  67. runnable-0.17.1/docs/index.md +0 -190
  68. runnable-0.17.1/docs/iterative.md +0 -44
  69. runnable-0.17.1/docs/reference.md +0 -146
  70. runnable-0.17.1/docs/tutorial/overview.md +0 -0
  71. runnable-0.17.1/docs/tutorial/script-based.md +0 -0
  72. runnable-0.17.1/docs/tutorial/single-notebook.md +0 -0
  73. runnable-0.17.1/docs/tutorial/switching-configs.md +0 -0
  74. runnable-0.17.1/docs/tutorial/using-parallel.md +0 -0
  75. runnable-0.17.1/docs/tutorial/wrap-up.md +0 -0
  76. runnable-0.17.1/docs/usage.md +0 -56
  77. runnable-0.17.1/docs/why-runnable.md +0 -104
  78. runnable-0.17.1/examples/01-tasks/notebook.py +0 -44
  79. runnable-0.17.1/examples/01-tasks/notebook.yaml +0 -31
  80. runnable-0.17.1/examples/01-tasks/python_tasks.py +0 -43
  81. runnable-0.17.1/examples/01-tasks/python_tasks.yaml +0 -23
  82. runnable-0.17.1/examples/01-tasks/scripts.py +0 -37
  83. runnable-0.17.1/examples/01-tasks/scripts.yaml +0 -20
  84. runnable-0.17.1/examples/01-tasks/stub.py +0 -42
  85. runnable-0.17.1/examples/01-tasks/stub.yaml +0 -29
  86. runnable-0.17.1/examples/02-sequential/default_fail.py +0 -36
  87. runnable-0.17.1/examples/02-sequential/default_fail.yaml +0 -23
  88. runnable-0.17.1/examples/02-sequential/on_failure_fail.py +0 -43
  89. runnable-0.17.1/examples/02-sequential/on_failure_fail.yaml +0 -34
  90. runnable-0.17.1/examples/02-sequential/on_failure_succeed.py +0 -44
  91. runnable-0.17.1/examples/02-sequential/on_failure_succeed.yaml +0 -34
  92. runnable-0.17.1/examples/02-sequential/traversal.py +0 -65
  93. runnable-0.17.1/examples/02-sequential/traversal.yaml +0 -46
  94. runnable-0.17.1/examples/03-parameters/passing_parameters_notebook.py +0 -59
  95. runnable-0.17.1/examples/03-parameters/passing_parameters_notebook.yaml +0 -38
  96. runnable-0.17.1/examples/03-parameters/passing_parameters_python.py +0 -55
  97. runnable-0.17.1/examples/03-parameters/passing_parameters_python.yaml +0 -38
  98. runnable-0.17.1/examples/03-parameters/passing_parameters_shell.py +0 -73
  99. runnable-0.17.1/examples/03-parameters/passing_parameters_shell.yaml +0 -51
  100. runnable-0.17.1/examples/03-parameters/static_parameters_non_python.py +0 -61
  101. runnable-0.17.1/examples/03-parameters/static_parameters_non_python.yaml +0 -46
  102. runnable-0.17.1/examples/03-parameters/static_parameters_python.py +0 -77
  103. runnable-0.17.1/examples/03-parameters/static_parameters_python.yaml +0 -33
  104. runnable-0.17.1/examples/04-catalog/catalog.py +0 -131
  105. runnable-0.17.1/examples/04-catalog/catalog.yaml +0 -115
  106. runnable-0.17.1/examples/06-parallel/nesting.py +0 -87
  107. runnable-0.17.1/examples/06-parallel/nesting.yaml +0 -50
  108. runnable-0.17.1/examples/06-parallel/parallel.py +0 -66
  109. runnable-0.17.1/examples/06-parallel/parallel.yaml +0 -45
  110. runnable-0.17.1/examples/07-map/custom_reducer.py +0 -129
  111. runnable-0.17.1/examples/07-map/custom_reducer.yaml +0 -73
  112. runnable-0.17.1/examples/07-map/map.py +0 -133
  113. runnable-0.17.1/examples/07-map/map.yaml +0 -74
  114. runnable-0.17.1/examples/08-mocking/default.yaml +0 -13
  115. runnable-0.17.1/examples/08-mocking/patching.yaml +0 -19
  116. runnable-0.17.1/examples/09-retry/config.yaml +0 -4
  117. runnable-0.17.1/examples/09-retry/python_tasks.py +0 -60
  118. runnable-0.17.1/examples/09-retry/python_tasks.yaml +0 -33
  119. runnable-0.17.1/examples/11-jobs/catalog.py +0 -23
  120. runnable-0.17.1/examples/11-jobs/catalog.yaml +0 -5
  121. runnable-0.17.1/examples/11-jobs/k8s-job.yaml +0 -41
  122. runnable-0.17.1/examples/11-jobs/local-container.yaml +0 -4
  123. runnable-0.17.1/examples/11-jobs/notebook.yaml +0 -3
  124. runnable-0.17.1/examples/11-jobs/passing_parameters_python.py +0 -47
  125. runnable-0.17.1/examples/11-jobs/python_parameters.yaml +0 -11
  126. runnable-0.17.1/examples/11-jobs/python_tasks.py +0 -44
  127. runnable-0.17.1/examples/11-jobs/python_tasks.yaml +0 -2
  128. runnable-0.17.1/examples/11-jobs/scripts.yaml +0 -20
  129. runnable-0.17.1/examples/Dockerfile.39 +0 -31
  130. runnable-0.17.1/examples/README.md +0 -93
  131. runnable-0.17.1/examples/common/functions.py +0 -166
  132. runnable-0.17.1/examples/common/initial_parameters.yaml +0 -8
  133. runnable-0.17.1/examples/common/process_chunk.ipynb +0 -70
  134. runnable-0.17.1/examples/common/read_files.ipynb +0 -43
  135. runnable-0.17.1/examples/common/read_parameters.ipynb +0 -69
  136. runnable-0.17.1/examples/common/simple_notebook.ipynb +0 -46
  137. runnable-0.17.1/examples/common/simple_notebook_mocked.ipynb +0 -46
  138. runnable-0.17.1/examples/common/write_parameters.ipynb +0 -68
  139. runnable-0.17.1/examples/comparisons/README.md +0 -174
  140. runnable-0.17.1/examples/comparisons/kedro/README.md +0 -1
  141. runnable-0.17.1/examples/comparisons/kfp/README.md +0 -1
  142. runnable-0.17.1/examples/comparisons/metaflow/main.py +0 -135
  143. runnable-0.17.1/examples/comparisons/metaflow/parameters.json +0 -46
  144. runnable-0.17.1/examples/comparisons/runnable/main.py +0 -291
  145. runnable-0.17.1/examples/comparisons/runnable/runnable_params.yaml +0 -41
  146. runnable-0.17.1/examples/comparisons/source.py +0 -202
  147. runnable-0.17.1/examples/configs/argo-config-full.yaml +0 -50
  148. runnable-0.17.1/examples/configs/argo-config.yaml +0 -18
  149. runnable-0.17.1/examples/configs/chunked-fs-run_log.yaml +0 -2
  150. runnable-0.17.1/examples/configs/default.yaml +0 -11
  151. runnable-0.17.1/examples/configs/dotenv.yaml +0 -4
  152. runnable-0.17.1/examples/configs/in-memory.yaml +0 -14
  153. runnable-0.17.1/examples/configs/local-container.yaml +0 -7
  154. runnable-0.17.1/examples/configs/mocked-config-debug.yaml +0 -12
  155. runnable-0.17.1/examples/configs/mocked-config-simple.yaml +0 -8
  156. runnable-0.17.1/examples/configs/mocked-config-unittest.yaml +0 -12
  157. runnable-0.17.1/examples/configs/mocked-config.yaml +0 -12
  158. runnable-0.17.1/examples/configs/mocked_map_parameters.yaml +0 -7
  159. runnable-0.17.1/examples/configs/retry-config.yaml +0 -10
  160. runnable-0.17.1/examples/executors/argo-map-sequential.yaml +0 -42
  161. runnable-0.17.1/examples/executors/local-container-override.yaml +0 -23
  162. runnable-0.17.1/examples/executors/step_overrides_container.py +0 -53
  163. runnable-0.17.1/examples/executors/step_overrides_container.yaml +0 -35
  164. runnable-0.17.1/examples/generated-argo-pipeline.yaml +0 -175
  165. runnable-0.17.1/examples/iris_demo.py +0 -102
  166. runnable-0.17.1/examples/tutorials/mnist/baseline_comparison.py +0 -312
  167. runnable-0.17.1/examples/tutorials/mnist/hyper_parameter_tuning.py +0 -206
  168. runnable-0.17.1/examples/tutorials/mnist/modular_source.py +0 -171
  169. runnable-0.17.1/examples/tutorials/mnist/parameters.yaml +0 -36
  170. runnable-0.17.1/examples/tutorials/mnist/parameters_source.py +0 -173
  171. runnable-0.17.1/examples/tutorials/mnist/source.py +0 -80
  172. runnable-0.17.1/examples/tutorials/reddit_text_classification/parameters.yaml +0 -9
  173. runnable-0.17.1/examples/tutorials/reddit_text_classification/pipeline.py +0 -60
  174. runnable-0.17.1/examples/tutorials/reddit_text_classification/steps.py +0 -131
  175. runnable-0.17.1/extensions/catalog/pyproject.toml +0 -7
  176. runnable-0.17.1/extensions/job_executor/pyproject.toml +0 -7
  177. runnable-0.17.1/extensions/nodes/pyproject.toml +0 -7
  178. runnable-0.17.1/extensions/pipeline_executor/pyproject.toml +0 -7
  179. runnable-0.17.1/extensions/run_log_store/pyproject.toml +0 -7
  180. runnable-0.17.1/extensions/secrets/__init__.py +0 -0
  181. runnable-0.17.1/extensions/secrets/pyproject.toml +0 -7
  182. runnable-0.17.1/mkdocs.yml +0 -140
  183. runnable-0.17.1/tests/__init__.py +0 -0
  184. runnable-0.17.1/tests/conftest.py +0 -11
  185. runnable-0.17.1/tests/extensions/__init__.py +0 -0
  186. runnable-0.17.1/tests/extensions/catalog/test_catalog_extension.py +0 -52
  187. runnable-0.17.1/tests/extensions/catalog/test_file_system.py +0 -312
  188. runnable-0.17.1/tests/extensions/pipeline_executor/test_argo_executor.py +0 -138
  189. runnable-0.17.1/tests/extensions/pipeline_executor/test_generic_executor.py +0 -558
  190. runnable-0.17.1/tests/extensions/pipeline_executor/test_local_executor.py +0 -14
  191. runnable-0.17.1/tests/extensions/run_log_store/__init__.py +0 -0
  192. runnable-0.17.1/tests/extensions/run_log_store/test_file_system.py +0 -155
  193. runnable-0.17.1/tests/extensions/secrets/test_dotenv.py +0 -17
  194. runnable-0.17.1/tests/extensions/test_node_extensions.py +0 -265
  195. runnable-0.17.1/tests/runnable/test_catalog.py +0 -61
  196. runnable-0.17.1/tests/runnable/test_datastore.py +0 -551
  197. runnable-0.17.1/tests/runnable/test_executor.py +0 -30
  198. runnable-0.17.1/tests/runnable/test_graph.py +0 -451
  199. runnable-0.17.1/tests/runnable/test_nodes.py +0 -439
  200. runnable-0.17.1/tests/runnable/test_parmeters.py +0 -131
  201. runnable-0.17.1/tests/runnable/test_sdk.py +0 -37
  202. runnable-0.17.1/tests/runnable/test_secrets.py +0 -33
  203. runnable-0.17.1/tests/runnable/test_utils.py +0 -453
  204. runnable-0.17.1/tests/test_examples.py +0 -210
  205. runnable-0.17.1/tox.ini +0 -19
  206. runnable-0.17.1/uv.lock +0 -2441
  207. {runnable-0.17.1 → runnable-0.19.0}/.gitignore +0 -0
  208. {runnable-0.17.1 → runnable-0.19.0}/LICENSE +0 -0
  209. {runnable-0.17.1 → runnable-0.19.0}/README.md +0 -0
  210. {runnable-0.17.1 → runnable-0.19.0}/extensions/README.md +0 -0
  211. {runnable-0.17.1 → runnable-0.19.0}/extensions/__init__.py +0 -0
  212. /runnable-0.17.1/CONTRIBUTING.md → /runnable-0.19.0/extensions/catalog/README.md +0 -0
  213. {runnable-0.17.1 → runnable-0.19.0}/extensions/catalog/file_system.py +0 -0
  214. /runnable-0.17.1/docs/architecture/yaml.md → /runnable-0.19.0/extensions/job_executor/README.md +0 -0
  215. {runnable-0.17.1 → runnable-0.19.0}/extensions/job_executor/__init__.py +0 -0
  216. {runnable-0.17.1 → runnable-0.19.0}/extensions/job_executor/k8s_job_spec.yaml +0 -0
  217. {runnable-0.17.1 → runnable-0.19.0}/extensions/job_executor/local.py +0 -0
  218. {runnable-0.17.1 → runnable-0.19.0}/extensions/job_executor/local_container.py +0 -0
  219. /runnable-0.17.1/docs/configurations/executors/retry.md → /runnable-0.19.0/extensions/nodes/README.md +0 -0
  220. {runnable-0.17.1 → runnable-0.19.0}/extensions/nodes/nodes.py +0 -0
  221. /runnable-0.17.1/docs/tutorial/dynamic-looping.md → /runnable-0.19.0/extensions/pipeline_executor/README.md +0 -0
  222. {runnable-0.17.1 → runnable-0.19.0}/extensions/pipeline_executor/__init__.py +0 -0
  223. {runnable-0.17.1 → runnable-0.19.0}/extensions/pipeline_executor/argo.py +0 -0
  224. {runnable-0.17.1 → runnable-0.19.0}/extensions/pipeline_executor/argo_specification.yaml +0 -0
  225. {runnable-0.17.1 → runnable-0.19.0}/extensions/pipeline_executor/local.py +0 -0
  226. {runnable-0.17.1 → runnable-0.19.0}/extensions/pipeline_executor/mocked.py +0 -0
  227. {runnable-0.17.1 → runnable-0.19.0}/extensions/pipeline_executor/retry.py +0 -0
  228. /runnable-0.17.1/docs/tutorial/modular-dags.md → /runnable-0.19.0/extensions/run_log_store/README.md +0 -0
  229. {runnable-0.17.1 → runnable-0.19.0}/extensions/run_log_store/__init__.py +0 -0
  230. {runnable-0.17.1 → runnable-0.19.0}/extensions/run_log_store/chunked_fs.py +0 -0
  231. {runnable-0.17.1 → runnable-0.19.0}/extensions/run_log_store/db/implementation_FF.py +0 -0
  232. {runnable-0.17.1 → runnable-0.19.0}/extensions/run_log_store/db/integration_FF.py +0 -0
  233. {runnable-0.17.1 → runnable-0.19.0}/extensions/run_log_store/file_system.py +0 -0
  234. {runnable-0.17.1 → runnable-0.19.0}/extensions/run_log_store/generic_chunked.py +0 -0
  235. /runnable-0.17.1/docs/tutorial/modular-notebooks.md → /runnable-0.19.0/extensions/secrets/README.md +0 -0
  236. {runnable-0.17.1 → runnable-0.19.0}/extensions/secrets/dotenv.py +0 -0
  237. {runnable-0.17.1 → runnable-0.19.0}/runnable/cli.py +0 -0
  238. {runnable-0.17.1 → runnable-0.19.0}/runnable/context.py +0 -0
  239. {runnable-0.17.1 → runnable-0.19.0}/runnable/datastore.py +0 -0
  240. {runnable-0.17.1 → runnable-0.19.0}/runnable/defaults.py +0 -0
  241. {runnable-0.17.1 → runnable-0.19.0}/runnable/exceptions.py +0 -0
  242. {runnable-0.17.1 → runnable-0.19.0}/runnable/graph.py +0 -0
  243. {runnable-0.17.1 → runnable-0.19.0}/runnable/names.py +0 -0
  244. {runnable-0.17.1 → runnable-0.19.0}/runnable/nodes.py +0 -0
  245. {runnable-0.17.1 → runnable-0.19.0}/runnable/pickler.py +0 -0
  246. {runnable-0.17.1 → runnable-0.19.0}/runnable/sdk.py +0 -0
  247. {runnable-0.17.1 → runnable-0.19.0}/runnable/secrets.py +0 -0
  248. {runnable-0.17.1 → runnable-0.19.0}/runnable/tasks.py +0 -0
@@ -1,23 +1,17 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: runnable
3
- Version: 0.17.1
3
+ Version: 0.19.0
4
4
  Summary: Add your description here
5
5
  Author-email: "Vammi, Vijay" <vijay.vammi@astrazeneca.com>
6
6
  License-File: LICENSE
7
7
  Requires-Python: >=3.10
8
- Requires-Dist: catalog
9
8
  Requires-Dist: click-plugins>=1.1.1
10
9
  Requires-Dist: click<=8.1.3
11
10
  Requires-Dist: dill>=0.3.9
12
- Requires-Dist: job-executor
13
- Requires-Dist: nodes
14
- Requires-Dist: pipeline-executor
15
11
  Requires-Dist: pydantic>=2.10.3
16
12
  Requires-Dist: python-dotenv>=1.0.1
17
13
  Requires-Dist: rich>=13.9.4
18
14
  Requires-Dist: ruamel-yaml>=0.18.6
19
- Requires-Dist: run-log-store
20
- Requires-Dist: secrets
21
15
  Requires-Dist: setuptools>=75.6.0
22
16
  Requires-Dist: stevedore>=5.4.0
23
17
  Requires-Dist: typer>=0.15.1
@@ -0,0 +1,14 @@
1
+ [project]
2
+ name = "catalog"
3
+ version = "0.0.0"
4
+ description = "Add your description here"
5
+ readme = "README.md"
6
+ requires-python = ">=3.10"
7
+ dependencies = []
8
+
9
+ [build-system]
10
+ requires = ["hatchling"]
11
+ build-backend = "hatchling.build"
12
+
13
+ [tool.hatch.build.targets.wheel]
14
+ packages = ["."]
@@ -101,23 +101,40 @@ class HostPath(BaseModel):
101
101
  path: str
102
102
 
103
103
 
104
- class Volume(BaseModel):
104
+ class HostPathVolume(BaseModel):
105
105
  name: str
106
106
  host_path: HostPath
107
107
 
108
108
 
109
- class TemplateSpec(BaseModel):
109
+ class PVCClaim(BaseModel):
110
+ claim_name: str
111
+
112
+ model_config = ConfigDict(
113
+ alias_generator=to_camel,
114
+ populate_by_name=True,
115
+ from_attributes=True,
116
+ )
117
+
118
+
119
+ class PVCVolume(BaseModel):
120
+ name: str
121
+ persistent_volume_claim: PVCClaim
122
+
123
+
124
+ class K8sTemplateSpec(BaseModel):
110
125
  active_deadline_seconds: int = Field(default=60 * 60 * 2) # 2 hours
111
126
  node_selector: Optional[dict[str, str]] = None
112
127
  tolerations: Optional[list[dict[str, str]]] = None
113
- volumes: Optional[list[Volume]] = Field(default_factory=lambda: [])
128
+ volumes: Optional[list[HostPathVolume | PVCVolume]] = Field(
129
+ default_factory=lambda: []
130
+ )
114
131
  service_account_name: Optional[str] = "default"
115
132
  restart_policy: RestartPolicy = RestartPolicy.NEVER
116
133
  container: Container
117
134
 
118
135
 
119
- class Template(BaseModel):
120
- spec: TemplateSpec
136
+ class K8sTemplate(BaseModel):
137
+ spec: K8sTemplateSpec
121
138
  metadata: Optional[ObjectMetaData] = None
122
139
 
123
140
 
@@ -125,32 +142,25 @@ class Spec(BaseModel):
125
142
  active_deadline_seconds: Optional[int] = Field(default=60 * 60 * 2) # 2 hours
126
143
  backoff_limit: int = 6
127
144
  selector: Optional[LabelSelector] = None
128
- template: Template
145
+ template: K8sTemplate
129
146
  ttl_seconds_after_finished: Optional[int] = Field(default=60 * 60 * 24) # 24 hours
130
147
 
131
148
 
132
- class K8sJobExecutor(GenericJobExecutor):
149
+ class GenericK8sJobExecutor(GenericJobExecutor):
133
150
  service_name: str = "k8s-job"
134
151
  config_path: Optional[str] = None
135
152
  job_spec: Spec
136
153
  mock: bool = False
137
-
138
- # The location the mount of .run_log_store is mounted to in minikube
139
- # ensure that minikube mount $HOME/workspace/runnable/.run_log_store:/volume/run_logs is executed first
140
- # $HOME/workspace/runnable/.catalog:/volume/catalog
141
- # Ensure that the docker build is done with eval $(minikube docker-env)
142
- mini_k8s_run_log_location: str = Field(default="/volume/run_logs/")
143
- mini_k8s_catalog_location: str = Field(default="/volume/catalog/")
154
+ namespace: str = Field(default="default")
144
155
 
145
156
  _is_local: bool = PrivateAttr(default=False)
157
+ _volume_mounts: list[VolumeMount] = PrivateAttr(default_factory=lambda: [])
158
+ _volumes: list[HostPathVolume | PVCVolume] = PrivateAttr(default_factory=lambda: [])
146
159
 
147
160
  _container_log_location: str = PrivateAttr(default="/tmp/run_logs/")
148
161
  _container_catalog_location: str = PrivateAttr(default="/tmp/catalog/")
149
162
  _container_secrets_location: str = PrivateAttr(default="/tmp/dotenv")
150
163
 
151
- _volumes: list[Volume] = []
152
- _volume_mounts: list[VolumeMount] = []
153
-
154
164
  model_config = ConfigDict(
155
165
  alias_generator=to_camel,
156
166
  populate_by_name=True,
@@ -287,14 +297,17 @@ class K8sJobExecutor(GenericJobExecutor):
287
297
  )
288
298
 
289
299
  logger.info(f"Submitting job: {job.__dict__}")
300
+ if self.mock:
301
+ print(job.__dict__)
302
+ return
290
303
 
291
304
  try:
292
305
  k8s_batch = self._client.BatchV1Api()
293
306
  response = k8s_batch.create_namespaced_job(
294
307
  body=job,
295
- namespace="default",
296
308
  _preload_content=False,
297
309
  pretty=True,
310
+ namespace=self.namespace,
298
311
  )
299
312
  logger.debug(f"Kubernetes job response: {response}")
300
313
  except Exception as e:
@@ -302,6 +315,43 @@ class K8sJobExecutor(GenericJobExecutor):
302
315
  print(e)
303
316
  raise
304
317
 
318
+ def _create_volumes(self): ...
319
+
320
+ def _use_volumes(self):
321
+ match self._context.run_log_store.service_name:
322
+ case "file-system":
323
+ self._context.run_log_store.log_folder = self._container_log_location
324
+ case "chunked-fs":
325
+ self._context.run_log_store.log_folder = self._container_log_location
326
+
327
+ match self._context.catalog_handler.service_name:
328
+ case "file-system":
329
+ self._context.catalog_handler.catalog_location = (
330
+ self._container_catalog_location
331
+ )
332
+
333
+
334
+ class MiniK8sJobExecutor(GenericK8sJobExecutor):
335
+ service_name: str = "k8s-job"
336
+ config_path: Optional[str] = None
337
+ job_spec: Spec
338
+ mock: bool = False
339
+
340
+ # The location the mount of .run_log_store is mounted to in minikube
341
+ # ensure that minikube mount $HOME/workspace/runnable/.run_log_store:/volume/run_logs is executed first
342
+ # $HOME/workspace/runnable/.catalog:/volume/catalog
343
+ # Ensure that the docker build is done with eval $(minikube docker-env)
344
+ mini_k8s_run_log_location: str = Field(default="/volume/run_logs/")
345
+ mini_k8s_catalog_location: str = Field(default="/volume/catalog/")
346
+
347
+ _is_local: bool = PrivateAttr(default=False)
348
+
349
+ model_config = ConfigDict(
350
+ alias_generator=to_camel,
351
+ populate_by_name=True,
352
+ from_attributes=True,
353
+ )
354
+
305
355
  def _create_volumes(self):
306
356
  match self._context.run_log_store.service_name:
307
357
  case "file-system":
@@ -311,7 +361,7 @@ class K8sJobExecutor(GenericJobExecutor):
311
361
  # You then are creating a volume that is mounted to /tmp/run_logs in the container
312
362
  # You are then referring to it.
313
363
  # https://stackoverflow.com/questions/57411456/minikube-mounted-host-folders-are-not-working
314
- Volume(
364
+ HostPathVolume(
315
365
  name="run-logs",
316
366
  host_path=HostPath(path=self.mini_k8s_run_log_location),
317
367
  )
@@ -323,7 +373,7 @@ class K8sJobExecutor(GenericJobExecutor):
323
373
  )
324
374
  case "chunked-fs":
325
375
  self._volumes.append(
326
- Volume(
376
+ HostPathVolume(
327
377
  name="run-logs",
328
378
  host_path=HostPath(path=self.mini_k8s_run_log_location),
329
379
  )
@@ -337,7 +387,7 @@ class K8sJobExecutor(GenericJobExecutor):
337
387
  match self._context.catalog_handler.service_name:
338
388
  case "file-system":
339
389
  self._volumes.append(
340
- Volume(
390
+ HostPathVolume(
341
391
  name="catalog",
342
392
  host_path=HostPath(path=self.mini_k8s_catalog_location),
343
393
  )
@@ -348,15 +398,87 @@ class K8sJobExecutor(GenericJobExecutor):
348
398
  )
349
399
  )
350
400
 
351
- def _use_volumes(self):
401
+
402
+ class K8sJobExecutor(GenericK8sJobExecutor):
403
+ service_name: str = "k8s-job"
404
+ config_path: Optional[str] = None
405
+ job_spec: Spec
406
+ mock: bool = False
407
+ pvc_claim_name: str
408
+
409
+ # change the spec to pull image if not present
410
+ def model_post_init(self, __context):
411
+ self.job_spec.template.spec.container.image_pull_policy = ImagePullPolicy.ALWAYS
412
+
413
+ _is_local: bool = PrivateAttr(default=False)
414
+
415
+ model_config = ConfigDict(
416
+ alias_generator=to_camel,
417
+ populate_by_name=True,
418
+ from_attributes=True,
419
+ )
420
+
421
+ def execute_job(self, job: BaseTaskType, catalog_settings=Optional[List[str]]):
422
+ self._use_volumes()
423
+ self._set_up_run_log()
424
+
425
+ job_log = self._context.run_log_store.create_job_log()
426
+ self._context.run_log_store.add_job_log(
427
+ run_id=self._context.run_id, job_log=job_log
428
+ )
429
+
430
+ job_log = self._context.run_log_store.get_job_log(run_id=self._context.run_id)
431
+
432
+ attempt_log = job.execute_command(
433
+ attempt_number=self.step_attempt_number,
434
+ mock=self.mock,
435
+ )
436
+
437
+ job_log.status = attempt_log.status
438
+ job_log.attempts.append(attempt_log)
439
+
440
+ data_catalogs_put: Optional[List[DataCatalog]] = self._sync_catalog(
441
+ catalog_settings=catalog_settings
442
+ )
443
+ logger.debug(f"data_catalogs_put: {data_catalogs_put}")
444
+
445
+ job_log.add_data_catalogs(data_catalogs_put or [])
446
+
447
+ console.print("Summary of job")
448
+ console.print(job_log.get_summary())
449
+
450
+ self._context.run_log_store.add_job_log(
451
+ run_id=self._context.run_id, job_log=job_log
452
+ )
453
+
454
+ def _create_volumes(self):
455
+ self._volumes.append(
456
+ PVCVolume(
457
+ name=self.pvc_claim_name,
458
+ persistent_volume_claim=PVCClaim(claim_name=self.pvc_claim_name),
459
+ )
460
+ )
352
461
  match self._context.run_log_store.service_name:
353
462
  case "file-system":
354
- self._context.run_log_store.log_folder = self._container_log_location
463
+ self._volume_mounts.append(
464
+ VolumeMount(
465
+ name=self.pvc_claim_name,
466
+ mount_path=self._container_log_location,
467
+ )
468
+ )
355
469
  case "chunked-fs":
356
- self._context.run_log_store.log_folder = self._container_log_location
470
+ self._volume_mounts.append(
471
+ VolumeMount(
472
+ name=self.pvc_claim_name,
473
+ mount_path=self._container_log_location,
474
+ )
475
+ )
357
476
 
358
477
  match self._context.catalog_handler.service_name:
359
478
  case "file-system":
360
- self._context.catalog_handler.catalog_location = (
361
- self._container_catalog_location
479
+ self._volume_mounts.append(
480
+ VolumeMount(
481
+ name=self.pvc_claim_name,
482
+ mount_path=self._container_catalog_location,
483
+ )
362
484
  )
@@ -0,0 +1,16 @@
1
+ [project]
2
+ name = "job_executor"
3
+ version = "0.0.0"
4
+ description = "Add your description here"
5
+ readme = "README.md"
6
+ requires-python = ">=3.10"
7
+ dependencies = []
8
+
9
+
10
+ [build-system]
11
+ requires = ["hatchling"]
12
+ build-backend = "hatchling.build"
13
+
14
+
15
+ [tool.hatch.build.targets.wheel]
16
+ packages = ["."]
@@ -0,0 +1,15 @@
1
+ [project]
2
+ name = "nodes"
3
+ version = "0.0.0"
4
+ description = "Add your description here"
5
+ readme = "README.md"
6
+ requires-python = ">=3.10"
7
+ dependencies = []
8
+
9
+
10
+ [build-system]
11
+ requires = ["hatchling"]
12
+ build-backend = "hatchling.build"
13
+
14
+ [tool.hatch.build.targets.wheel]
15
+ packages = ["."]
@@ -268,7 +268,6 @@ class LocalContainerExecutor(GenericPipelineExecutor):
268
268
  f"Please provide a docker_image using executor_config of the step {node.name} or at global config"
269
269
  )
270
270
 
271
- # TODO: Should consider using getpass.getuser() when running the docker container? Volume permissions
272
271
  container = client.containers.create(
273
272
  image=docker_image,
274
273
  command=command,
@@ -0,0 +1,16 @@
1
+ [project]
2
+ name = "pipeline_executor"
3
+ version = "0.0.0"
4
+ description = "Add your description here"
5
+ readme = "README.md"
6
+ requires-python = ">=3.10"
7
+ dependencies = []
8
+
9
+
10
+ [build-system]
11
+ requires = ["hatchling"]
12
+ build-backend = "hatchling.build"
13
+
14
+
15
+ [tool.hatch.build.targets.wheel]
16
+ packages = ["."]
@@ -0,0 +1,15 @@
1
+ [project]
2
+ name = "run_log_store"
3
+ version = "0.0.0"
4
+ description = "Extensions to run log store"
5
+ readme = "README.md"
6
+ requires-python = ">=3.10"
7
+ dependencies = []
8
+
9
+
10
+ [build-system]
11
+ requires = ["hatchling"]
12
+ build-backend = "hatchling.build"
13
+
14
+ [tool.hatch.build.targets.wheel]
15
+ packages = ["."]
@@ -0,0 +1,15 @@
1
+ [project]
2
+ name = "secrets"
3
+ version = "0.0.0"
4
+ description = "Extension to manage secrets"
5
+ readme = "README.md"
6
+ requires-python = ">=3.10"
7
+ dependencies = []
8
+
9
+
10
+ [build-system]
11
+ requires = ["hatchling"]
12
+ build-backend = "hatchling.build"
13
+
14
+ [tool.hatch.build.targets.wheel]
15
+ packages = ["."]
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "runnable"
3
- version = "0.17.1"
3
+ version = "0.19.0"
4
4
  description = "Add your description here"
5
5
  readme = "README.md"
6
6
  authors = [
@@ -18,17 +18,8 @@ dependencies = [
18
18
  "setuptools>=75.6.0",
19
19
  "python-dotenv>=1.0.1",
20
20
  "typer>=0.15.1",
21
- "nodes",
22
- "secrets",
23
- "catalog",
24
- "run_log_store",
25
- "pipeline_executor",
26
- "job_executor",
27
21
  ]
28
22
 
29
- [project.scripts]
30
- runnable = 'runnable.cli:app'
31
-
32
23
  [project.optional-dependencies]
33
24
  docker = [
34
25
  "docker>=7.1.0",
@@ -43,10 +34,6 @@ k8s = [
43
34
  "kubernetes>=31.0.0",
44
35
  ]
45
36
 
46
- [build-system]
47
- requires = ["hatchling"]
48
- build-backend = "hatchling.build"
49
-
50
37
  [dependency-groups]
51
38
  dev = [
52
39
  "pytest-cov>=6.0.0",
@@ -68,7 +55,13 @@ release = [
68
55
  ]
69
56
 
70
57
  [tool.uv.workspace]
71
- members = ["extensions/*"]
58
+ members = ["extensions/catalog",
59
+ "extensions/job_executor",
60
+ "extensions/nodes",
61
+ "extensions/pipeline_executor",
62
+ "extensions/run_log_store",
63
+ "extensions/secrets",
64
+ ]
72
65
 
73
66
  [tool.uv.sources]
74
67
  nodes = {workspace = true}
@@ -79,6 +72,22 @@ pipeline_executor = {workspace = true}
79
72
  job_executor = {workspace = true}
80
73
 
81
74
 
75
+ [project.scripts]
76
+ runnable = 'runnable.cli:app'
77
+
78
+ [build-system]
79
+ requires = ["hatchling"]
80
+ build-backend = "hatchling.build"
81
+
82
+ [tool.hatch.build]
83
+ ignore-vcs = true
84
+ include = [
85
+ "/runnable",
86
+ "/extensions",
87
+ ]
88
+
89
+
90
+ # Plugin systems
82
91
  [project.entry-points.'pipeline_executor']
83
92
  "local" = "extensions.pipeline_executor.local:LocalExecutor"
84
93
  "local-container" = "extensions.pipeline_executor.local_container:LocalContainerExecutor"
@@ -89,6 +98,7 @@ job_executor = {workspace = true}
89
98
  [project.entry-points.'job_executor']
90
99
  "local" = "extensions.job_executor.local:LocalJobExecutor"
91
100
  "local-container" = "extensions.job_executor.local_container:LocalContainerJobExecutor"
101
+ "mini-k8s-job" = "extensions.job_executor.k8s:MiniK8sJobExecutor"
92
102
  "k8s-job" = "extensions.job_executor.k8s:K8sJobExecutor"
93
103
  # "argo" = "extensions.pipeline_executor.argo:ArgoExecutor"
94
104
  # "mocked" = "extensions.pipeline_executor.mocked:MockedExecutor"
@@ -127,6 +137,7 @@ file-system = "extensions.run_log_store.file_system:FileSystemRunLogstore"
127
137
  "notebook" = "runnable.tasks:NotebookTaskType"
128
138
 
129
139
 
140
+ # Release configuration
130
141
  [tool.semantic_release]
131
142
  commit_parser = "angular"
132
143
  major_on_zero = true
@@ -1,5 +1,6 @@
1
1
  # ruff: noqa
2
2
 
3
+
3
4
  import logging
4
5
  import os
5
6
  from logging.config import dictConfig
@@ -10,8 +10,6 @@ from runnable.datastore import DataCatalog
10
10
 
11
11
  logger = logging.getLogger(defaults.LOGGER_NAME)
12
12
 
13
- # TODO: Should ** be allowed as glob pattern as it can potentially copy everything to catalog
14
-
15
13
 
16
14
  def is_catalog_out_of_sync(
17
15
  catalog, synced_catalogs=Optional[List[DataCatalog]]
@@ -170,3 +168,4 @@ class DoNothingCatalog(BaseCatalog):
170
168
  Does nothing
171
169
  """
172
170
  logger.info("Using a do-nothing catalog, doing nothing while sync between runs")
171
+ logger.info("Using a do-nothing catalog, doing nothing while sync between runs")
@@ -16,9 +16,6 @@ from runnable.executor import BaseJobExecutor, BasePipelineExecutor
16
16
  logger = logging.getLogger(defaults.LOGGER_NAME)
17
17
 
18
18
 
19
- print("") # removes the buffer print
20
-
21
-
22
19
  def get_default_configs() -> RunnableConfig:
23
20
  """
24
21
  User can provide extensions as part of their code base, runnable-config.yaml provides the place to put them.
@@ -128,11 +125,10 @@ def prepare_configurations(
128
125
  "job-executor", None
129
126
  ) # type: ignore
130
127
  if not job_executor_config:
131
- executor_config = cast(
128
+ job_executor_config = cast(
132
129
  ServiceConfig,
133
130
  runnable_defaults.get("job-executor", defaults.DEFAULT_JOB_EXECUTOR),
134
131
  )
135
-
136
132
  assert job_executor_config, "Job executor is not provided"
137
133
  configured_executor = utils.get_provider_by_name_and_type(
138
134
  "job_executor", job_executor_config
@@ -11,9 +11,9 @@ import runnable.context as context
11
11
  from runnable import defaults
12
12
  from runnable.datastore import DataCatalog, JobLog, StepLog
13
13
  from runnable.defaults import TypeMapVariable
14
- from runnable.graph import Graph
15
14
 
16
15
  if TYPE_CHECKING: # pragma: no cover
16
+ from runnable.graph import Graph
17
17
  from runnable.nodes import BaseNode
18
18
  from runnable.tasks import BaseTaskType
19
19
 
@@ -15,8 +15,6 @@ from runnable.utils import remove_prefix
15
15
 
16
16
  logger = logging.getLogger(defaults.LOGGER_NAME)
17
17
 
18
- # TODO: Revisit this, it might be a bit too complicated than required
19
-
20
18
 
21
19
  def get_user_set_parameters(remove: bool = False) -> Dict[str, JsonParameter]:
22
20
  """
@@ -50,13 +48,6 @@ def get_user_set_parameters(remove: bool = False) -> Dict[str, JsonParameter]:
50
48
  return parameters
51
49
 
52
50
 
53
- def serialize_parameter_as_str(value: Any) -> str:
54
- if isinstance(value, BaseModel):
55
- return json.dumps(value.model_dump())
56
-
57
- return json.dumps(value)
58
-
59
-
60
51
  def filter_arguments_for_func(
61
52
  func: Callable[..., Any],
62
53
  params: Dict[str, Any],
@@ -17,7 +17,7 @@ from ruamel.yaml import YAML
17
17
  from stevedore import driver
18
18
 
19
19
  import runnable.context as context
20
- from runnable import defaults, names
20
+ from runnable import console, defaults, names
21
21
  from runnable.defaults import TypeMapVariable
22
22
 
23
23
  if TYPE_CHECKING: # pragma: no cover
@@ -176,7 +176,7 @@ def is_a_git_repo() -> bool:
176
176
  logger.info("Found the code to be git versioned")
177
177
  return True
178
178
  except BaseException: # pylint: disable=W0702
179
- logger.error("No git repo found, unsafe hash")
179
+ console.print("Not a git repo", style="bold red")
180
180
 
181
181
  return False
182
182
 
@@ -195,27 +195,7 @@ def get_current_code_commit() -> Union[str, None]:
195
195
  logger.info("Found the git commit to be: %s", label)
196
196
  return label
197
197
  except BaseException: # pylint: disable=W0702
198
- logger.exception("Error getting git hash")
199
- raise
200
-
201
-
202
- def archive_git_tracked(name: str):
203
- """Generate a git archive of the tracked files.
204
-
205
- Args:
206
- name (str): The name to give the archive
207
-
208
- Raises:
209
- Exception: If its not a git repo
210
- """
211
- command = f"git archive -v -o {name}.tar.gz --format=tar.gz HEAD"
212
-
213
- if not is_a_git_repo():
214
- raise Exception("Not a git repo")
215
- try:
216
- subprocess.check_output(command.split()).strip().decode("utf-8")
217
- except BaseException: # pylint: disable=W0702
218
- logger.exception("Error archiving repo")
198
+ console.print("Not a git repo, error getting hash", style="bold red")
219
199
  raise
220
200
 
221
201
 
@@ -234,7 +214,7 @@ def is_git_clean() -> Tuple[bool, Union[None, str]]:
234
214
  return True, None
235
215
  return False, label
236
216
  except BaseException: # pylint: disable=W0702
237
- logger.exception("Error checking if the code is git clean")
217
+ console.print("Not a git repo, not clean", style="bold red")
238
218
 
239
219
  return False, None
240
220
 
@@ -253,7 +233,7 @@ def get_git_remote() -> Union[str, None]:
253
233
  logger.info("Found the git remote to be: %s", label)
254
234
  return label
255
235
  except BaseException: # pylint: disable=W0702
256
- logger.exception("Error getting git remote")
236
+ console.print("Not a git repo, no remote", style="bold red")
257
237
  raise
258
238
 
259
239
 
@@ -1,10 +0,0 @@
1
- docs/
2
- .github/
3
- .mypy_cache/
4
- .pytest_cache/
5
- .ruff_cache/
6
- .tox/
7
- .scripts/
8
- .tests/
9
- .venv/
10
- minikube/
@@ -1,18 +0,0 @@
1
- name: docs
2
- on:
3
- push:
4
- branches:
5
- - main
6
-
7
- jobs:
8
- deploy:
9
- runs-on: ubuntu-latest
10
- steps:
11
- - uses: actions/checkout@v2
12
- - name: Install uv
13
- run: curl -LsSf https://astral.sh/uv/install.sh | sh
14
- - name: "Set up Python"
15
- run: uv python install
16
- - run: |
17
- uv sync --only-group docs
18
- uv run mkdocs gh-deploy --force