runnable 0.16.0__tar.gz → 0.17.1__tar.gz

Sign up to get free protection for your applications and to get access to all the features.
Files changed (242) hide show
  1. {runnable-0.16.0 → runnable-0.17.1}/PKG-INFO +1 -1
  2. {runnable-0.16.0 → runnable-0.17.1}/examples/02-sequential/on_failure_fail.py +2 -1
  3. {runnable-0.16.0 → runnable-0.17.1}/examples/02-sequential/on_failure_succeed.py +4 -2
  4. runnable-0.17.1/examples/configs/in-memory.yaml +14 -0
  5. {runnable-0.16.0 → runnable-0.17.1}/extensions/pipeline_executor/local.py +14 -28
  6. {runnable-0.16.0 → runnable-0.17.1}/pyproject.toml +1 -1
  7. {runnable-0.16.0 → runnable-0.17.1}/runnable/context.py +3 -1
  8. {runnable-0.16.0 → runnable-0.17.1}/runnable/datastore.py +14 -3
  9. {runnable-0.16.0 → runnable-0.17.1}/runnable/executor.py +1 -3
  10. {runnable-0.16.0 → runnable-0.17.1}/runnable/sdk.py +40 -99
  11. {runnable-0.16.0 → runnable-0.17.1}/.dockerignore +0 -0
  12. {runnable-0.16.0 → runnable-0.17.1}/.github/workflows/docs.yaml +0 -0
  13. {runnable-0.16.0 → runnable-0.17.1}/.github/workflows/pr.yaml +0 -0
  14. {runnable-0.16.0 → runnable-0.17.1}/.github/workflows/release.yaml +0 -0
  15. {runnable-0.16.0 → runnable-0.17.1}/.gitignore +0 -0
  16. {runnable-0.16.0 → runnable-0.17.1}/.mypy.ini +0 -0
  17. {runnable-0.16.0 → runnable-0.17.1}/.pre-commit-config.yaml +0 -0
  18. {runnable-0.16.0 → runnable-0.17.1}/.python-version +0 -0
  19. {runnable-0.16.0 → runnable-0.17.1}/CHANGELOG.md +0 -0
  20. {runnable-0.16.0 → runnable-0.17.1}/CONTRIBUTING.md +0 -0
  21. {runnable-0.16.0 → runnable-0.17.1}/Dockerfile +0 -0
  22. {runnable-0.16.0 → runnable-0.17.1}/LICENSE +0 -0
  23. {runnable-0.16.0 → runnable-0.17.1}/README.md +0 -0
  24. {runnable-0.16.0 → runnable-0.17.1}/docs/architecture/yaml.md +0 -0
  25. {runnable-0.16.0 → runnable-0.17.1}/docs/assets/cropped.png +0 -0
  26. {runnable-0.16.0 → runnable-0.17.1}/docs/assets/screenshots/argo-expose-parameters.png +0 -0
  27. {runnable-0.16.0 → runnable-0.17.1}/docs/assets/screenshots/argo-kubeflow-exec.png +0 -0
  28. {runnable-0.16.0 → runnable-0.17.1}/docs/assets/screenshots/argo-kubeflow-ui.png +0 -0
  29. {runnable-0.16.0 → runnable-0.17.1}/docs/assets/screenshots/argo-nested.png +0 -0
  30. {runnable-0.16.0 → runnable-0.17.1}/docs/assets/screenshots/argo-parallel-map.png +0 -0
  31. {runnable-0.16.0 → runnable-0.17.1}/docs/assets/screenshots/argo-sequential-map.png +0 -0
  32. {runnable-0.16.0 → runnable-0.17.1}/docs/assets/screenshots/argo-workflows-gant.png +0 -0
  33. {runnable-0.16.0 → runnable-0.17.1}/docs/assets/screenshots/argo-workflows-logs.png +0 -0
  34. {runnable-0.16.0 → runnable-0.17.1}/docs/assets/screenshots/mlflow.png +0 -0
  35. {runnable-0.16.0 → runnable-0.17.1}/docs/assets/screenshots/mlflow_example.png +0 -0
  36. {runnable-0.16.0 → runnable-0.17.1}/docs/assets/screenshots/mlflow_step.png +0 -0
  37. {runnable-0.16.0 → runnable-0.17.1}/docs/assets/screenshots/notebook_api_parameters.png +0 -0
  38. {runnable-0.16.0 → runnable-0.17.1}/docs/assets/screenshots/notebook_env_parameters.png +0 -0
  39. {runnable-0.16.0 → runnable-0.17.1}/docs/assets/screenshots/notebook_input_parameters.png +0 -0
  40. {runnable-0.16.0 → runnable-0.17.1}/docs/assets/screenshots/notebook_native_parameters.png +0 -0
  41. {runnable-0.16.0 → runnable-0.17.1}/docs/assets/screenshots/simple_notebook.png +0 -0
  42. {runnable-0.16.0 → runnable-0.17.1}/docs/assets/speed.png +0 -0
  43. {runnable-0.16.0 → runnable-0.17.1}/docs/assets/sport.png +0 -0
  44. {runnable-0.16.0 → runnable-0.17.1}/docs/assets/work_dark.png +0 -0
  45. {runnable-0.16.0 → runnable-0.17.1}/docs/assets/work_light.png +0 -0
  46. {runnable-0.16.0 → runnable-0.17.1}/docs/concepts/catalog.md +0 -0
  47. {runnable-0.16.0 → runnable-0.17.1}/docs/concepts/index.md +0 -0
  48. {runnable-0.16.0 → runnable-0.17.1}/docs/concepts/map.md +0 -0
  49. {runnable-0.16.0 → runnable-0.17.1}/docs/concepts/nesting.md +0 -0
  50. {runnable-0.16.0 → runnable-0.17.1}/docs/concepts/parallel.md +0 -0
  51. {runnable-0.16.0 → runnable-0.17.1}/docs/concepts/parameters.md +0 -0
  52. {runnable-0.16.0 → runnable-0.17.1}/docs/concepts/pipeline.md +0 -0
  53. {runnable-0.16.0 → runnable-0.17.1}/docs/concepts/run-log.md +0 -0
  54. {runnable-0.16.0 → runnable-0.17.1}/docs/concepts/secrets.md +0 -0
  55. {runnable-0.16.0 → runnable-0.17.1}/docs/concepts/task.md +0 -0
  56. {runnable-0.16.0 → runnable-0.17.1}/docs/configurations/catalog.md +0 -0
  57. {runnable-0.16.0 → runnable-0.17.1}/docs/configurations/executors/argo.md +0 -0
  58. {runnable-0.16.0 → runnable-0.17.1}/docs/configurations/executors/container-environments.md +0 -0
  59. {runnable-0.16.0 → runnable-0.17.1}/docs/configurations/executors/local-container.md +0 -0
  60. {runnable-0.16.0 → runnable-0.17.1}/docs/configurations/executors/local.md +0 -0
  61. {runnable-0.16.0 → runnable-0.17.1}/docs/configurations/executors/mocked.md +0 -0
  62. {runnable-0.16.0 → runnable-0.17.1}/docs/configurations/executors/retry.md +0 -0
  63. {runnable-0.16.0 → runnable-0.17.1}/docs/configurations/overview.md +0 -0
  64. {runnable-0.16.0 → runnable-0.17.1}/docs/configurations/run-log.md +0 -0
  65. {runnable-0.16.0 → runnable-0.17.1}/docs/configurations/secrets.md +0 -0
  66. {runnable-0.16.0 → runnable-0.17.1}/docs/css/extra.css +0 -0
  67. {runnable-0.16.0 → runnable-0.17.1}/docs/index.md +0 -0
  68. {runnable-0.16.0 → runnable-0.17.1}/docs/iterative.md +0 -0
  69. {runnable-0.16.0 → runnable-0.17.1}/docs/reference.md +0 -0
  70. {runnable-0.16.0 → runnable-0.17.1}/docs/tutorial/dynamic-looping.md +0 -0
  71. {runnable-0.16.0 → runnable-0.17.1}/docs/tutorial/modular-dags.md +0 -0
  72. {runnable-0.16.0 → runnable-0.17.1}/docs/tutorial/modular-notebooks.md +0 -0
  73. {runnable-0.16.0 → runnable-0.17.1}/docs/tutorial/overview.md +0 -0
  74. {runnable-0.16.0 → runnable-0.17.1}/docs/tutorial/script-based.md +0 -0
  75. {runnable-0.16.0 → runnable-0.17.1}/docs/tutorial/single-notebook.md +0 -0
  76. {runnable-0.16.0 → runnable-0.17.1}/docs/tutorial/switching-configs.md +0 -0
  77. {runnable-0.16.0 → runnable-0.17.1}/docs/tutorial/using-parallel.md +0 -0
  78. {runnable-0.16.0 → runnable-0.17.1}/docs/tutorial/wrap-up.md +0 -0
  79. {runnable-0.16.0 → runnable-0.17.1}/docs/usage.md +0 -0
  80. {runnable-0.16.0 → runnable-0.17.1}/docs/why-runnable.md +0 -0
  81. {runnable-0.16.0 → runnable-0.17.1}/examples/01-tasks/notebook.py +0 -0
  82. {runnable-0.16.0 → runnable-0.17.1}/examples/01-tasks/notebook.yaml +0 -0
  83. {runnable-0.16.0 → runnable-0.17.1}/examples/01-tasks/python_tasks.py +0 -0
  84. {runnable-0.16.0 → runnable-0.17.1}/examples/01-tasks/python_tasks.yaml +0 -0
  85. {runnable-0.16.0 → runnable-0.17.1}/examples/01-tasks/scripts.py +0 -0
  86. {runnable-0.16.0 → runnable-0.17.1}/examples/01-tasks/scripts.yaml +0 -0
  87. {runnable-0.16.0 → runnable-0.17.1}/examples/01-tasks/stub.py +0 -0
  88. {runnable-0.16.0 → runnable-0.17.1}/examples/01-tasks/stub.yaml +0 -0
  89. {runnable-0.16.0 → runnable-0.17.1}/examples/02-sequential/default_fail.py +0 -0
  90. {runnable-0.16.0 → runnable-0.17.1}/examples/02-sequential/default_fail.yaml +0 -0
  91. {runnable-0.16.0 → runnable-0.17.1}/examples/02-sequential/on_failure_fail.yaml +0 -0
  92. {runnable-0.16.0 → runnable-0.17.1}/examples/02-sequential/on_failure_succeed.yaml +0 -0
  93. {runnable-0.16.0 → runnable-0.17.1}/examples/02-sequential/traversal.py +0 -0
  94. {runnable-0.16.0 → runnable-0.17.1}/examples/02-sequential/traversal.yaml +0 -0
  95. {runnable-0.16.0 → runnable-0.17.1}/examples/03-parameters/passing_parameters_notebook.py +0 -0
  96. {runnable-0.16.0 → runnable-0.17.1}/examples/03-parameters/passing_parameters_notebook.yaml +0 -0
  97. {runnable-0.16.0 → runnable-0.17.1}/examples/03-parameters/passing_parameters_python.py +0 -0
  98. {runnable-0.16.0 → runnable-0.17.1}/examples/03-parameters/passing_parameters_python.yaml +0 -0
  99. {runnable-0.16.0 → runnable-0.17.1}/examples/03-parameters/passing_parameters_shell.py +0 -0
  100. {runnable-0.16.0 → runnable-0.17.1}/examples/03-parameters/passing_parameters_shell.yaml +0 -0
  101. {runnable-0.16.0 → runnable-0.17.1}/examples/03-parameters/static_parameters_non_python.py +0 -0
  102. {runnable-0.16.0 → runnable-0.17.1}/examples/03-parameters/static_parameters_non_python.yaml +0 -0
  103. {runnable-0.16.0 → runnable-0.17.1}/examples/03-parameters/static_parameters_python.py +0 -0
  104. {runnable-0.16.0 → runnable-0.17.1}/examples/03-parameters/static_parameters_python.yaml +0 -0
  105. {runnable-0.16.0 → runnable-0.17.1}/examples/04-catalog/catalog.py +0 -0
  106. {runnable-0.16.0 → runnable-0.17.1}/examples/04-catalog/catalog.yaml +0 -0
  107. {runnable-0.16.0 → runnable-0.17.1}/examples/06-parallel/nesting.py +0 -0
  108. {runnable-0.16.0 → runnable-0.17.1}/examples/06-parallel/nesting.yaml +0 -0
  109. {runnable-0.16.0 → runnable-0.17.1}/examples/06-parallel/parallel.py +0 -0
  110. {runnable-0.16.0 → runnable-0.17.1}/examples/06-parallel/parallel.yaml +0 -0
  111. {runnable-0.16.0 → runnable-0.17.1}/examples/07-map/custom_reducer.py +0 -0
  112. {runnable-0.16.0 → runnable-0.17.1}/examples/07-map/custom_reducer.yaml +0 -0
  113. {runnable-0.16.0 → runnable-0.17.1}/examples/07-map/map.py +0 -0
  114. {runnable-0.16.0 → runnable-0.17.1}/examples/07-map/map.yaml +0 -0
  115. {runnable-0.16.0 → runnable-0.17.1}/examples/08-mocking/default.yaml +0 -0
  116. {runnable-0.16.0 → runnable-0.17.1}/examples/08-mocking/patching.yaml +0 -0
  117. {runnable-0.16.0 → runnable-0.17.1}/examples/09-retry/config.yaml +0 -0
  118. {runnable-0.16.0 → runnable-0.17.1}/examples/09-retry/python_tasks.py +0 -0
  119. {runnable-0.16.0 → runnable-0.17.1}/examples/09-retry/python_tasks.yaml +0 -0
  120. {runnable-0.16.0 → runnable-0.17.1}/examples/11-jobs/catalog.py +0 -0
  121. {runnable-0.16.0 → runnable-0.17.1}/examples/11-jobs/catalog.yaml +0 -0
  122. {runnable-0.16.0 → runnable-0.17.1}/examples/11-jobs/k8s-job.yaml +0 -0
  123. {runnable-0.16.0 → runnable-0.17.1}/examples/11-jobs/local-container.yaml +0 -0
  124. {runnable-0.16.0 → runnable-0.17.1}/examples/11-jobs/notebook.yaml +0 -0
  125. {runnable-0.16.0 → runnable-0.17.1}/examples/11-jobs/passing_parameters_python.py +0 -0
  126. {runnable-0.16.0 → runnable-0.17.1}/examples/11-jobs/python_parameters.yaml +0 -0
  127. {runnable-0.16.0 → runnable-0.17.1}/examples/11-jobs/python_tasks.py +0 -0
  128. {runnable-0.16.0 → runnable-0.17.1}/examples/11-jobs/python_tasks.yaml +0 -0
  129. {runnable-0.16.0 → runnable-0.17.1}/examples/11-jobs/scripts.yaml +0 -0
  130. {runnable-0.16.0 → runnable-0.17.1}/examples/Dockerfile.39 +0 -0
  131. {runnable-0.16.0 → runnable-0.17.1}/examples/README.md +0 -0
  132. {runnable-0.16.0 → runnable-0.17.1}/examples/common/functions.py +0 -0
  133. {runnable-0.16.0 → runnable-0.17.1}/examples/common/initial_parameters.yaml +0 -0
  134. {runnable-0.16.0 → runnable-0.17.1}/examples/common/process_chunk.ipynb +0 -0
  135. {runnable-0.16.0 → runnable-0.17.1}/examples/common/read_files.ipynb +0 -0
  136. {runnable-0.16.0 → runnable-0.17.1}/examples/common/read_parameters.ipynb +0 -0
  137. {runnable-0.16.0 → runnable-0.17.1}/examples/common/simple_notebook.ipynb +0 -0
  138. {runnable-0.16.0 → runnable-0.17.1}/examples/common/simple_notebook_mocked.ipynb +0 -0
  139. {runnable-0.16.0 → runnable-0.17.1}/examples/common/write_parameters.ipynb +0 -0
  140. {runnable-0.16.0 → runnable-0.17.1}/examples/comparisons/README.md +0 -0
  141. {runnable-0.16.0 → runnable-0.17.1}/examples/comparisons/kedro/README.md +0 -0
  142. {runnable-0.16.0 → runnable-0.17.1}/examples/comparisons/kfp/README.md +0 -0
  143. {runnable-0.16.0 → runnable-0.17.1}/examples/comparisons/metaflow/main.py +0 -0
  144. {runnable-0.16.0 → runnable-0.17.1}/examples/comparisons/metaflow/parameters.json +0 -0
  145. {runnable-0.16.0 → runnable-0.17.1}/examples/comparisons/runnable/main.py +0 -0
  146. {runnable-0.16.0 → runnable-0.17.1}/examples/comparisons/runnable/runnable_params.yaml +0 -0
  147. {runnable-0.16.0 → runnable-0.17.1}/examples/comparisons/source.py +0 -0
  148. {runnable-0.16.0 → runnable-0.17.1}/examples/configs/argo-config-full.yaml +0 -0
  149. {runnable-0.16.0 → runnable-0.17.1}/examples/configs/argo-config.yaml +0 -0
  150. {runnable-0.16.0 → runnable-0.17.1}/examples/configs/chunked-fs-run_log.yaml +0 -0
  151. {runnable-0.16.0 → runnable-0.17.1}/examples/configs/default.yaml +0 -0
  152. {runnable-0.16.0 → runnable-0.17.1}/examples/configs/dotenv.yaml +0 -0
  153. {runnable-0.16.0 → runnable-0.17.1}/examples/configs/local-container.yaml +0 -0
  154. {runnable-0.16.0 → runnable-0.17.1}/examples/configs/mocked-config-debug.yaml +0 -0
  155. {runnable-0.16.0 → runnable-0.17.1}/examples/configs/mocked-config-simple.yaml +0 -0
  156. {runnable-0.16.0 → runnable-0.17.1}/examples/configs/mocked-config-unittest.yaml +0 -0
  157. {runnable-0.16.0 → runnable-0.17.1}/examples/configs/mocked-config.yaml +0 -0
  158. {runnable-0.16.0 → runnable-0.17.1}/examples/configs/mocked_map_parameters.yaml +0 -0
  159. {runnable-0.16.0 → runnable-0.17.1}/examples/configs/retry-config.yaml +0 -0
  160. {runnable-0.16.0 → runnable-0.17.1}/examples/executors/argo-map-sequential.yaml +0 -0
  161. {runnable-0.16.0 → runnable-0.17.1}/examples/executors/local-container-override.yaml +0 -0
  162. {runnable-0.16.0 → runnable-0.17.1}/examples/executors/step_overrides_container.py +0 -0
  163. {runnable-0.16.0 → runnable-0.17.1}/examples/executors/step_overrides_container.yaml +0 -0
  164. {runnable-0.16.0 → runnable-0.17.1}/examples/generated-argo-pipeline.yaml +0 -0
  165. {runnable-0.16.0 → runnable-0.17.1}/examples/iris_demo.py +0 -0
  166. {runnable-0.16.0 → runnable-0.17.1}/examples/tutorials/mnist/baseline_comparison.py +0 -0
  167. {runnable-0.16.0 → runnable-0.17.1}/examples/tutorials/mnist/hyper_parameter_tuning.py +0 -0
  168. {runnable-0.16.0 → runnable-0.17.1}/examples/tutorials/mnist/modular_source.py +0 -0
  169. {runnable-0.16.0 → runnable-0.17.1}/examples/tutorials/mnist/parameters.yaml +0 -0
  170. {runnable-0.16.0 → runnable-0.17.1}/examples/tutorials/mnist/parameters_source.py +0 -0
  171. {runnable-0.16.0 → runnable-0.17.1}/examples/tutorials/mnist/source.py +0 -0
  172. {runnable-0.16.0 → runnable-0.17.1}/examples/tutorials/reddit_text_classification/parameters.yaml +0 -0
  173. {runnable-0.16.0 → runnable-0.17.1}/examples/tutorials/reddit_text_classification/pipeline.py +0 -0
  174. {runnable-0.16.0 → runnable-0.17.1}/examples/tutorials/reddit_text_classification/steps.py +0 -0
  175. {runnable-0.16.0 → runnable-0.17.1}/extensions/README.md +0 -0
  176. {runnable-0.16.0 → runnable-0.17.1}/extensions/__init__.py +0 -0
  177. {runnable-0.16.0 → runnable-0.17.1}/extensions/catalog/file_system.py +0 -0
  178. {runnable-0.16.0 → runnable-0.17.1}/extensions/catalog/pyproject.toml +0 -0
  179. {runnable-0.16.0 → runnable-0.17.1}/extensions/job_executor/__init__.py +0 -0
  180. {runnable-0.16.0 → runnable-0.17.1}/extensions/job_executor/k8s.py +0 -0
  181. {runnable-0.16.0 → runnable-0.17.1}/extensions/job_executor/k8s_job_spec.yaml +0 -0
  182. {runnable-0.16.0 → runnable-0.17.1}/extensions/job_executor/local.py +0 -0
  183. {runnable-0.16.0 → runnable-0.17.1}/extensions/job_executor/local_container.py +0 -0
  184. {runnable-0.16.0 → runnable-0.17.1}/extensions/job_executor/pyproject.toml +0 -0
  185. {runnable-0.16.0 → runnable-0.17.1}/extensions/nodes/nodes.py +0 -0
  186. {runnable-0.16.0 → runnable-0.17.1}/extensions/nodes/pyproject.toml +0 -0
  187. {runnable-0.16.0 → runnable-0.17.1}/extensions/pipeline_executor/__init__.py +0 -0
  188. {runnable-0.16.0 → runnable-0.17.1}/extensions/pipeline_executor/argo.py +0 -0
  189. {runnable-0.16.0 → runnable-0.17.1}/extensions/pipeline_executor/argo_specification.yaml +0 -0
  190. {runnable-0.16.0 → runnable-0.17.1}/extensions/pipeline_executor/local_container.py +0 -0
  191. {runnable-0.16.0 → runnable-0.17.1}/extensions/pipeline_executor/mocked.py +0 -0
  192. {runnable-0.16.0 → runnable-0.17.1}/extensions/pipeline_executor/pyproject.toml +0 -0
  193. {runnable-0.16.0 → runnable-0.17.1}/extensions/pipeline_executor/retry.py +0 -0
  194. {runnable-0.16.0 → runnable-0.17.1}/extensions/run_log_store/__init__.py +0 -0
  195. {runnable-0.16.0 → runnable-0.17.1}/extensions/run_log_store/chunked_fs.py +0 -0
  196. {runnable-0.16.0 → runnable-0.17.1}/extensions/run_log_store/db/implementation_FF.py +0 -0
  197. {runnable-0.16.0 → runnable-0.17.1}/extensions/run_log_store/db/integration_FF.py +0 -0
  198. {runnable-0.16.0 → runnable-0.17.1}/extensions/run_log_store/file_system.py +0 -0
  199. {runnable-0.16.0 → runnable-0.17.1}/extensions/run_log_store/generic_chunked.py +0 -0
  200. {runnable-0.16.0 → runnable-0.17.1}/extensions/run_log_store/pyproject.toml +0 -0
  201. {runnable-0.16.0 → runnable-0.17.1}/extensions/secrets/__init__.py +0 -0
  202. {runnable-0.16.0 → runnable-0.17.1}/extensions/secrets/dotenv.py +0 -0
  203. {runnable-0.16.0 → runnable-0.17.1}/extensions/secrets/pyproject.toml +0 -0
  204. {runnable-0.16.0 → runnable-0.17.1}/mkdocs.yml +0 -0
  205. {runnable-0.16.0 → runnable-0.17.1}/runnable/__init__.py +0 -0
  206. {runnable-0.16.0 → runnable-0.17.1}/runnable/catalog.py +0 -0
  207. {runnable-0.16.0 → runnable-0.17.1}/runnable/cli.py +0 -0
  208. {runnable-0.16.0 → runnable-0.17.1}/runnable/defaults.py +0 -0
  209. {runnable-0.16.0 → runnable-0.17.1}/runnable/entrypoints.py +0 -0
  210. {runnable-0.16.0 → runnable-0.17.1}/runnable/exceptions.py +0 -0
  211. {runnable-0.16.0 → runnable-0.17.1}/runnable/graph.py +0 -0
  212. {runnable-0.16.0 → runnable-0.17.1}/runnable/names.py +0 -0
  213. {runnable-0.16.0 → runnable-0.17.1}/runnable/nodes.py +0 -0
  214. {runnable-0.16.0 → runnable-0.17.1}/runnable/parameters.py +0 -0
  215. {runnable-0.16.0 → runnable-0.17.1}/runnable/pickler.py +0 -0
  216. {runnable-0.16.0 → runnable-0.17.1}/runnable/secrets.py +0 -0
  217. {runnable-0.16.0 → runnable-0.17.1}/runnable/tasks.py +0 -0
  218. {runnable-0.16.0 → runnable-0.17.1}/runnable/utils.py +0 -0
  219. {runnable-0.16.0 → runnable-0.17.1}/tests/__init__.py +0 -0
  220. {runnable-0.16.0 → runnable-0.17.1}/tests/conftest.py +0 -0
  221. {runnable-0.16.0 → runnable-0.17.1}/tests/extensions/__init__.py +0 -0
  222. {runnable-0.16.0 → runnable-0.17.1}/tests/extensions/catalog/test_catalog_extension.py +0 -0
  223. {runnable-0.16.0 → runnable-0.17.1}/tests/extensions/catalog/test_file_system.py +0 -0
  224. {runnable-0.16.0 → runnable-0.17.1}/tests/extensions/pipeline_executor/test_argo_executor.py +0 -0
  225. {runnable-0.16.0 → runnable-0.17.1}/tests/extensions/pipeline_executor/test_generic_executor.py +0 -0
  226. {runnable-0.16.0 → runnable-0.17.1}/tests/extensions/pipeline_executor/test_local_executor.py +0 -0
  227. {runnable-0.16.0 → runnable-0.17.1}/tests/extensions/run_log_store/__init__.py +0 -0
  228. {runnable-0.16.0 → runnable-0.17.1}/tests/extensions/run_log_store/test_file_system.py +0 -0
  229. {runnable-0.16.0 → runnable-0.17.1}/tests/extensions/secrets/test_dotenv.py +0 -0
  230. {runnable-0.16.0 → runnable-0.17.1}/tests/extensions/test_node_extensions.py +0 -0
  231. {runnable-0.16.0 → runnable-0.17.1}/tests/runnable/test_catalog.py +0 -0
  232. {runnable-0.16.0 → runnable-0.17.1}/tests/runnable/test_datastore.py +0 -0
  233. {runnable-0.16.0 → runnable-0.17.1}/tests/runnable/test_executor.py +0 -0
  234. {runnable-0.16.0 → runnable-0.17.1}/tests/runnable/test_graph.py +0 -0
  235. {runnable-0.16.0 → runnable-0.17.1}/tests/runnable/test_nodes.py +0 -0
  236. {runnable-0.16.0 → runnable-0.17.1}/tests/runnable/test_parmeters.py +0 -0
  237. {runnable-0.16.0 → runnable-0.17.1}/tests/runnable/test_sdk.py +0 -0
  238. {runnable-0.16.0 → runnable-0.17.1}/tests/runnable/test_secrets.py +0 -0
  239. {runnable-0.16.0 → runnable-0.17.1}/tests/runnable/test_utils.py +0 -0
  240. {runnable-0.16.0 → runnable-0.17.1}/tests/test_examples.py +0 -0
  241. {runnable-0.16.0 → runnable-0.17.1}/tox.ini +0 -0
  242. {runnable-0.16.0 → runnable-0.17.1}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: runnable
3
- Version: 0.16.0
3
+ Version: 0.17.1
4
4
  Summary: Add your description here
5
5
  Author-email: "Vammi, Vijay" <vijay.vammi@astrazeneca.com>
6
6
  License-File: LICENSE
@@ -28,7 +28,8 @@ def main():
28
28
  step_3 = Stub(name="step 3", terminate_with_success=True)
29
29
  step_4 = Stub(name="step 4", terminate_with_failure=True) # (1)
30
30
 
31
- step_1.on_failure = step_4.name
31
+ on_failure_pipeline = Pipeline(steps=[step_4])
32
+ step_1.on_failure = on_failure_pipeline # (2)
32
33
 
33
34
  pipeline = Pipeline(
34
35
  steps=[step_1, step_2, step_3],
@@ -28,10 +28,12 @@ def main():
28
28
  step_3 = Stub(name="step 3", terminate_with_success=True)
29
29
  step_4 = Stub(name="step 4", terminate_with_success=True) # (1)
30
30
 
31
- step_1.on_failure = step_4.name
31
+ on_failure_pipeline = Pipeline(steps=[step_4])
32
+
33
+ step_1.on_failure = on_failure_pipeline # (2)
32
34
 
33
35
  pipeline = Pipeline(
34
- steps=[step_1, step_2, step_3, [step_4]],
36
+ steps=[step_1, step_2, step_3],
35
37
  )
36
38
  pipeline.execute()
37
39
 
@@ -0,0 +1,14 @@
1
+ pipeline-executor:
2
+ type: local # (1)
3
+ config:
4
+ object_serialisation: false
5
+
6
+
7
+ run-log-store:
8
+ type: buffered # (2)
9
+
10
+ catalog:
11
+ type: do-nothing # (3)
12
+
13
+ secrets:
14
+ type: do-nothing # (4)
@@ -1,5 +1,7 @@
1
1
  import logging
2
2
 
3
+ from pydantic import Field, PrivateAttr
4
+
3
5
  from extensions.pipeline_executor import GenericPipelineExecutor
4
6
  from runnable import defaults
5
7
  from runnable.defaults import TypeMapVariable
@@ -22,7 +24,18 @@ class LocalExecutor(GenericPipelineExecutor):
22
24
  """
23
25
 
24
26
  service_name: str = "local"
25
- _is_local: bool = True
27
+
28
+ object_serialisation: bool = Field(default=True)
29
+
30
+ _is_local: bool = PrivateAttr(default=True)
31
+
32
+ def execute_from_graph(
33
+ self, node: BaseNode, map_variable: TypeMapVariable = None, **kwargs
34
+ ):
35
+ if not self.object_serialisation:
36
+ self._context.object_serialisation = False
37
+
38
+ super().execute_from_graph(node=node, map_variable=map_variable, **kwargs)
26
39
 
27
40
  def trigger_node_execution(
28
41
  self, node: BaseNode, map_variable: TypeMapVariable = None, **kwargs
@@ -47,30 +60,3 @@ class LocalExecutor(GenericPipelineExecutor):
47
60
  map_variable (dict[str, str], optional): _description_. Defaults to None.
48
61
  """
49
62
  self._execute_node(node=node, map_variable=map_variable, **kwargs)
50
-
51
- # def execute_job(self, node: TaskNode):
52
- # """
53
- # Set up the step log and call the execute node
54
-
55
- # Args:
56
- # node (BaseNode): _description_
57
- # """
58
-
59
- # step_log = self._context.run_log_store.create_step_log(
60
- # node.name, node._get_step_log_name(map_variable=None)
61
- # )
62
-
63
- # self.add_code_identities(node=node, step_log=step_log)
64
-
65
- # step_log.step_type = node.node_type
66
- # step_log.status = defaults.PROCESSING
67
- # self._context.run_log_store.add_step_log(step_log, self._context.run_id)
68
- # self.execute_node(node=node)
69
-
70
- # # Update the run log status
71
- # step_log = self._context.run_log_store.get_step_log(
72
- # node._get_step_log_name(), self._context.run_id
73
- # )
74
- # self._context.run_log_store.update_run_log_status(
75
- # run_id=self._context.run_id, status=step_log.status
76
- # )
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "runnable"
3
- version = "0.16.0"
3
+ version = "0.17.1"
4
4
  description = "Add your description here"
5
5
  readme = "README.md"
6
6
  authors = [
@@ -1,4 +1,4 @@
1
- from typing import Dict, List, Optional
1
+ from typing import Any, Dict, List, Optional
2
2
 
3
3
  from pydantic import BaseModel, ConfigDict, Field, SerializeAsAny
4
4
  from rich.progress import Progress
@@ -29,6 +29,8 @@ class Context(BaseModel):
29
29
  from_sdk: bool = False
30
30
 
31
31
  run_id: str = ""
32
+ object_serialisation: bool = True
33
+ return_objects: Dict[str, Any] = {}
32
34
 
33
35
  tag: str = ""
34
36
  variables: Dict[str, str] = {}
@@ -98,22 +98,33 @@ class ObjectParameter(BaseModel):
98
98
  @computed_field # type: ignore
99
99
  @property
100
100
  def description(self) -> str:
101
- return f"Pickled object stored in catalog as: {self.value}"
101
+ if context.run_context.object_serialisation:
102
+ return f"Pickled object stored in catalog as: {self.value}"
103
+
104
+ return f"Object stored in memory as: {self.value}"
102
105
 
103
106
  @property
104
107
  def file_name(self) -> str:
105
108
  return f"{self.value}{context.run_context.pickler.extension}"
106
109
 
107
110
  def get_value(self) -> Any:
108
- # Get the pickled object
109
- catalog_handler = context.run_context.catalog_handler
111
+ # If there was no serialisation, return the object from the return objects
112
+ if not context.run_context.object_serialisation:
113
+ return context.run_context.return_objects[self.value]
110
114
 
115
+ # If the object was serialised, get it from the catalog
116
+ catalog_handler = context.run_context.catalog_handler
111
117
  catalog_handler.get(name=self.file_name, run_id=context.run_context.run_id)
112
118
  obj = context.run_context.pickler.load(path=self.file_name)
113
119
  os.remove(self.file_name) # Remove after loading
114
120
  return obj
115
121
 
116
122
  def put_object(self, data: Any) -> None:
123
+ if not context.run_context.object_serialisation:
124
+ context.run_context.return_objects[self.value] = data
125
+ return
126
+
127
+ # If the object was serialised, put it in the catalog
117
128
  context.run_context.pickler.dump(data=data, path=self.file_name)
118
129
 
119
130
  catalog_handler = context.run_context.catalog_handler
@@ -34,9 +34,7 @@ class BaseExecutor(ABC, BaseModel):
34
34
  service_name: str = ""
35
35
  service_type: str = "executor"
36
36
 
37
- _is_local: bool = (
38
- False # This is a flag to indicate whether the executor is local or not.
39
- )
37
+ _is_local: bool = PrivateAttr(default=False)
40
38
 
41
39
  model_config = ConfigDict(extra="forbid")
42
40
 
@@ -84,7 +84,7 @@ class BaseTraversal(ABC, BaseModel):
84
84
  next_node: str = Field(default="", serialization_alias="next_node")
85
85
  terminate_with_success: bool = Field(default=False, exclude=True)
86
86
  terminate_with_failure: bool = Field(default=False, exclude=True)
87
- on_failure: str = Field(default="", alias="on_failure")
87
+ on_failure: Optional[Pipeline] = Field(default=None)
88
88
 
89
89
  model_config = ConfigDict(extra="forbid")
90
90
 
@@ -117,18 +117,6 @@ class BaseTraversal(ABC, BaseModel):
117
117
 
118
118
  return other
119
119
 
120
- def depends_on(self, node: StepType) -> Self:
121
- assert not isinstance(node, Success)
122
- assert not isinstance(node, Fail)
123
-
124
- if node.next_node:
125
- raise Exception(
126
- f"The {node} node already has a next node: {node.next_node}"
127
- )
128
-
129
- node.next_node = self.name
130
- return self
131
-
132
120
  @model_validator(mode="after")
133
121
  def validate_terminations(self) -> Self:
134
122
  if self.terminate_with_failure and self.terminate_with_success:
@@ -175,7 +163,6 @@ class BaseTask(BaseTraversal):
175
163
  if isinstance(x, str):
176
164
  task_returns.append(TaskReturns(name=x, kind="json"))
177
165
  continue
178
-
179
166
  # Its already task returns
180
167
  task_returns.append(x)
181
168
 
@@ -188,6 +175,9 @@ class BaseTask(BaseTraversal):
188
175
  "A node not being terminated must have a user defined next node"
189
176
  )
190
177
 
178
+ if self.on_failure:
179
+ self.on_failure = self.on_failure.steps[0].name # type: ignore
180
+
191
181
  return TaskNode.parse_from_config(
192
182
  self.model_dump(exclude_none=True, by_alias=True)
193
183
  )
@@ -605,8 +595,6 @@ class Pipeline(BaseModel):
605
595
  The order of steps is important as it determines the order of execution.
606
596
  Any on failure behavior should the first step in ```on_failure``` pipelines.
607
597
 
608
-
609
-
610
598
  on_failure (List[List[Pipeline], optional): A list of Pipelines to execute in case of failure.
611
599
 
612
600
  For example, for the below pipeline:
@@ -624,7 +612,7 @@ class Pipeline(BaseModel):
624
612
 
625
613
  """
626
614
 
627
- steps: List[Union[StepType, List["Pipeline"]]]
615
+ steps: List[StepType]
628
616
  name: str = ""
629
617
  description: str = ""
630
618
 
@@ -637,114 +625,67 @@ class Pipeline(BaseModel):
637
625
  _dag: graph.Graph = PrivateAttr()
638
626
  model_config = ConfigDict(extra="forbid")
639
627
 
640
- def _validate_path(self, path: List[StepType], failure_path: bool = False) -> None:
641
- # TODO: Drastically simplify this
642
- # Check if one and only one step terminates with success
643
- # Check no more than one step terminates with failure
644
-
645
- reached_success = False
646
- reached_failure = False
647
-
648
- for step in path:
649
- if step.terminate_with_success:
650
- if reached_success:
651
- raise Exception(
652
- "A pipeline cannot have more than one step that terminates with success"
653
- )
654
- reached_success = True
655
- continue
656
- if step.terminate_with_failure:
657
- if reached_failure:
658
- raise Exception(
659
- "A pipeline cannot have more than one step that terminates with failure"
660
- )
661
- reached_failure = True
662
-
663
- if not reached_success and not reached_failure:
664
- raise Exception(
665
- "A pipeline must have at least one step that terminates with success"
666
- )
667
-
668
- def _construct_path(self, path: List[StepType]) -> None:
669
- prev_step = path[0]
670
-
671
- for step in path:
672
- if step == prev_step:
673
- continue
674
-
675
- if prev_step.terminate_with_success or prev_step.terminate_with_failure:
676
- raise Exception(
677
- f"A step that terminates with success/failure cannot have a next step: {prev_step}"
678
- )
679
-
680
- if prev_step.next_node and prev_step.next_node not in ["success", "fail"]:
681
- raise Exception(f"Step already has a next node: {prev_step} ")
682
-
683
- prev_step.next_node = step.name
684
- prev_step = step
685
-
686
628
  def model_post_init(self, __context: Any) -> None:
687
629
  """
688
630
  The sequence of steps can either be:
689
- [step1, step2,..., stepN, [step11, step12,..., step1N], [step21, step22,...,]]
631
+ [step1, step2,..., stepN]
690
632
  indicates:
691
633
  - step1 > step2 > ... > stepN
692
634
  - We expect terminate with success or fail to be explicitly stated on a step.
693
635
  - If it is stated, the step cannot have a next step defined apart from "success" and "fail".
694
-
695
- The inner list of steps is only to accommodate on-failure behaviors.
696
- - For sake of simplicity, lets assume that it has the same behavior as the happy pipeline.
697
- - A task which was already seen should not be part of this.
698
- - There should be at least one step which terminates with success
699
-
700
636
  Any definition of pipeline should have one node that terminates with success.
701
637
  """
702
- # TODO: Bug with repeat names
703
- # TODO: https://github.com/AstraZeneca/runnable/issues/156
638
+ # The last step of the pipeline is defaulted to be a success step
639
+ # unless it is explicitly stated to terminate with failure.
640
+ terminal_step: StepType = self.steps[-1]
641
+ if not terminal_step.terminate_with_failure:
642
+ terminal_step.terminate_with_success = True
704
643
 
705
- success_path: List[StepType] = []
706
- on_failure_paths: List[List[StepType]] = []
644
+ # assert that there is only one termination node with success or failure
645
+ # Assert that there are no duplicate step names
646
+ observed: Dict[str, str] = {}
647
+ count_termination: int = 0
707
648
 
708
649
  for step in self.steps:
709
650
  if isinstance(
710
651
  step, (Stub, PythonTask, NotebookTask, ShellTask, Parallel, Map)
711
652
  ):
712
- success_path.append(step)
713
- continue
714
- # on_failure_paths.append(step)
715
-
716
- if not success_path:
717
- raise Exception("There should be some success path")
718
-
719
- # Check all paths are valid and construct the path
720
- paths = [success_path] + on_failure_paths
721
- failure_path = False
722
- for path in paths:
723
- self._validate_path(path, failure_path)
724
- self._construct_path(path)
725
-
726
- failure_path = True
653
+ if step.terminate_with_success or step.terminate_with_failure:
654
+ count_termination += 1
655
+ if step.name in observed:
656
+ raise Exception(
657
+ f"Step names should be unique. Found duplicate: {step.name}"
658
+ )
659
+ observed[step.name] = step.name
727
660
 
728
- all_steps: List[StepType] = []
661
+ if count_termination > 1:
662
+ raise AssertionError(
663
+ "A pipeline can only have one termination node with success or failure"
664
+ )
729
665
 
730
- for path in paths:
731
- for step in path:
732
- all_steps.append(step)
666
+ # link the steps by assigning the next_node name to be that name of the node
667
+ # immediately after it.
668
+ for i in range(len(self.steps) - 1):
669
+ self.steps[i] >> self.steps[i + 1]
733
670
 
734
- seen = set()
735
- unique = [x for x in all_steps if not (x in seen or seen.add(x))] # type: ignore
671
+ # Add any on_failure pipelines to the steps
672
+ gathered_on_failure: List[StepType] = []
673
+ for step in self.steps:
674
+ if step.on_failure:
675
+ gathered_on_failure.extend(step.on_failure.steps)
736
676
 
737
677
  self._dag = graph.Graph(
738
- start_at=all_steps[0].name,
678
+ start_at=self.steps[0].name,
739
679
  description=self.description,
740
680
  internal_branch_name=self.internal_branch_name,
741
681
  )
742
682
 
743
- for step in unique:
683
+ self.steps.extend(gathered_on_failure)
684
+
685
+ for step in self.steps:
744
686
  self._dag.add_node(step.create_node())
745
687
 
746
- if self.add_terminal_nodes:
747
- self._dag.add_terminal_nodes()
688
+ self._dag.add_terminal_nodes()
748
689
 
749
690
  self._dag.check_graph()
750
691
 
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes