easylink 0.1.19__tar.gz → 0.1.20__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 (265) hide show
  1. {easylink-0.1.19 → easylink-0.1.20}/CHANGELOG.rst +4 -0
  2. {easylink-0.1.19 → easylink-0.1.20}/PKG-INFO +1 -1
  3. easylink-0.1.20/src/easylink/_version.py +1 -0
  4. {easylink-0.1.19 → easylink-0.1.20}/src/easylink/devtools/implementation_creator.py +17 -2
  5. {easylink-0.1.19 → easylink-0.1.20}/src/easylink/steps/cascading/update_clusters_by_connected_components.py +18 -10
  6. {easylink-0.1.19 → easylink-0.1.20}/src/easylink.egg-info/PKG-INFO +1 -1
  7. {easylink-0.1.19 → easylink-0.1.20}/tests/e2e/test_pipelines_main_schema.py +15 -13
  8. {easylink-0.1.19 → easylink-0.1.20}/tests/unit/test_implementation_creator.py +57 -12
  9. easylink-0.1.19/src/easylink/_version.py +0 -1
  10. {easylink-0.1.19 → easylink-0.1.20}/.bandit +0 -0
  11. {easylink-0.1.19 → easylink-0.1.20}/.flake8 +0 -0
  12. {easylink-0.1.19 → easylink-0.1.20}/.github/CODEOWNERS +0 -0
  13. {easylink-0.1.19 → easylink-0.1.20}/.github/pull_request_template.md +0 -0
  14. {easylink-0.1.19 → easylink-0.1.20}/.github/workflows/deploy.yml +0 -0
  15. {easylink-0.1.19 → easylink-0.1.20}/.github/workflows/update_readme.yml +0 -0
  16. {easylink-0.1.19 → easylink-0.1.20}/.gitignore +0 -0
  17. {easylink-0.1.19 → easylink-0.1.20}/.readthedocs.yml +0 -0
  18. {easylink-0.1.19 → easylink-0.1.20}/CONTRIBUTING.rst +0 -0
  19. {easylink-0.1.19 → easylink-0.1.20}/Jenkinsfile +0 -0
  20. {easylink-0.1.19 → easylink-0.1.20}/LICENSE +0 -0
  21. {easylink-0.1.19 → easylink-0.1.20}/Makefile +0 -0
  22. {easylink-0.1.19 → easylink-0.1.20}/README.rst +0 -0
  23. {easylink-0.1.19 → easylink-0.1.20}/docs/Makefile +0 -0
  24. {easylink-0.1.19 → easylink-0.1.20}/docs/nitpick-exceptions +0 -0
  25. {easylink-0.1.19 → easylink-0.1.20}/docs/source/_static/style.css +0 -0
  26. {easylink-0.1.19 → easylink-0.1.20}/docs/source/_templates/layout.html +0 -0
  27. {easylink-0.1.19 → easylink-0.1.20}/docs/source/api_reference/cli.rst +0 -0
  28. {easylink-0.1.19 → easylink-0.1.20}/docs/source/api_reference/configuration.rst +0 -0
  29. {easylink-0.1.19 → easylink-0.1.20}/docs/source/api_reference/graph_components.rst +0 -0
  30. {easylink-0.1.19 → easylink-0.1.20}/docs/source/api_reference/implementation.rst +0 -0
  31. {easylink-0.1.19 → easylink-0.1.20}/docs/source/api_reference/index.rst +0 -0
  32. {easylink-0.1.19 → easylink-0.1.20}/docs/source/api_reference/pipeline.rst +0 -0
  33. {easylink-0.1.19 → easylink-0.1.20}/docs/source/api_reference/pipeline_graph.rst +0 -0
  34. {easylink-0.1.19 → easylink-0.1.20}/docs/source/api_reference/pipeline_schema.rst +0 -0
  35. {easylink-0.1.19 → easylink-0.1.20}/docs/source/api_reference/pipeline_schema_constants/development.rst +0 -0
  36. {easylink-0.1.19 → easylink-0.1.20}/docs/source/api_reference/pipeline_schema_constants/index.rst +0 -0
  37. {easylink-0.1.19 → easylink-0.1.20}/docs/source/api_reference/pipeline_schema_constants/testing.rst +0 -0
  38. {easylink-0.1.19 → easylink-0.1.20}/docs/source/api_reference/rule.rst +0 -0
  39. {easylink-0.1.19 → easylink-0.1.20}/docs/source/api_reference/runner.rst +0 -0
  40. {easylink-0.1.19 → easylink-0.1.20}/docs/source/api_reference/step.rst +0 -0
  41. {easylink-0.1.19 → easylink-0.1.20}/docs/source/api_reference/utilities/aggregator_utils.rst +0 -0
  42. {easylink-0.1.19 → easylink-0.1.20}/docs/source/api_reference/utilities/data_utils.rst +0 -0
  43. {easylink-0.1.19 → easylink-0.1.20}/docs/source/api_reference/utilities/general_utils.rst +0 -0
  44. {easylink-0.1.19 → easylink-0.1.20}/docs/source/api_reference/utilities/index.rst +0 -0
  45. {easylink-0.1.19 → easylink-0.1.20}/docs/source/api_reference/utilities/paths.rst +0 -0
  46. {easylink-0.1.19 → easylink-0.1.20}/docs/source/api_reference/utilities/splitter_utils.rst +0 -0
  47. {easylink-0.1.19 → easylink-0.1.20}/docs/source/api_reference/utilities/validation_utils.rst +0 -0
  48. {easylink-0.1.19 → easylink-0.1.20}/docs/source/concepts/index.rst +0 -0
  49. {easylink-0.1.19 → easylink-0.1.20}/docs/source/concepts/pipeline_schema/images/01_step.drawio.png +0 -0
  50. {easylink-0.1.19 → easylink-0.1.20}/docs/source/concepts/pipeline_schema/images/02_default_implementation.drawio.png +0 -0
  51. {easylink-0.1.19 → easylink-0.1.20}/docs/source/concepts/pipeline_schema/images/03_slots.drawio.png +0 -0
  52. {easylink-0.1.19 → easylink-0.1.20}/docs/source/concepts/pipeline_schema/images/04_data_dependency.drawio.png +0 -0
  53. {easylink-0.1.19 → easylink-0.1.20}/docs/source/concepts/pipeline_schema/images/05_pipeline_schema.drawio.png +0 -0
  54. {easylink-0.1.19 → easylink-0.1.20}/docs/source/concepts/pipeline_schema/images/06_default_input.drawio.png +0 -0
  55. {easylink-0.1.19 → easylink-0.1.20}/docs/source/concepts/pipeline_schema/images/07_cloneable_section.drawio.png +0 -0
  56. {easylink-0.1.19 → easylink-0.1.20}/docs/source/concepts/pipeline_schema/images/08_cloneable_section_expanded.drawio.png +0 -0
  57. {easylink-0.1.19 → easylink-0.1.20}/docs/source/concepts/pipeline_schema/images/09_loopable_section.drawio.png +0 -0
  58. {easylink-0.1.19 → easylink-0.1.20}/docs/source/concepts/pipeline_schema/images/10_loopable_section_expanded.drawio.png +0 -0
  59. {easylink-0.1.19 → easylink-0.1.20}/docs/source/concepts/pipeline_schema/images/11_cloneable_section_splitter.drawio.png +0 -0
  60. {easylink-0.1.19 → easylink-0.1.20}/docs/source/concepts/pipeline_schema/images/12_cloneable_section_splitter_expanded.drawio.png +0 -0
  61. {easylink-0.1.19 → easylink-0.1.20}/docs/source/concepts/pipeline_schema/images/13_autoparallel_section.drawio.png +0 -0
  62. {easylink-0.1.19 → easylink-0.1.20}/docs/source/concepts/pipeline_schema/images/14_choice_section.drawio.png +0 -0
  63. {easylink-0.1.19 → easylink-0.1.20}/docs/source/concepts/pipeline_schema/images/15_choice_section_expanded.drawio.png +0 -0
  64. {easylink-0.1.19 → easylink-0.1.20}/docs/source/concepts/pipeline_schema/images/16_step_hierarchy.drawio.png +0 -0
  65. {easylink-0.1.19 → easylink-0.1.20}/docs/source/concepts/pipeline_schema/images/18_schema_to_pipeline.drawio.png +0 -0
  66. {easylink-0.1.19 → easylink-0.1.20}/docs/source/concepts/pipeline_schema/images/19_schema_to_pipeline_combined.drawio.png +0 -0
  67. {easylink-0.1.19 → easylink-0.1.20}/docs/source/concepts/pipeline_schema/images/clustering_sub_steps.drawio.png +0 -0
  68. {easylink-0.1.19 → easylink-0.1.20}/docs/source/concepts/pipeline_schema/images/easylink_pipeline_schema.drawio.png +0 -0
  69. {easylink-0.1.19 → easylink-0.1.20}/docs/source/concepts/pipeline_schema/images/entity_resolution_sub_steps.drawio.png +0 -0
  70. {easylink-0.1.19 → easylink-0.1.20}/docs/source/concepts/pipeline_schema/images/linking_sub_steps.drawio.png +0 -0
  71. {easylink-0.1.19 → easylink-0.1.20}/docs/source/concepts/pipeline_schema/index.rst +0 -0
  72. {easylink-0.1.19 → easylink-0.1.20}/docs/source/concepts/workarounds.rst +0 -0
  73. {easylink-0.1.19 → easylink-0.1.20}/docs/source/conf.py +0 -0
  74. {easylink-0.1.19 → easylink-0.1.20}/docs/source/glossary.rst +0 -0
  75. {easylink-0.1.19 → easylink-0.1.20}/docs/source/index.rst +0 -0
  76. {easylink-0.1.19 → easylink-0.1.20}/docs/source/user_guide/cli.rst +0 -0
  77. {easylink-0.1.19 → easylink-0.1.20}/docs/source/user_guide/index.rst +0 -0
  78. {easylink-0.1.19 → easylink-0.1.20}/docs/source/user_guide/tutorials/DAG-common-pipeline.svg +0 -0
  79. {easylink-0.1.19 → easylink-0.1.20}/docs/source/user_guide/tutorials/DAG-e2e-pipeline-expanded.svg +0 -0
  80. {easylink-0.1.19 → easylink-0.1.20}/docs/source/user_guide/tutorials/DAG-e2e-pipeline.svg +0 -0
  81. {easylink-0.1.19 → easylink-0.1.20}/docs/source/user_guide/tutorials/DAG-r-pyspark.svg +0 -0
  82. {easylink-0.1.19 → easylink-0.1.20}/docs/source/user_guide/tutorials/environment_slurm.yaml +0 -0
  83. {easylink-0.1.19 → easylink-0.1.20}/docs/source/user_guide/tutorials/getting_started.rst +0 -0
  84. {easylink-0.1.19 → easylink-0.1.20}/docs/source/user_guide/tutorials/impl-config-pipeline.yaml +0 -0
  85. {easylink-0.1.19 → easylink-0.1.20}/docs/source/user_guide/tutorials/index.rst +0 -0
  86. {easylink-0.1.19 → easylink-0.1.20}/docs/source/user_guide/tutorials/input_data.yaml +0 -0
  87. {easylink-0.1.19 → easylink-0.1.20}/docs/source/user_guide/tutorials/input_file_1.parquet +0 -0
  88. {easylink-0.1.19 → easylink-0.1.20}/docs/source/user_guide/tutorials/input_file_2.parquet +0 -0
  89. {easylink-0.1.19 → easylink-0.1.20}/docs/source/user_guide/tutorials/input_file_3.parquet +0 -0
  90. {easylink-0.1.19 → easylink-0.1.20}/docs/source/user_guide/tutorials/r_spark_pipeline.yaml +0 -0
  91. {easylink-0.1.19 → easylink-0.1.20}/pyproject.toml +0 -0
  92. {easylink-0.1.19 → easylink-0.1.20}/python_versions.json +0 -0
  93. {easylink-0.1.19 → easylink-0.1.20}/pytype.cfg +0 -0
  94. {easylink-0.1.19 → easylink-0.1.20}/setup.cfg +0 -0
  95. {easylink-0.1.19 → easylink-0.1.20}/setup.py +0 -0
  96. {easylink-0.1.19 → easylink-0.1.20}/src/easylink/__about__.py +0 -0
  97. {easylink-0.1.19 → easylink-0.1.20}/src/easylink/__init__.py +0 -0
  98. {easylink-0.1.19 → easylink-0.1.20}/src/easylink/cli.py +0 -0
  99. {easylink-0.1.19 → easylink-0.1.20}/src/easylink/configuration.py +0 -0
  100. {easylink-0.1.19 → easylink-0.1.20}/src/easylink/graph_components.py +0 -0
  101. {easylink-0.1.19 → easylink-0.1.20}/src/easylink/images/spark_cluster/Dockerfile +0 -0
  102. {easylink-0.1.19 → easylink-0.1.20}/src/easylink/images/spark_cluster/README.md +0 -0
  103. {easylink-0.1.19 → easylink-0.1.20}/src/easylink/implementation.py +0 -0
  104. {easylink-0.1.19 → easylink-0.1.20}/src/easylink/implementation_metadata.yaml +0 -0
  105. {easylink-0.1.19 → easylink-0.1.20}/src/easylink/pipeline.py +0 -0
  106. {easylink-0.1.19 → easylink-0.1.20}/src/easylink/pipeline_graph.py +0 -0
  107. {easylink-0.1.19 → easylink-0.1.20}/src/easylink/pipeline_schema.py +0 -0
  108. {easylink-0.1.19 → easylink-0.1.20}/src/easylink/pipeline_schema_constants/__init__.py +0 -0
  109. {easylink-0.1.19 → easylink-0.1.20}/src/easylink/pipeline_schema_constants/development.py +0 -0
  110. {easylink-0.1.19 → easylink-0.1.20}/src/easylink/pipeline_schema_constants/main.py +0 -0
  111. {easylink-0.1.19 → easylink-0.1.20}/src/easylink/pipeline_schema_constants/testing.py +0 -0
  112. {easylink-0.1.19 → easylink-0.1.20}/src/easylink/rule.py +0 -0
  113. {easylink-0.1.19 → easylink-0.1.20}/src/easylink/runner.py +0 -0
  114. {easylink-0.1.19 → easylink-0.1.20}/src/easylink/step.py +0 -0
  115. {easylink-0.1.19 → easylink-0.1.20}/src/easylink/steps/cascading/exclude_clustered.def +0 -0
  116. {easylink-0.1.19 → easylink-0.1.20}/src/easylink/steps/cascading/exclude_clustered.py +0 -0
  117. {easylink-0.1.19 → easylink-0.1.20}/src/easylink/steps/cascading/exclude_none.def +0 -0
  118. {easylink-0.1.19 → easylink-0.1.20}/src/easylink/steps/cascading/exclude_none.py +0 -0
  119. {easylink-0.1.19 → easylink-0.1.20}/src/easylink/steps/cascading/update_clusters_by_connected_components.def +0 -0
  120. {easylink-0.1.19 → easylink-0.1.20}/src/easylink/steps/default/default_clusters_to_links.def +0 -0
  121. {easylink-0.1.19 → easylink-0.1.20}/src/easylink/steps/default/default_clusters_to_links.py +0 -0
  122. {easylink-0.1.19 → easylink-0.1.20}/src/easylink/steps/default/default_determining_exclusions.def +0 -0
  123. {easylink-0.1.19 → easylink-0.1.20}/src/easylink/steps/default/default_determining_exclusions.py +0 -0
  124. {easylink-0.1.19 → easylink-0.1.20}/src/easylink/steps/default/default_removing_records.def +0 -0
  125. {easylink-0.1.19 → easylink-0.1.20}/src/easylink/steps/default/default_removing_records.py +0 -0
  126. {easylink-0.1.19 → easylink-0.1.20}/src/easylink/steps/default/default_schema_alignment.def +0 -0
  127. {easylink-0.1.19 → easylink-0.1.20}/src/easylink/steps/default/default_schema_alignment.py +0 -0
  128. {easylink-0.1.19 → easylink-0.1.20}/src/easylink/steps/default/default_updating_clusters.def +0 -0
  129. {easylink-0.1.19 → easylink-0.1.20}/src/easylink/steps/default/default_updating_clusters.py +0 -0
  130. {easylink-0.1.19 → easylink-0.1.20}/src/easylink/steps/dev/README.md +0 -0
  131. {easylink-0.1.19 → easylink-0.1.20}/src/easylink/steps/dev/build-containers-local.sh +0 -0
  132. {easylink-0.1.19 → easylink-0.1.20}/src/easylink/steps/dev/build-containers-remote.sh +0 -0
  133. {easylink-0.1.19 → easylink-0.1.20}/src/easylink/steps/dev/input_data/create_input_files.ipynb +0 -0
  134. {easylink-0.1.19 → easylink-0.1.20}/src/easylink/steps/dev/input_data/input_file_1.csv +0 -0
  135. {easylink-0.1.19 → easylink-0.1.20}/src/easylink/steps/dev/input_data/input_file_1.parquet +0 -0
  136. {easylink-0.1.19 → easylink-0.1.20}/src/easylink/steps/dev/input_data/input_file_2.csv +0 -0
  137. {easylink-0.1.19 → easylink-0.1.20}/src/easylink/steps/dev/input_data/input_file_2.parquet +0 -0
  138. {easylink-0.1.19 → easylink-0.1.20}/src/easylink/steps/dev/python_pandas/README.md +0 -0
  139. {easylink-0.1.19 → easylink-0.1.20}/src/easylink/steps/dev/python_pandas/dummy_step.py +0 -0
  140. {easylink-0.1.19 → easylink-0.1.20}/src/easylink/steps/dev/python_pandas/python_pandas.def +0 -0
  141. {easylink-0.1.19 → easylink-0.1.20}/src/easylink/steps/dev/python_pyspark/README.md +0 -0
  142. {easylink-0.1.19 → easylink-0.1.20}/src/easylink/steps/dev/python_pyspark/dummy_step.py +0 -0
  143. {easylink-0.1.19 → easylink-0.1.20}/src/easylink/steps/dev/python_pyspark/python_pyspark.def +0 -0
  144. {easylink-0.1.19 → easylink-0.1.20}/src/easylink/steps/dev/r/README.md +0 -0
  145. {easylink-0.1.19 → easylink-0.1.20}/src/easylink/steps/dev/r/dummy_step.R +0 -0
  146. {easylink-0.1.19 → easylink-0.1.20}/src/easylink/steps/dev/r/r-image.def +0 -0
  147. {easylink-0.1.19 → easylink-0.1.20}/src/easylink/steps/dev/test.py +0 -0
  148. {easylink-0.1.19 → easylink-0.1.20}/src/easylink/steps/fastLink/fastLink_evaluating_pairs.R +0 -0
  149. {easylink-0.1.19 → easylink-0.1.20}/src/easylink/steps/fastLink/fastLink_evaluating_pairs.def +0 -0
  150. {easylink-0.1.19 → easylink-0.1.20}/src/easylink/steps/fastLink/fastLink_links_to_clusters.R +0 -0
  151. {easylink-0.1.19 → easylink-0.1.20}/src/easylink/steps/fastLink/fastLink_links_to_clusters.def +0 -0
  152. {easylink-0.1.19 → easylink-0.1.20}/src/easylink/steps/output_dir/dummy_step_1_for_output_dir_example.def +0 -0
  153. {easylink-0.1.19 → easylink-0.1.20}/src/easylink/steps/output_dir/dummy_step_1_for_output_dir_example.py +0 -0
  154. {easylink-0.1.19 → easylink-0.1.20}/src/easylink/steps/output_dir/dummy_step_2_for_output_dir_example.def +0 -0
  155. {easylink-0.1.19 → easylink-0.1.20}/src/easylink/steps/output_dir/dummy_step_2_for_output_dir_example.py +0 -0
  156. {easylink-0.1.19 → easylink-0.1.20}/src/easylink/steps/rl-dummy/canonicalizing_and_downstream_analysis/dummy_canonicalizing_and_downstream_analysis.def +0 -0
  157. {easylink-0.1.19 → easylink-0.1.20}/src/easylink/steps/rl-dummy/canonicalizing_and_downstream_analysis/dummy_canonicalizing_and_downstream_analysis.py +0 -0
  158. {easylink-0.1.19 → easylink-0.1.20}/src/easylink/steps/rl-dummy/input_data/create_input_files.ipynb +0 -0
  159. {easylink-0.1.19 → easylink-0.1.20}/src/easylink/steps/rl-dummy/input_data/input_file_1.parquet +0 -0
  160. {easylink-0.1.19 → easylink-0.1.20}/src/easylink/steps/rl-dummy/input_data/input_file_2.parquet +0 -0
  161. {easylink-0.1.19 → easylink-0.1.20}/src/easylink/steps/rl-dummy/input_data/known_clusters.parquet +0 -0
  162. {easylink-0.1.19 → easylink-0.1.20}/src/easylink/steps/rl-dummy/pre-processing/dummy_pre-processing.def +0 -0
  163. {easylink-0.1.19 → easylink-0.1.20}/src/easylink/steps/rl-dummy/pre-processing/dummy_pre-processing.py +0 -0
  164. {easylink-0.1.19 → easylink-0.1.20}/src/easylink/steps/splink/splink_blocking_and_filtering.def +0 -0
  165. {easylink-0.1.19 → easylink-0.1.20}/src/easylink/steps/splink/splink_blocking_and_filtering.py +0 -0
  166. {easylink-0.1.19 → easylink-0.1.20}/src/easylink/steps/splink/splink_evaluating_pairs.def +0 -0
  167. {easylink-0.1.19 → easylink-0.1.20}/src/easylink/steps/splink/splink_evaluating_pairs.py +0 -0
  168. {easylink-0.1.19 → easylink-0.1.20}/src/easylink/steps/splink/splink_links_to_clusters.def +0 -0
  169. {easylink-0.1.19 → easylink-0.1.20}/src/easylink/steps/splink/splink_links_to_clusters.py +0 -0
  170. {easylink-0.1.19 → easylink-0.1.20}/src/easylink/utilities/__init__.py +0 -0
  171. {easylink-0.1.19 → easylink-0.1.20}/src/easylink/utilities/aggregator_utils.py +0 -0
  172. {easylink-0.1.19 → easylink-0.1.20}/src/easylink/utilities/data_utils.py +0 -0
  173. {easylink-0.1.19 → easylink-0.1.20}/src/easylink/utilities/general_utils.py +0 -0
  174. {easylink-0.1.19 → easylink-0.1.20}/src/easylink/utilities/paths.py +0 -0
  175. {easylink-0.1.19 → easylink-0.1.20}/src/easylink/utilities/spark.smk +0 -0
  176. {easylink-0.1.19 → easylink-0.1.20}/src/easylink/utilities/splitter_utils.py +0 -0
  177. {easylink-0.1.19 → easylink-0.1.20}/src/easylink/utilities/validation_utils.py +0 -0
  178. {easylink-0.1.19 → easylink-0.1.20}/src/easylink.egg-info/SOURCES.txt +0 -0
  179. {easylink-0.1.19 → easylink-0.1.20}/src/easylink.egg-info/dependency_links.txt +0 -0
  180. {easylink-0.1.19 → easylink-0.1.20}/src/easylink.egg-info/entry_points.txt +0 -0
  181. {easylink-0.1.19 → easylink-0.1.20}/src/easylink.egg-info/not-zip-safe +0 -0
  182. {easylink-0.1.19 → easylink-0.1.20}/src/easylink.egg-info/requires.txt +0 -0
  183. {easylink-0.1.19 → easylink-0.1.20}/src/easylink.egg-info/top_level.txt +0 -0
  184. {easylink-0.1.19 → easylink-0.1.20}/tests/__init__.py +0 -0
  185. {easylink-0.1.19 → easylink-0.1.20}/tests/conftest.py +0 -0
  186. {easylink-0.1.19 → easylink-0.1.20}/tests/e2e/pipeline_splink_dummy_results.csv +0 -0
  187. {easylink-0.1.19 → easylink-0.1.20}/tests/e2e/test_easylink_run.py +4 -4
  188. {easylink-0.1.19 → easylink-0.1.20}/tests/e2e/test_step_types.py +0 -0
  189. {easylink-0.1.19 → easylink-0.1.20}/tests/integration/test_compositions.py +0 -0
  190. {easylink-0.1.19 → easylink-0.1.20}/tests/integration/test_data_utils.py +0 -0
  191. {easylink-0.1.19 → easylink-0.1.20}/tests/integration/test_snakemake.py +0 -0
  192. {easylink-0.1.19 → easylink-0.1.20}/tests/integration/test_snakemake_slurm.py +0 -0
  193. {easylink-0.1.19 → easylink-0.1.20}/tests/integration/test_snakemake_spark.py +0 -0
  194. {easylink-0.1.19 → easylink-0.1.20}/tests/specifications/common/environment_local.yaml +0 -0
  195. {easylink-0.1.19 → easylink-0.1.20}/tests/specifications/common/input_data.yaml +0 -0
  196. {easylink-0.1.19 → easylink-0.1.20}/tests/specifications/common/input_data_one_file.yaml +0 -0
  197. {easylink-0.1.19 → easylink-0.1.20}/tests/specifications/common/pipeline.yaml +0 -0
  198. {easylink-0.1.19 → easylink-0.1.20}/tests/specifications/e2e/environment_slurm.yaml +0 -0
  199. {easylink-0.1.19 → easylink-0.1.20}/tests/specifications/e2e/input_data_dummy.yaml +0 -0
  200. {easylink-0.1.19 → easylink-0.1.20}/tests/specifications/e2e/pipeline.yaml +0 -0
  201. {easylink-0.1.19 → easylink-0.1.20}/tests/specifications/e2e/pipeline_cascade.yaml +0 -0
  202. {easylink-0.1.19 → easylink-0.1.20}/tests/specifications/e2e/pipeline_expanded.yaml +0 -0
  203. {easylink-0.1.19 → easylink-0.1.20}/tests/specifications/e2e/pipeline_splink_dummy.yaml +0 -0
  204. {easylink-0.1.19 → easylink-0.1.20}/tests/specifications/e2e/pipeline_with_fastLink.yaml +0 -0
  205. {easylink-0.1.19 → easylink-0.1.20}/tests/specifications/integration/embarrassingly_parallel/pipeline_hierarchical_step.yaml +0 -0
  206. {easylink-0.1.19 → easylink-0.1.20}/tests/specifications/integration/embarrassingly_parallel/pipeline_loop_step.yaml +0 -0
  207. {easylink-0.1.19 → easylink-0.1.20}/tests/specifications/integration/embarrassingly_parallel/pipeline_parallel_step.yaml +0 -0
  208. {easylink-0.1.19 → easylink-0.1.20}/tests/specifications/integration/environment_spark_slurm.yaml +0 -0
  209. {easylink-0.1.19 → easylink-0.1.20}/tests/specifications/integration/pipeline.yaml +0 -0
  210. {easylink-0.1.19 → easylink-0.1.20}/tests/specifications/integration/pipeline_output_dir.yaml +0 -0
  211. {easylink-0.1.19 → easylink-0.1.20}/tests/specifications/integration/pipeline_output_dir_default.yaml +0 -0
  212. {easylink-0.1.19 → easylink-0.1.20}/tests/specifications/integration/pipeline_spark.yaml +0 -0
  213. {easylink-0.1.19 → easylink-0.1.20}/tests/specifications/unit/environment_minimum.yaml +0 -0
  214. {easylink-0.1.19 → easylink-0.1.20}/tests/specifications/unit/environment_spark_slurm.yaml +0 -0
  215. {easylink-0.1.19 → easylink-0.1.20}/tests/specifications/unit/pipeline.yaml +0 -0
  216. {easylink-0.1.19 → easylink-0.1.20}/tests/specifications/unit/pipeline_bad_combined_implementations.yaml +0 -0
  217. {easylink-0.1.19 → easylink-0.1.20}/tests/specifications/unit/pipeline_bad_implementation.yaml +0 -0
  218. {easylink-0.1.19 → easylink-0.1.20}/tests/specifications/unit/pipeline_bad_loop_formatting.yaml +0 -0
  219. {easylink-0.1.19 → easylink-0.1.20}/tests/specifications/unit/pipeline_bad_step.yaml +0 -0
  220. {easylink-0.1.19 → easylink-0.1.20}/tests/specifications/unit/pipeline_bad_type_key.yaml +0 -0
  221. {easylink-0.1.19 → easylink-0.1.20}/tests/specifications/unit/pipeline_combine_bad_implementation_names.yaml +0 -0
  222. {easylink-0.1.19 → easylink-0.1.20}/tests/specifications/unit/pipeline_combine_bad_topology.yaml +0 -0
  223. {easylink-0.1.19 → easylink-0.1.20}/tests/specifications/unit/pipeline_combine_two_steps.yaml +0 -0
  224. {easylink-0.1.19 → easylink-0.1.20}/tests/specifications/unit/pipeline_combine_with_extra_node.yaml +0 -0
  225. {easylink-0.1.19 → easylink-0.1.20}/tests/specifications/unit/pipeline_combine_with_iteration.yaml +0 -0
  226. {easylink-0.1.19 → easylink-0.1.20}/tests/specifications/unit/pipeline_combine_with_iteration_cycle.yaml +0 -0
  227. {easylink-0.1.19 → easylink-0.1.20}/tests/specifications/unit/pipeline_combine_with_missing_node.yaml +0 -0
  228. {easylink-0.1.19 → easylink-0.1.20}/tests/specifications/unit/pipeline_combine_with_parallel.yaml +0 -0
  229. {easylink-0.1.19 → easylink-0.1.20}/tests/specifications/unit/pipeline_missing_implementation_name.yaml +0 -0
  230. {easylink-0.1.19 → easylink-0.1.20}/tests/specifications/unit/pipeline_missing_implementations.yaml +0 -0
  231. {easylink-0.1.19 → easylink-0.1.20}/tests/specifications/unit/pipeline_missing_loop_nodes.yaml +0 -0
  232. {easylink-0.1.19 → easylink-0.1.20}/tests/specifications/unit/pipeline_missing_step.yaml +0 -0
  233. {easylink-0.1.19 → easylink-0.1.20}/tests/specifications/unit/pipeline_missing_substeps.yaml +0 -0
  234. {easylink-0.1.19 → easylink-0.1.20}/tests/specifications/unit/pipeline_missing_type_key.yaml +0 -0
  235. {easylink-0.1.19 → easylink-0.1.20}/tests/specifications/unit/pipeline_nested_templated_steps.yaml +0 -0
  236. {easylink-0.1.19 → easylink-0.1.20}/tests/specifications/unit/pipeline_out_of_order.yaml +0 -0
  237. {easylink-0.1.19 → easylink-0.1.20}/tests/specifications/unit/pipeline_spark.yaml +0 -0
  238. {easylink-0.1.19 → easylink-0.1.20}/tests/specifications/unit/pipeline_type_config_mismatch.yaml +0 -0
  239. {easylink-0.1.19 → easylink-0.1.20}/tests/specifications/unit/pipeline_wrong_parallel_split_keys.yaml +0 -0
  240. {easylink-0.1.19 → easylink-0.1.20}/tests/unit/__init__.py +0 -0
  241. {easylink-0.1.19 → easylink-0.1.20}/tests/unit/conftest.py +0 -0
  242. {easylink-0.1.19 → easylink-0.1.20}/tests/unit/recipe_strings/python_pandas.txt +0 -0
  243. {easylink-0.1.19 → easylink-0.1.20}/tests/unit/rule_strings/aggregation_rule.txt +0 -0
  244. {easylink-0.1.19 → easylink-0.1.20}/tests/unit/rule_strings/checkpoint_rule.txt +0 -0
  245. {easylink-0.1.19 → easylink-0.1.20}/tests/unit/rule_strings/embarrassingly_parallel_rule.txt +0 -0
  246. {easylink-0.1.19 → easylink-0.1.20}/tests/unit/rule_strings/implemented_rule_local.txt +0 -0
  247. {easylink-0.1.19 → easylink-0.1.20}/tests/unit/rule_strings/implemented_rule_slurm.txt +0 -0
  248. {easylink-0.1.19 → easylink-0.1.20}/tests/unit/rule_strings/pipeline_local.txt +0 -0
  249. {easylink-0.1.19 → easylink-0.1.20}/tests/unit/rule_strings/pipeline_slurm.txt +0 -0
  250. {easylink-0.1.19 → easylink-0.1.20}/tests/unit/rule_strings/target_rule.txt +0 -0
  251. {easylink-0.1.19 → easylink-0.1.20}/tests/unit/rule_strings/validation_rule.txt +0 -0
  252. {easylink-0.1.19 → easylink-0.1.20}/tests/unit/test_cli.py +0 -0
  253. {easylink-0.1.19 → easylink-0.1.20}/tests/unit/test_config.py +0 -0
  254. {easylink-0.1.19 → easylink-0.1.20}/tests/unit/test_data_utils.py +0 -0
  255. {easylink-0.1.19 → easylink-0.1.20}/tests/unit/test_general_utils.py +0 -0
  256. {easylink-0.1.19 → easylink-0.1.20}/tests/unit/test_graph_components.py +0 -0
  257. {easylink-0.1.19 → easylink-0.1.20}/tests/unit/test_implementation.py +0 -0
  258. {easylink-0.1.19 → easylink-0.1.20}/tests/unit/test_pipeline.py +0 -0
  259. {easylink-0.1.19 → easylink-0.1.20}/tests/unit/test_pipeline_graph.py +0 -0
  260. {easylink-0.1.19 → easylink-0.1.20}/tests/unit/test_pipeline_schema.py +0 -0
  261. {easylink-0.1.19 → easylink-0.1.20}/tests/unit/test_rule.py +0 -0
  262. {easylink-0.1.19 → easylink-0.1.20}/tests/unit/test_runner.py +0 -0
  263. {easylink-0.1.19 → easylink-0.1.20}/tests/unit/test_step.py +0 -0
  264. {easylink-0.1.19 → easylink-0.1.20}/tests/unit/test_validations.py +0 -0
  265. {easylink-0.1.19 → easylink-0.1.20}/update_readme.py +0 -0
@@ -1,3 +1,7 @@
1
+ **0.1.20 - 6/11/25**
2
+
3
+ - Update implementation creator tool for new implementation_metadata.yaml format
4
+
1
5
  **0.1.19 - 6/11/25**
2
6
 
3
7
  - Implement support for images hosted on zenodo
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: easylink
3
- Version: 0.1.19
3
+ Version: 0.1.20
4
4
  Summary: Research repository for the EasyLink ER ecosystem project.
5
5
  Home-page: https://github.com/ihmeuw/easylink
6
6
  Author: The EasyLink developers
@@ -0,0 +1 @@
1
+ __version__ = "0.1.20"
@@ -29,7 +29,7 @@ from easylink.step import (
29
29
  TemplatedStep,
30
30
  )
31
31
  from easylink.utilities.data_utils import load_yaml
32
- from easylink.utilities.paths import IMPLEMENTATION_METADATA
32
+ from easylink.utilities.paths import DEV_IMAGES_DIR, IMPLEMENTATION_METADATA
33
33
 
34
34
 
35
35
  def main(script_path: Path, host: Path) -> None:
@@ -195,9 +195,24 @@ class ImplementationCreator:
195
195
  f"Implementation '{self.implementation_name}' already exists in the registry. "
196
196
  "Overwriting it with the latest data."
197
197
  )
198
+
199
+ # Handle the fact that developers might be saving to username subdirs
200
+ # If the host folder is a subdirectory of DEV_IMAGES_DIR (e.g., the default
201
+ # host directory when calling `easylink devtools create-implementation`
202
+ # is DEV_IMAGES_DIR/<username>), we want to include the relative path
203
+ # to the DEV_IMAGES_DIR in the image name. This is required because ultimately
204
+ # when running a pipeline, all images are expected to be in a single directory.
205
+ image_name = (
206
+ self.hosted_container_path.name
207
+ # Use just the image name if the hosted path is not a part of DEV_IMAGES_DIR
208
+ if not self.hosted_container_path.is_relative_to(DEV_IMAGES_DIR)
209
+ # Use the path relative to DEV_IMAGES_DIR as the image name
210
+ else str(self.hosted_container_path.relative_to(DEV_IMAGES_DIR))
211
+ )
212
+
198
213
  info[self.implementation_name] = {
199
214
  "steps": [self.step],
200
- "image_path": str(self.hosted_container_path),
215
+ "image_name": str(image_name),
201
216
  "script_cmd": f"{self.script_base_command} /{self.script_path.name}",
202
217
  "outputs": {
203
218
  self.output_slot: "result.parquet",
@@ -60,12 +60,14 @@ new_clusters_df = load_file(new_clusters_filepath)
60
60
  def merge_clusters(known_clusters_df, new_clusters_df):
61
61
  # Combine both dataframes
62
62
  combined_df = pd.concat([known_clusters_df, new_clusters_df], ignore_index=True)
63
-
64
- # Drop records with missing cluster IDs
65
- combined_df = combined_df.dropna(subset=["Cluster ID"])
63
+ combined_df["Input Record Key"] = (
64
+ combined_df["Input Record Dataset"]
65
+ + "-__-"
66
+ + combined_df["Input Record ID"].astype(int).astype(str)
67
+ )
66
68
 
67
69
  # Group by Cluster ID to get connected records
68
- cluster_groups = combined_df.groupby("Cluster ID")["Input Record ID"].apply(list)
70
+ cluster_groups = combined_df.groupby("Cluster ID")["Input Record Key"].apply(list)
69
71
 
70
72
  # Build a graph of all connections implied by cluster IDs
71
73
  G = nx.Graph()
@@ -75,8 +77,8 @@ def merge_clusters(known_clusters_df, new_clusters_df):
75
77
  G.add_edge(group[i], group[j])
76
78
 
77
79
  # Add isolated nodes (records with unique clusters)
78
- all_ids = set(combined_df["Input Record ID"])
79
- G.add_nodes_from(all_ids)
80
+ all_keys = set(combined_df["Input Record Key"])
81
+ G.add_nodes_from(all_keys)
80
82
 
81
83
  # Compute connected components
82
84
  components = list(nx.connected_components(G))
@@ -84,13 +86,19 @@ def merge_clusters(known_clusters_df, new_clusters_df):
84
86
  # Assign new cluster IDs
85
87
  merged_data = []
86
88
  for cluster_id, records in enumerate(components, start=1):
87
- for record_id in records:
88
- merged_data.append((record_id, cluster_id))
89
+ for record_key in records:
90
+ merged_data.append((record_key, cluster_id))
89
91
 
90
92
  # Build the final DataFrame
91
- merged_df = pd.DataFrame(merged_data, columns=["Input Record ID", "Cluster ID"])
93
+ merged_df = pd.DataFrame(merged_data, columns=["Input Record Key", "Cluster ID"])
94
+
95
+ merged_df[["Input Record Dataset", "Input Record ID"]] = merged_df[
96
+ "Input Record Key"
97
+ ].str.split("-__-", n=1, expand=True)
98
+
99
+ merged_df["Input Record ID"] = merged_df["Input Record ID"].astype(int)
92
100
 
93
- return merged_df
101
+ return merged_df[["Input Record Dataset", "Input Record ID", "Cluster ID"]]
94
102
 
95
103
 
96
104
  output_df = merge_clusters(known_clusters_df, new_clusters_df)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: easylink
3
- Version: 0.1.19
3
+ Version: 0.1.20
4
4
  Summary: Research repository for the EasyLink ER ecosystem project.
5
5
  Home-page: https://github.com/ihmeuw/easylink
6
6
  Author: The EasyLink developers
@@ -18,18 +18,18 @@ from easylink.utilities.paths import DEV_IMAGES_DIR
18
18
  @pytest.mark.parametrize(
19
19
  "pipeline_specification, input_data, computing_environment, correct_results_csv",
20
20
  [
21
- # slurm pipeline_splink_dummy.yaml
21
+ # local pipeline_splink_dummy.yaml
22
22
  (
23
23
  "tests/specifications/e2e/pipeline_splink_dummy.yaml",
24
24
  "tests/specifications/e2e/input_data_dummy.yaml",
25
- "tests/specifications/e2e/environment_slurm.yaml",
25
+ "tests/specifications/common/environment_local.yaml",
26
26
  "tests/e2e/pipeline_splink_dummy_results.csv",
27
27
  ),
28
- # local pipeline_splink_dummy.yaml
28
+ # slurm pipeline_splink_dummy.yaml
29
29
  (
30
30
  "tests/specifications/e2e/pipeline_splink_dummy.yaml",
31
31
  "tests/specifications/e2e/input_data_dummy.yaml",
32
- "tests/specifications/common/environment_local.yaml",
32
+ "tests/specifications/e2e/environment_slurm.yaml",
33
33
  "tests/e2e/pipeline_splink_dummy_results.csv",
34
34
  ),
35
35
  ],
@@ -103,7 +103,6 @@ def test_pipeline_splink_dummy(
103
103
  )
104
104
 
105
105
 
106
- @pytest.mark.skip(reason="FIXME [SSCI-2312]: This test is sporadically failing")
107
106
  @pytest.mark.slow
108
107
  @pytest.mark.skipif(
109
108
  not is_on_slurm(),
@@ -112,32 +111,32 @@ def test_pipeline_splink_dummy(
112
111
  @pytest.mark.parametrize(
113
112
  "pipeline_specification, input_data, computing_environment, splink_results_csv",
114
113
  [
115
- # slurm pipeline_with_fastLink.yaml
114
+ # local pipeline_with_fastLink.yaml
116
115
  (
117
116
  "tests/specifications/e2e/pipeline_with_fastLink.yaml",
118
117
  "tests/specifications/e2e/input_data_dummy.yaml",
119
- "tests/specifications/e2e/environment_slurm.yaml",
118
+ "tests/specifications/common/environment_local.yaml",
120
119
  "tests/e2e/pipeline_splink_dummy_results.csv",
121
120
  ),
122
- # local pipeline_with_fastLink.yaml
121
+ # slurm pipeline_with_fastLink.yaml
123
122
  (
124
123
  "tests/specifications/e2e/pipeline_with_fastLink.yaml",
125
124
  "tests/specifications/e2e/input_data_dummy.yaml",
126
- "tests/specifications/common/environment_local.yaml",
125
+ "tests/specifications/e2e/environment_slurm.yaml",
127
126
  "tests/e2e/pipeline_splink_dummy_results.csv",
128
127
  ),
129
- # slurm pipeline_cascade.yaml
128
+ # local pipeline_cascade.yaml
130
129
  (
131
130
  "tests/specifications/e2e/pipeline_cascade.yaml",
132
131
  "tests/specifications/e2e/input_data_dummy.yaml",
133
- "tests/specifications/e2e/environment_slurm.yaml",
132
+ "tests/specifications/common/environment_local.yaml",
134
133
  "tests/e2e/pipeline_splink_dummy_results.csv",
135
134
  ),
136
- # local pipeline_cascade.yaml
135
+ # slurm pipeline_cascade.yaml
137
136
  (
138
137
  "tests/specifications/e2e/pipeline_cascade.yaml",
139
138
  "tests/specifications/e2e/input_data_dummy.yaml",
140
- "tests/specifications/common/environment_local.yaml",
139
+ "tests/specifications/e2e/environment_slurm.yaml",
141
140
  "tests/e2e/pipeline_splink_dummy_results.csv",
142
141
  ),
143
142
  ],
@@ -158,6 +157,9 @@ def test_pipelines_same_output_relabeled(
158
157
  Jenkins logs.
159
158
  """
160
159
 
160
+ if "fastLink" in pipeline_specification:
161
+ pytest.skip(reason="FIXME [SSCI-2312]: This test is sporadically failing")
162
+
161
163
  with capsys.disabled(): # disabled so we can monitor job submissions
162
164
  print(
163
165
  "\n\n*** RUNNING TEST ***\n"
@@ -8,7 +8,7 @@ from pytest_mock import MockerFixture
8
8
 
9
9
  from easylink.devtools.implementation_creator import ImplementationCreator
10
10
  from easylink.utilities.data_utils import load_yaml
11
- from easylink.utilities.paths import IMPLEMENTATION_METADATA
11
+ from easylink.utilities.paths import DEV_IMAGES_DIR, IMPLEMENTATION_METADATA
12
12
 
13
13
  GOOD_METADATA = """
14
14
  # STEP_NAME: step_1
@@ -181,31 +181,35 @@ def test_register(tmp_path: Path, mocker: MockerFixture) -> None:
181
181
  # copy the real implementation metadata file to the test directory
182
182
  shutil.copy(IMPLEMENTATION_METADATA, implementation_metadata)
183
183
 
184
+ # Don't accidentally write to the real implementation metadata file
184
185
  def _write_test_metadata(info: dict[str, str | dict[str, str]]) -> None:
185
- # Don't accidentally write to the real implementation metadata file
186
186
  if implementation_metadata.resolve() == IMPLEMENTATION_METADATA.resolve():
187
187
  raise ValueError("Attempting to write to the real implementation metadata file")
188
188
  with open(str(implementation_metadata), "w") as f:
189
189
  yaml.dump(info, f, sort_keys=False)
190
190
 
191
+ mocker.patch(
192
+ "easylink.devtools.implementation_creator.ImplementationCreator._write_metadata",
193
+ side_effect=_write_test_metadata,
194
+ )
195
+ mocker.patch(
196
+ "easylink.devtools.implementation_creator.load_yaml",
197
+ return_value=load_yaml(implementation_metadata),
198
+ )
199
+
191
200
  # write the script to be used for the test
192
201
  with open(script_path, "w") as file:
193
202
  file.write(GOOD_METADATA)
194
203
 
195
204
  creator = ImplementationCreator(script_path, Path("some-host"))
196
-
197
205
  assert "test_implementation" not in load_yaml(implementation_metadata)
198
- mocker.patch(
199
- "easylink.devtools.implementation_creator.ImplementationCreator._write_metadata",
200
- side_effect=_write_test_metadata,
201
- )
202
206
  creator.register()
203
207
 
204
208
  # load the new metadata and check it
205
209
  details = load_yaml(implementation_metadata)["test_implementation"]
206
210
  assert details == {
207
211
  "steps": ["step_1"],
208
- "image_path": "some-host/test_implementation.sif",
212
+ "image_name": "test_implementation.sif",
209
213
  "script_cmd": "python /test_implementation.py",
210
214
  "outputs": {"step_1_main_output": "result.parquet"},
211
215
  }
@@ -221,18 +225,59 @@ def test_register(tmp_path: Path, mocker: MockerFixture) -> None:
221
225
  md = load_yaml(implementation_metadata)
222
226
  assert "test_implementation" in md
223
227
  assert "test_new_implementation" not in md
224
-
225
228
  new_creator.register()
226
229
 
227
- new_details = load_yaml(implementation_metadata)["test_new_implementation"]
228
- assert new_details == {
230
+ md = load_yaml(implementation_metadata)
231
+ assert "test_implementation" in md
232
+ assert md["test_new_implementation"] == {
229
233
  "steps": ["step_1"],
230
- "image_path": "some-other-host/test_new_implementation.sif",
234
+ "image_name": "test_new_implementation.sif",
231
235
  "script_cmd": "python /test_new_implementation.py",
232
236
  "outputs": {"step_1_main_output": "result.parquet"},
233
237
  }
234
238
 
235
239
 
240
+ def test_register_to_dev_folder_subdir(tmp_path: Path, mocker: MockerFixture) -> None:
241
+
242
+ implementation_metadata = tmp_path / "test_implementation_metadata.yaml"
243
+ # copy the real implementation metadata file to the test directory
244
+ shutil.copy(IMPLEMENTATION_METADATA, implementation_metadata)
245
+
246
+ # Don't accidentally write to the real implementation metadata file
247
+ def _write_test_metadata(info: dict[str, str | dict[str, str]]) -> None:
248
+ if implementation_metadata.resolve() == IMPLEMENTATION_METADATA.resolve():
249
+ raise ValueError("Attempting to write to the real implementation metadata file")
250
+ with open(str(implementation_metadata), "w") as f:
251
+ yaml.dump(info, f, sort_keys=False)
252
+
253
+ mocker.patch(
254
+ "easylink.devtools.implementation_creator.ImplementationCreator._write_metadata",
255
+ side_effect=_write_test_metadata,
256
+ )
257
+ mocker.patch(
258
+ "easylink.devtools.implementation_creator.load_yaml",
259
+ return_value=load_yaml(implementation_metadata),
260
+ )
261
+
262
+ dev_script = tmp_path / "some_fancy_new_implementation.py"
263
+ with open(dev_script, "w") as file:
264
+ file.write(GOOD_METADATA)
265
+
266
+ dev_creator = ImplementationCreator(dev_script, Path(DEV_IMAGES_DIR) / "some-subdir")
267
+
268
+ md = load_yaml(implementation_metadata)
269
+ assert "some_fancy_new_implementation" not in md
270
+ dev_creator.register()
271
+
272
+ md = load_yaml(implementation_metadata)
273
+ assert md["some_fancy_new_implementation"] == {
274
+ "steps": ["step_1"],
275
+ "image_name": "some-subdir/some_fancy_new_implementation.sif",
276
+ "script_cmd": "python /some_fancy_new_implementation.py",
277
+ "outputs": {"step_1_main_output": "result.parquet"},
278
+ }
279
+
280
+
236
281
  ####################
237
282
  # Helper functions #
238
283
  ####################
@@ -1 +0,0 @@
1
- __version__ = "0.1.19"
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
File without changes
File without changes
File without changes